From patchwork Fri Mar 21 20:41:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 14026037 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1306C36007 for ; Fri, 21 Mar 2025 20:41:21 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 0B95D280005; Fri, 21 Mar 2025 16:41:12 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B0695280008; Fri, 21 Mar 2025 16:41:11 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 58D79280009; Fri, 21 Mar 2025 16:41:11 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id DA067280005 for ; Fri, 21 Mar 2025 16:41:10 -0400 (EDT) Received: from smtpin11.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 587661601F2 for ; Fri, 21 Mar 2025 20:41:12 +0000 (UTC) X-FDA: 83246727984.11.E09186A Received: from sea.source.kernel.org (sea.source.kernel.org [172.234.252.31]) by imf20.hostedemail.com (Postfix) with ESMTP id 754941C0011 for ; Fri, 21 Mar 2025 20:41:10 +0000 (UTC) Authentication-Results: imf20.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=WtJq8S47; spf=pass (imf20.hostedemail.com: domain of kees@kernel.org designates 172.234.252.31 as permitted sender) smtp.mailfrom=kees@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1742589670; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=VbKWtK+NrfMUzgaefAJgL3246DTAiQjDK5yAvA0Y/sc=; b=clV4PhNw07BPVOAN83NpBb4Er502PZ1BT4lqDeODFdzy7n6Codf9ELkGOpqOOt16jz34Yi vQPo/x41bNvQenrmTl72wkh9zlVQ+CMjoMhbFCwMvOGsekZasQefyoJ3CgpThsJEMNxigL +NzbgaX1Dg6hbW9uf/nwAqyRxyVxFKA= ARC-Authentication-Results: i=1; imf20.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=WtJq8S47; spf=pass (imf20.hostedemail.com: domain of kees@kernel.org designates 172.234.252.31 as permitted sender) smtp.mailfrom=kees@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1742589670; a=rsa-sha256; cv=none; b=Fz4B+/n09BMckoFRNZW2fnbHit/jKm2EERh2G5ao3uYAsXSzSyzeBwVcA8z7ErQ+BlTMzS dWY7UfOSdPplqkyCYu7WaNZvd8drNYhkqzckKnQ230Av/agPRPK8gZeW5M8D13paqucQJc NGY0bJ/SLXvgnZ0qSVDLXVuSLyXCl2o= Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id DB04544118; Fri, 21 Mar 2025 20:41:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EF32AC4CEEE; Fri, 21 Mar 2025 20:41:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1742589669; bh=8jN+LgPc4pYO7xP8Ft4KTlabcnXZcFpxZy0ZLjzDlJ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WtJq8S47J/UuWqIAzy9TuEJGFQk4HJuLRbH8atr4DkckIW8aXz4mhZhyDvxpREsHs pRz/myqOcZP8kBIQkxj93QtnE+NoL+cAe8pFBq7KoEgOYgT+S7+YVyC1kTj3K2YKxn u6pcn5daWnjtIktg8f1Da/vbZCLSx2+f4TSuTkwxby6VkAodokz6T/fhVvsL6TTcVS mb2Nxlku8Sm528ibouXmGEjQAMLBewdMwBIsPBZCtlgJirx5gvUM+2GbM62VL/ZHb0 8UXSomC4QEcbKaDad86AheREhHoY/DmO1oSa06aS177vok6kSNQbvGm0zpCEybBQGT ls9yw8rB8S+vg== From: Kees Cook To: Vlastimil Babka Cc: Kees Cook , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Roman Gushchin , Hyeonggon Yoo <42.hyeyoo@gmail.com>, linux-mm@kvack.org, Miguel Ojeda , Nathan Chancellor , Marco Elver , Nick Desaulniers , Przemek Kitszel , linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH 4/5] slab: Set freed variables to NULL by default Date: Fri, 21 Mar 2025 13:41:00 -0700 Message-Id: <20250321204105.1898507-4-kees@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250321202620.work.175-kees@kernel.org> References: <20250321202620.work.175-kees@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4269; i=kees@kernel.org; h=from:subject; bh=8jN+LgPc4pYO7xP8Ft4KTlabcnXZcFpxZy0ZLjzDlJ8=; b=owGbwMvMwCVmps19z/KJym7G02pJDOl3z92p+u+64HJA29I5My3e3+V+YpHjosRV7hSQWLmb7 2rYS9nOjlIWBjEuBlkxRZYgO/c4F4+37eHucxVh5rAygQxh4OIUgIm0zWX4Kymo1fzu4dItS5lN L54sOBR8f4ZR2IcXrw5xa11VYq+TyGFkuH5kVZ9nvsOsv+6xv36efM6lFZbqfmciZ4tSmPrNljf ubAA= X-Developer-Key: i=kees@kernel.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 X-Rspamd-Queue-Id: 754941C0011 X-Rspamd-Server: rspam05 X-Rspam-User: X-Stat-Signature: x7i3duos5rogusdnt5hazxpt67qrtxoz X-HE-Tag: 1742589670-964968 X-HE-Meta: U2FsdGVkX1/MvXktD2u7UY6dvfYFzE0/59c6k2OLpBeA5D2ZrXD5//Ro11EMcmmOmezizeDwV+m8O0N1hXkl234wCh/lm7rsXaXtLtMYwkbVzbu29j4M73m/g+7HESGWEa7voycM5SgGGhx9siGVkFRoRmgEW1c4nfwoCoG/HZvvNywxEPjgFu38syOevt1pR9yC2ttZW/qEvLgY/gv99NM3cQuoV+K/JU//d9GvtmqS7tsRAicwqHUsCXfVay27LXp+vY+BWXjyGvcewlawGve+aRknRoLL5BbQcH4dgxhNLUJjrCy1QPiDXkmMOTPiQB/eScmHXKIb/Vl4N1R7KPE3Or4mUx91alEe1nl0gCX+XQyiJkL6ZrWyu89Cqc1tVvfRXtzwMJDOH/LQssBtZyy7QvsEERQXZnIMo1/uqzNsru2Q8FNSWQcJxCKmd/BbjRb8HZIu0vURJlYuFUBjOdvCSyqzsj7InbJ4wvpVErsK83go5gBzAt9Aw2CbV655BBpKEORYAc2FBB4da60ub54nJgp/hz+88/A8NtHaC+di9CmJQNYq97P//LnaCi5uzbeEE2Qf/T8cXlaXXV+1UTflFVSpHRx6AvWtOG0hYqLIs5K9wVzlbOy8lwCBDh2n8gKlfGdMm/rYKaxJWP/XWeUevUhGKwohZpgzSS4HYtr1EOzUJA5Yj9Hn45fBMa/q4iXrQ8iaid78rIygDM9y8nFP+dEvjLG9ulLKzkLqdYP5C07dtlxuhwFU0ImRLvq7mcpicWdOLS3M87Iu8iyULzpkIvSKygWZFPsA7+IEhY60kQntDXuCr3egkaaQHIonk92Fgs6MR8XDTRAzBnvXo5fIU10sws9eI2lnXA6/eto+Kz37mugZyzP3A5itYoKe3B4btPBCfM07hcfrs/J+45YkKgPn4nTM2MbT6XTbWoRNkPlrgZeK7epjpXjenFbhL6TwBPoiNYekdSeKJuD +XGIMcpa tuEkhRU5P0pnwCZYaM0ppiP5/rra6Pj96nA/ogNka33IxjEmO2C3YysKaIKfWAK/kUV85gEWW8V9HywNxuwUVMUNVbRD6RGvaiU2KQo+u0+TDnn4EPvNPvNQm+VqYYDh5Zpb2WslnQ7QHx59uPYf0C83LIyHMMZ0vDxGilGNcULWnrDE5natXOE6jQpQIifJeLXgHT1ndHoC95Qw+cXg5TVXt23ywJEP/VoVaqE5GV8h4KoBZobzhbqq3S62pZp7sGjv3Z+dGpfXcpoLypUGv8b7jWHQa+NXiIhE1F8d9E6f5Ebb0q4SooX7rvCvHyg66+3pIJFWKFiu0NqhG67lcGTG0OKDiuu5w/2fjVNJNsPArXl/UNLHXqfTCzWXBusggzqiGsXPYF7AOetclM2DLKvqKAvJc2if/A/ypgMu/AAA4e8yT0jqz94Zw7Q4Dh5Wv7itRI6pURouIq36QbV+tEV1s2dwPyLmVPVnKdPmk/Tl/UZ4kMwbJIdI/rRXkuGTz+f0zqCR3RMUA8FmXP+A0KJ3ISLRliFFWR/kLOPB8afBTv9DLfawc89edKn4NjLvcZRaha2qX9fDIyM8= 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: List-Subscribe: List-Unsubscribe: To defang a subset of "dangling pointer" use-after-free flaws[1], take the address of any lvalues passed to kfree() and set them to NULL after freeing. To do this manually, kfree_and_null() (and the "sensitive" variant) are introduced. Link: https://github.com/KSPP/linux/issues/87 [1] Signed-off-by: Kees Cook --- Cc: Vlastimil Babka Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Cc: Andrew Morton Cc: Roman Gushchin Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com> Cc: linux-mm@kvack.org --- include/linux/slab.h | 30 +++++++++++++++++++++++++++--- mm/slab_common.c | 8 ++++---- mm/slub.c | 6 +++--- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/include/linux/slab.h b/include/linux/slab.h index 3e807ccc8583..2717ad238fa2 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -465,11 +465,35 @@ void * __must_check krealloc_noprof(const void *objp, size_t new_size, gfp_t flags) __realloc_size(2); #define krealloc(...) alloc_hooks(krealloc_noprof(__VA_ARGS__)) -void kfree(const void *objp); -void kfree_sensitive(const void *objp); +void __kfree(const void *objp); +void __kfree_sensitive(const void *objp); size_t __ksize(const void *objp); -#define __kfree(x) kfree(x) +static inline void kfree_and_null(void **ptr) +{ + __kfree(*ptr); + *ptr = NULL; +} +static inline void kfree_sensitive_and_null(void **ptr) +{ + __kfree_sensitive(*ptr); + *ptr = NULL; +} + +#define __force_lvalue_expr(x) \ + __builtin_choose_expr(__is_lvalue(x), x, (void *){ NULL }) + +#define __free_and_null(__how, x) \ +({ \ + typeof(x) *__ptr = &(x); \ + __how ## _and_null((void **)__ptr); \ +}) +#define __free_and_maybe_null(__how, x) \ + __builtin_choose_expr(__is_lvalue(x), \ + __free_and_null(__how, __force_lvalue_expr(x)), \ + __kfree(x)) +#define kfree(x) __free_and_maybe_null(kfree, x) +#define kfree_sensitive(x) __free_and_maybe_null(kfree_sensitive, x) DEFINE_FREE(kfree, void *, if (!IS_ERR_OR_NULL(_T)) kfree(_T)) DEFINE_FREE(kfree_sensitive, void *, if (_T) kfree_sensitive(_T)) diff --git a/mm/slab_common.c b/mm/slab_common.c index 4030907b6b7d..9a82952ec266 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -1211,7 +1211,7 @@ module_init(slab_proc_init); #endif /* CONFIG_SLUB_DEBUG */ /** - * kfree_sensitive - Clear sensitive information in memory before freeing + * __kfree_sensitive - Clear sensitive information in memory before freeing * @p: object to free memory of * * The memory of the object @p points to is zeroed before freed. @@ -1221,7 +1221,7 @@ module_init(slab_proc_init); * deal bigger than the requested buffer size passed to kmalloc(). So be * careful when using this function in performance sensitive code. */ -void kfree_sensitive(const void *p) +void __kfree_sensitive(const void *p) { size_t ks; void *mem = (void *)p; @@ -1231,9 +1231,9 @@ void kfree_sensitive(const void *p) kasan_unpoison_range(mem, ks); memzero_explicit(mem, ks); } - kfree(mem); + __kfree(mem); } -EXPORT_SYMBOL(kfree_sensitive); +EXPORT_SYMBOL(__kfree_sensitive); size_t ksize(const void *objp) { diff --git a/mm/slub.c b/mm/slub.c index 1f50129dcfb3..38dd898667bf 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -4729,12 +4729,12 @@ static void free_large_kmalloc(struct folio *folio, void *object) } /** - * kfree - free previously allocated memory + * __kfree - free previously allocated memory * @object: pointer returned by kmalloc() or kmem_cache_alloc() * * If @object is NULL, no operation is performed. */ -void kfree(const void *object) +void __kfree(const void *object) { struct folio *folio; struct slab *slab; @@ -4756,7 +4756,7 @@ void kfree(const void *object) s = slab->slab_cache; slab_free(s, slab, x, _RET_IP_); } -EXPORT_SYMBOL(kfree); +EXPORT_SYMBOL(__kfree); static __always_inline __realloc_size(2) void * __do_krealloc(const void *p, size_t new_size, gfp_t flags)