From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6351FC43214 for ; Wed, 18 Aug 2021 05:08:52 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 07DC7610A0 for ; Wed, 18 Aug 2021 05:08:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 07DC7610A0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kvack.org Received: by kanga.kvack.org (Postfix) id 96CC68D0006; Wed, 18 Aug 2021 01:08:47 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 8AC8F8D0005; Wed, 18 Aug 2021 01:08:47 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6ABDE8D0003; Wed, 18 Aug 2021 01:08:47 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0207.hostedemail.com [216.40.44.207]) by kanga.kvack.org (Postfix) with ESMTP id 459068D0001 for ; Wed, 18 Aug 2021 01:08:47 -0400 (EDT) Received: from smtpin35.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with ESMTP id DE976181B04AD for ; Wed, 18 Aug 2021 05:08:46 +0000 (UTC) X-FDA: 78487021452.35.2E29239 Received: from mail-pf1-f172.google.com (mail-pf1-f172.google.com [209.85.210.172]) by imf18.hostedemail.com (Postfix) with ESMTP id 99DFC4004097 for ; Wed, 18 Aug 2021 05:08:46 +0000 (UTC) Received: by mail-pf1-f172.google.com with SMTP id y11so948491pfl.13 for ; Tue, 17 Aug 2021 22:08:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PJoa4iKvyV5ZjcOKo8KLgCpzhWd1dLdAE7oHmS24kmI=; b=XoqR3saVnkwQdaMbo8v29/zLHplfZcejHyGEtGR80f/yvY/cgcEmJVBX6LB1twfOmR C57Wb9w3oBqxKggPS8I6LTjLP1Mg8N4TVD1yqljUPvsHHNnkxYnR3c6SZh+ZoDw4JYVr bSxIGT0JG05gMBr+nZxEAEA67uQJIh6d2QyNE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PJoa4iKvyV5ZjcOKo8KLgCpzhWd1dLdAE7oHmS24kmI=; b=sEWXKCaqtCsATnU3rPpGMEp80SJ7tRyIjIfUVSWYDRbf2ey8LMw3LLNaj791EcpOBL Nh7/ddCgndUIWGW4i3nVFzJIRGSLSt3rMKUIlgjzM0TjhZRgcQIp4dKDV78CxMOMzivU /KuDCznDG+O9gFKrlqwxw5wwBasfiq116GDHDHEbhQvrvK5uAD1/GFSX1g+FEdVecJQB 1s7zfvc1gugBKCxavFSt7r0gOfKZPisXPhVuQNOKTOVWRo1MS4fShmLUQ7OIUaXt/SFE 6lEnORXmjI8l5+R76bKVSvjkbRqBJpjPqgfSnlafpQ19w1zqZcd5L5ZhSUjxstc9LlQ8 8I4g== X-Gm-Message-State: AOAM533ebVc3h2B93D89h+3Q0pb5eYmNqw1ItQIloj3BzhoIKaNuieZJ G3Ra6JifsA6hMS2s566y8gIjAQ== X-Google-Smtp-Source: ABdhPJwKgzp5vA4w6wkQdQaDJ9fAJpJsvxtDCO2cLAcpiN0uM8Y2YDiktkkEfIpYFuEAoycRcGb4Kw== X-Received: by 2002:aa7:8058:0:b029:332:9da3:102d with SMTP id y24-20020aa780580000b02903329da3102dmr7352676pfm.21.1629263325814; Tue, 17 Aug 2021 22:08:45 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id j6sm5037394pgq.0.2021.08.17.22.08.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Aug 2021 22:08:43 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Daniel Micay , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Vlastimil Babka , linux-mm@kvack.org, Miguel Ojeda , Nathan Chancellor , Nick Desaulniers , Dennis Zhou , Tejun Heo , Masahiro Yamada , Michal Marek , clang-built-linux@googlegroups.com, linux-kbuild@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH 2/5] slab: Add __alloc_size attributes for better bounds checking Date: Tue, 17 Aug 2021 22:08:38 -0700 Message-Id: <20210818050841.2226600-3-keescook@chromium.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210818050841.2226600-1-keescook@chromium.org> References: <20210818050841.2226600-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7084; h=from:subject; bh=mOKi2doWtdNTuoRZf7uNcQVzIU50qiNF7t9u3Nn55qQ=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBhHJXYMzR6/MsdNgjHLHDWQusu9UKxXGXBcBf1OYKK Sz9e4kaJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYRyV2AAKCRCJcvTf3G3AJmNnD/ 4yTBX9z+fMGN8gDeZBU4fNrWeR2k4e14MeZzDbYV0BUqaiphoGMO9p570IWy3da8EoE65rBJYK1awp XvcnrLv86Vuzu6rHtLI4zcs4RRxNiF87TV2dbP8s1HWO06CHw45W9hJlWRbhRpJqElGhl9g1K5MKqs XidOG9M5i7z+sAs1BC+Uli1H+df+7CqijqxN7/2kqL2/ofwnVzpdVMf3paBst2Nh5fjiPmfRsf+tL2 0L3PfcWWT4+qLXaKE8dCaf69XkaLsMS3boQ30GBGLP4aClofiPF90eOBpqp2MnPNU1NADlJo+OmQ+W 4gmdLCmRi/+Tmtj6GQQgIJmJhsVA1AOUfeQdLjzuz4LbC5xa+7EbID0zlnXBWirdmrQeU2QFARrJSA g/3MwdNzqXo44qT5eFkC3n7j8gi0PYlfoOIFBX+hX9jAPFm56giDzgXIRTYp4gv53bsq6jhcquLpbs nEvse6BvVgBmwNKbKqJElqHbeV6+AkkctfP7+GHcytUqt4Vqp7IxAsxclM+5SwNuDb2SsCuc5CoHyo D42unWsvnFRPWkvTryy08B1bgojos+XmbygssJcfd3lBEAIknNjdAbNuouIw5chZTsKPTw/MACHxJF iqpKgOBq/btkAFocY2xjN0hDO/2MXd909gs1IViC61xu9yLty70IT9IrLw3Q== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 X-Rspamd-Queue-Id: 99DFC4004097 Authentication-Results: imf18.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=XoqR3saV; spf=pass (imf18.hostedemail.com: domain of keescook@chromium.org designates 209.85.210.172 as permitted sender) smtp.mailfrom=keescook@chromium.org; dmarc=pass (policy=none) header.from=chromium.org X-Rspamd-Server: rspam01 X-Stat-Signature: eb7dnrpuzxx8hoxdfcys5fm3mbtktrzt X-HE-Tag: 1629263326-478852 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: As already done in GrapheneOS, add the __alloc_size attribute for regular kmalloc interfaces, to provide additional hinting for better bounds checking, assisting CONFIG_FORTIFY_SOURCE and other compiler optimizations. Co-developed-by: Daniel Micay Signed-off-by: Daniel Micay Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Cc: Andrew Morton Cc: Vlastimil Babka Cc: linux-mm@kvack.org Signed-off-by: Kees Cook --- include/linux/slab.h | 50 +++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/include/linux/slab.h b/include/linux/slab.h index c0d46b6fa12a..b2181c176999 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -181,7 +181,7 @@ int kmem_cache_shrink(struct kmem_cache *); /* * Common kmalloc functions provided by all allocators */ -void * __must_check krealloc(const void *, size_t, gfp_t); +void * __must_check krealloc(const void *, size_t, gfp_t) __alloc_size(2= ); void kfree(const void *); void kfree_sensitive(const void *); size_t __ksize(const void *); @@ -425,7 +425,7 @@ static __always_inline unsigned int __kmalloc_index(s= ize_t size, #define kmalloc_index(s) __kmalloc_index(s, true) #endif /* !CONFIG_SLOB */ =20 -void *__kmalloc(size_t size, gfp_t flags) __assume_kmalloc_alignment __m= alloc; +void *__kmalloc(size_t size, gfp_t flags) __alloc_size(1) __assume_kmall= oc_alignment __malloc; void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags) __assume_slab_a= lignment __malloc; void kmem_cache_free(struct kmem_cache *, void *); =20 @@ -449,7 +449,8 @@ static __always_inline void kfree_bulk(size_t size, v= oid **p) } =20 #ifdef CONFIG_NUMA -void *__kmalloc_node(size_t size, gfp_t flags, int node) __assume_kmallo= c_alignment __malloc; +void *__kmalloc_node(size_t size, gfp_t flags, int node) __alloc_size(1) + __assume_kmalloc_alignment __malloc; void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node) = __assume_slab_alignment __malloc; #else static __always_inline void *__kmalloc_node(size_t size, gfp_t flags, in= t node) @@ -574,7 +575,7 @@ static __always_inline void *kmalloc_large(size_t siz= e, gfp_t flags) * Try really hard to succeed the allocation but fail * eventually. */ -static __always_inline void *kmalloc(size_t size, gfp_t flags) +static __always_inline __alloc_size(1) void *kmalloc(size_t size, gfp_t = flags) { if (__builtin_constant_p(size)) { #ifndef CONFIG_SLOB @@ -596,7 +597,8 @@ static __always_inline void *kmalloc(size_t size, gfp= _t flags) return __kmalloc(size, flags); } =20 -static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int = node) +static __always_inline __alloc_size(1) void * +kmalloc_node(size_t size, gfp_t flags, int node) { #ifndef CONFIG_SLOB if (__builtin_constant_p(size) && @@ -620,7 +622,8 @@ static __always_inline void *kmalloc_node(size_t size= , gfp_t flags, int node) * @size: element size. * @flags: the type of memory to allocate (see kmalloc). */ -static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) +static inline __alloc_size(1, 2) void * +kmalloc_array(size_t n, size_t size, gfp_t flags) { size_t bytes; =20 @@ -638,7 +641,7 @@ static inline void *kmalloc_array(size_t n, size_t si= ze, gfp_t flags) * @new_size: new size of a single member of the array * @flags: the type of memory to allocate (see kmalloc) */ -static __must_check inline void * +static __must_check inline __alloc_size(2, 3) void * krealloc_array(void *p, size_t new_n, size_t new_size, gfp_t flags) { size_t bytes; @@ -655,7 +658,8 @@ krealloc_array(void *p, size_t new_n, size_t new_size= , gfp_t flags) * @size: element size. * @flags: the type of memory to allocate (see kmalloc). */ -static inline void *kcalloc(size_t n, size_t size, gfp_t flags) +static inline __alloc_size(1, 2) void * +kcalloc(size_t n, size_t size, gfp_t flags) { return kmalloc_array(n, size, flags | __GFP_ZERO); } @@ -684,7 +688,8 @@ static inline void *kmalloc_array_node(size_t n, size= _t size, gfp_t flags, return __kmalloc_node(bytes, flags, node); } =20 -static inline void *kcalloc_node(size_t n, size_t size, gfp_t flags, int= node) +static inline __alloc_size(1, 2) void * +kcalloc_node(size_t n, size_t size, gfp_t flags, int node) { return kmalloc_array_node(n, size, flags | __GFP_ZERO, node); } @@ -716,7 +721,8 @@ static inline void *kmem_cache_zalloc(struct kmem_cac= he *k, gfp_t flags) * @size: how many bytes of memory are required. * @flags: the type of memory to allocate (see kmalloc). */ -static inline void *kzalloc(size_t size, gfp_t flags) +static inline __alloc_size(1) void * +kzalloc(size_t size, gfp_t flags) { return kmalloc(size, flags | __GFP_ZERO); } @@ -727,26 +733,31 @@ static inline void *kzalloc(size_t size, gfp_t flag= s) * @flags: the type of memory to allocate (see kmalloc). * @node: memory node from which to allocate */ -static inline void *kzalloc_node(size_t size, gfp_t flags, int node) +static inline __alloc_size(1) void * +kzalloc_node(size_t size, gfp_t flags, int node) { return kmalloc_node(size, flags | __GFP_ZERO, node); } =20 -extern void *kvmalloc_node(size_t size, gfp_t flags, int node); -static inline void *kvmalloc(size_t size, gfp_t flags) +extern __alloc_size(1) void * +kvmalloc_node(size_t size, gfp_t flags, int node); +static inline __alloc_size(1) void *kvmalloc(size_t size, gfp_t flags) { return kvmalloc_node(size, flags, NUMA_NO_NODE); } -static inline void *kvzalloc_node(size_t size, gfp_t flags, int node) +static inline __alloc_size(1) void * +kvzalloc_node(size_t size, gfp_t flags, int node) { return kvmalloc_node(size, flags | __GFP_ZERO, node); } -static inline void *kvzalloc(size_t size, gfp_t flags) +static inline __alloc_size(1) void * +kvzalloc(size_t size, gfp_t flags) { return kvmalloc(size, flags | __GFP_ZERO); } =20 -static inline void *kvmalloc_array(size_t n, size_t size, gfp_t flags) +static inline __alloc_size(1, 2) void * +kvmalloc_array(size_t n, size_t size, gfp_t flags) { size_t bytes; =20 @@ -756,13 +767,14 @@ static inline void *kvmalloc_array(size_t n, size_t= size, gfp_t flags) return kvmalloc(bytes, flags); } =20 -static inline void *kvcalloc(size_t n, size_t size, gfp_t flags) +static inline __alloc_size(1, 2) void * +kvcalloc(size_t n, size_t size, gfp_t flags) { return kvmalloc_array(n, size, flags | __GFP_ZERO); } =20 -extern void *kvrealloc(const void *p, size_t oldsize, size_t newsize, - gfp_t flags); +extern __alloc_size(3) void * +kvrealloc(const void *p, size_t oldsize, size_t newsize, gfp_t flags); extern void kvfree(const void *addr); extern void kvfree_sensitive(const void *addr, size_t len); =20 --=20 2.30.2