From patchwork Wed Sep 27 00:38:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Paasch X-Patchwork-Id: 818875 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=apple.com header.i=@apple.com header.b="h7CxzvXn"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3y1zpy6ZcFz9t3m for ; Wed, 27 Sep 2017 10:54:02 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1032892AbdI0AyA (ORCPT ); Tue, 26 Sep 2017 20:54:00 -0400 Received: from mail-out5.apple.com ([17.151.62.27]:42268 "EHLO mail-in5.apple.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1030619AbdI0Ax6 (ORCPT ); Tue, 26 Sep 2017 20:53:58 -0400 X-Greylist: delayed 901 seconds by postgrey-1.27 at vger.kernel.org; Tue, 26 Sep 2017 20:53:58 EDT DKIM-Signature: v=1; a=rsa-sha256; d=apple.com; s=mailout2048s; c=relaxed/simple; q=dns/txt; i=@apple.com; t=1506472737; h=From:Sender:Reply-To:Subject:Date:Message-id:To:Cc:MIME-Version:Content-Type: Content-transfer-encoding:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=6b7hNYrRB8ybXgBLQtfpwfx1F8ivkGm0qC9tD6t5jKw=; b=h7CxzvXnOaYnev5GlgyPHmlqbePJnu+pCZb2cjfax6O2HJznvus6Gkl10ZHZo8vF 0HCdmWGAWtAr26IFercrUCBpAbFyWqIqMyt0jxY1VHNtJUYuESgE5nsNxXHL4oHm TceDbKU7i2hEw4BRxqOerjWW99HlUQV4JNBQz+SU+rHDvyHq3GtVV9kC1VDfV2Z/ 744MxzBtLDnx6j2yBI2Eor/Q4CXORXn+nmDvYXO8KjYaIvH3uBPTj83Pr28cjbIM +y6f1d11if2oH+mRkhjFdvptHS2GPASy6jGJbQ3MR36z+C7JVZkKKu1LCGUpugtJ k8bEot+dcDZrFia/3umPtQ==; Received: from relay8.apple.com (relay8.apple.com [17.128.113.102]) (using TLS with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mail-in5.apple.com (Apple Secure Mail Relay) with SMTP id F0.0A.30368.123FAC95; Tue, 26 Sep 2017 17:38:57 -0700 (PDT) X-AuditID: 11973e13-357ff700000076a0-5e-59caf321bf6e Received: from nwk-mmpp-sz10.apple.com (nwk-mmpp-sz10.apple.com [17.128.115.122]) by relay8.apple.com (Apple SCV relay) with SMTP id A7.72.06978.123FAC95; Tue, 26 Sep 2017 17:38:57 -0700 (PDT) Content-transfer-encoding: 7BIT Received: from localhost ([17.226.23.151]) by nwk-mmpp-sz10.apple.com (Oracle Communications Messaging Server 8.0.1.3.20170825 64bit (built Aug 25 2017)) with ESMTPSA id <0OWW00I9FXSXNN70@nwk-mmpp-sz10.apple.com>; Tue, 26 Sep 2017 17:38:57 -0700 (PDT) From: Christoph Paasch To: David Miller Cc: netdev@vger.kernel.org Subject: [PATCH net] net: Set sk_prot_creator when cloning sockets to the right proto Date: Tue, 26 Sep 2017 17:38:50 -0700 Message-id: <20170927003850.23731-1-cpaasch@apple.com> X-Mailer: git-send-email 2.14.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrPJMWRmVeSWpSXmKPExsUi2FCYpqv4+VSkwdfTmhZzzrewWBxbIObA 5LFl5U0mj8+b5AKYorhsUlJzMstSi/TtErgybs8/wVjwQaqioWklYwPjdZEuRk4OCQETiY9X Z7CA2EICa5gk7n4ogYl37XjE3sXIBRQ/xCgxo/sOWxcjBwezgLzEwfOyEPFGJok3P84xgzQI C0hKdN+5A2azCWhJvL3dzgpiiwioSUw8MQEsziwgJfHy0gxGiPpwiT1/trKAzGQRUJWY1SUD EuYVMJPYv+IhM8QN8hLnHtxmBtklIXCQVaJ72yS2CYz8sxDOWMDIuIpRKDcxM0c3M89UL7Gg ICdVLzk/dxMjKISm2wnvYDy9yuoQowAHoxIPL0PIqUgh1sSy4srcQ4zSHCxK4rzrBIBCAumJ JanZqakFqUXxRaU5qcWHGJk4OKUaGBUb1+7LOOa16Cr3jgynp2HZBk1H215tmFMfbV+/IGH7 xL3Hjkh1/dTbLWrB9LK32srrhcXmRY9vcTnELY4Ij97af3qbrEUMp7p2peqZWb+XL/5TkP/N dp5u6jrbM7va/5aK66sUfz61a7WEhhxLYxj3jLn5BwKmnf+QfOzi3cfzvuoKlVhuZlBiKc5I NNRiLipOBABzAyvFAgIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrMJMWRmVeSWpSXmKPExsUi2FBcpav4+VSkwaM7qhZzzrewWBxbIObA 5LFl5U0mj8+b5AKYorhsUlJzMstSi/TtErgybs8/wVjwQaqioWklYwPjdZEuRk4OCQETia4d j9i7GLk4hAQOMUrM6L7D1sXIwcEsIC9x8LwsRLyRSeLNj3PMIA3CApIS3XfugNlsAloSb2+3 s4LYIgJqEhNPTACLMwtISby8NIMRoj5cYs+frSwgM1kEVCVmdcmAhHkFzCT2r3jIDHGDvMS5 B7eZJzDyzELYvICRcRWjQFFqTmKlhV5iQUFOql5yfu4mRrDXC9N2MDYttzrEKMDBqMTDGxF2 KlKINbGsuDIX6AUOZiUR3ubbQCHelMTKqtSi/Pii0pzU4kOM0hwsSuK8y9ccjRQSSE8sSc1O TS1ILYLJMnFwSjUw1i3XWProsEc3Z1tjb7ndnH7Zu88kvu/KnNvEmiNSJtH73/JHr9sHwysv u17oXd4z6/sL3zovhpTDkiHeLpfPz3wn4XeYyXgNS27OpfVXv196sT6ew1hv+qbMolO/pz7T ytY/NrF4Zs+FZc5mlwXOha37/zTYYoe9yr7dv4tM+FOE8m4ztGwzVmIpzkg01GIuKk4EAJ8+ iUf2AQAA Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org sk->sk_prot and sk->sk_prot_creator can differ when the app uses IPV6_ADDRFORM (transforming an IPv6-socket to an IPv4-one). Which is why sk_prot_creator is there to make sure that sk_prot_free() does the kmem_cache_free() on the right kmem_cache slab. Now, if such a socket gets transformed back to a listening socket (using connect() with AF_UNSPEC) we will allocate an IPv4 tcp_sock through sk_clone_lock() when a new connection comes in. But sk_prot_creator will still point to the IPv6 kmem_cache (as everything got copied in sk_clone_lock()). When freeing, we will thus put this memory back into the IPv6 kmem_cache although it was allocated in the IPv4 cache. I have seen memory corruption happening because of this. With slub-debugging and MEMCG_KMEM enabled this gives the warning "cache_from_obj: Wrong slab cache. TCPv6 but object is from TCP" A C-program to trigger this: void main(void) { int fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); int new_fd, newest_fd, client_fd; struct sockaddr_in6 bind_addr; struct sockaddr_in bind_addr4, client_addr1, client_addr2; struct sockaddr unsp; int val; memset(&bind_addr, 0, sizeof(bind_addr)); bind_addr.sin6_family = AF_INET6; bind_addr.sin6_port = ntohs(42424); memset(&client_addr1, 0, sizeof(client_addr1)); client_addr1.sin_family = AF_INET; client_addr1.sin_port = ntohs(42424); client_addr1.sin_addr.s_addr = inet_addr("127.0.0.1"); memset(&client_addr2, 0, sizeof(client_addr2)); client_addr2.sin_family = AF_INET; client_addr2.sin_port = ntohs(42421); client_addr2.sin_addr.s_addr = inet_addr("127.0.0.1"); memset(&unsp, 0, sizeof(unsp)); unsp.sa_family = AF_UNSPEC; bind(fd, (struct sockaddr *)&bind_addr, sizeof(bind_addr)); listen(fd, 5); client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); connect(client_fd, (struct sockaddr *)&client_addr1, sizeof(client_addr1)); new_fd = accept(fd, NULL, NULL); close(fd); val = AF_INET; setsockopt(new_fd, SOL_IPV6, IPV6_ADDRFORM, &val, sizeof(val)); connect(new_fd, &unsp, sizeof(unsp)); memset(&bind_addr4, 0, sizeof(bind_addr4)); bind_addr4.sin_family = AF_INET; bind_addr4.sin_port = ntohs(42421); bind(new_fd, (struct sockaddr *)&bind_addr4, sizeof(bind_addr4)); listen(new_fd, 5); client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); connect(client_fd, (struct sockaddr *)&client_addr2, sizeof(client_addr2)); newest_fd = accept(new_fd, NULL, NULL); close(new_fd); close(client_fd); close(new_fd); } As far as I can see, this bug has been there since the beginning of the git-days. Signed-off-by: Christoph Paasch Reviewed-by: Eric Dumazet --- net/core/sock.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/core/sock.c b/net/core/sock.c index 9b7b6bbb2a23..7d55c05f449d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1654,6 +1654,8 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) sock_copy(newsk, sk); + newsk->sk_prot_creator = sk->sk_prot; + /* SANITY */ if (likely(newsk->sk_net_refcnt)) get_net(sock_net(newsk));