From patchwork Mon Dec 25 09:58:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Laight X-Patchwork-Id: 13504563 X-Patchwork-Delegate: kuba@kernel.org Received: from eu-smtp-delivery-151.mimecast.com (eu-smtp-delivery-151.mimecast.com [185.58.86.151]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F1C1A179B1 for ; Mon, 25 Dec 2023 09:58:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ACULAB.COM Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=aculab.com Received: from AcuMS.aculab.com (156.67.243.121 [156.67.243.121]) by relay.mimecast.com with ESMTP with both STARTTLS and AUTH (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id uk-mta-405--17qtIQCNQ-VIvzLmd8C0A-1; Mon, 25 Dec 2023 09:58:53 +0000 X-MC-Unique: -17qtIQCNQ-VIvzLmd8C0A-1 Received: from AcuMS.Aculab.com (10.202.163.6) by AcuMS.aculab.com (10.202.163.6) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Mon, 25 Dec 2023 09:58:30 +0000 Received: from AcuMS.Aculab.com ([::1]) by AcuMS.aculab.com ([::1]) with mapi id 15.00.1497.048; Mon, 25 Dec 2023 09:58:30 +0000 From: David Laight To: "'netdev@vger.kernel.org'" , "'David S . Miller'" , "'kuba@kernel.org'" CC: "'eric.dumazet@gmail.com'" , "'martin.lau@linux.dev'" , 'Alexei Starovoitov' , 'Stephen Hemminger' , "'Jens Axboe'" , 'Daniel Borkmann' , "'Andrii Nakryiko'" Subject: [PATCH net-next 4/4] sockptr: Change sockptr_t to be a struct of a kernel and user pointer. Thread-Topic: [PATCH net-next 4/4] sockptr: Change sockptr_t to be a struct of a kernel and user pointer. Thread-Index: Ado3GOykMznC7Y2GTLihcf026jh1OQ== Date: Mon, 25 Dec 2023 09:58:30 +0000 Message-ID: <18fcf82093314112a569aa8327b52f1c@AcuMS.aculab.com> References: <199c9af56a5741feaf4b1768bf7356be@AcuMS.aculab.com> In-Reply-To: <199c9af56a5741feaf4b1768bf7356be@AcuMS.aculab.com> Accept-Language: en-GB, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: aculab.com Content-Language: en-US X-Patchwork-Delegate: kuba@kernel.org The original commit for sockptr_t tried to use the pointer value to determine whether a pointer was user or kernel. This can't work on some architecures and was buffy on x86. So the is_kernel descriminator was added after the union of pointers. However this is still open to misuse and accidents. Replace the union with a struct and remove the is_kernel member. The user and kernel values are now in different places. The size doesn't change - it was always padded out to 'two pointers'. The only functional difference is that NULL pointers are always 'user'. So dereferncing will (usually) fault in copy_from_user() rather than panic if supplied as a kernel address. Simple driver code that uses kernel sockets still works. I've not tested bpf - but that should work unless it is breaking the rules. Signed-off-by: David Laight --- include/linux/sockptr.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h index 307961b41541..7516c2ada6a8 100644 --- a/include/linux/sockptr.h +++ b/include/linux/sockptr.h @@ -12,21 +12,18 @@ #include typedef struct { - union { - void *kernel; - void __user *user; - }; - bool is_kernel : 1; + void *kernel; + void __user *user; } sockptr_t; static inline bool sockptr_is_kernel(sockptr_t sockptr) { - return sockptr.is_kernel; + return !!sockptr.kernel; } static inline sockptr_t KERNEL_SOCKPTR(void *p) { - return (sockptr_t) { .kernel = p, .is_kernel = true }; + return (sockptr_t) { .kernel = p }; } static inline sockptr_t USER_SOCKPTR(void __user *p) @@ -36,9 +33,7 @@ static inline sockptr_t USER_SOCKPTR(void __user *p) static inline bool sockptr_is_null(sockptr_t sockptr) { - if (sockptr_is_kernel(sockptr)) - return !sockptr.kernel; - return !sockptr.user; + return !sockptr.user && !sockptr.kernel; } static inline int copy_from_sockptr_offset(void *dst, sockptr_t src,