All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <kees@kernel.org>
To: "Mickaël Salaün" <mic@digikod.net>
Cc: "Randy Dunlap" <rdunlap@infradead.org>,
	"Steven Rostedt" <rostedt@goodmis.org>,
	"Stephen Rothwell" <sfr@canb.auug.org.au>,
	"Linux Next Mailing List" <linux-next@vger.kernel.org>,
	"Linux Kernel Mailing List" <linux-kernel@vger.kernel.org>,
	linux-security-module@vger.kernel.org,
	"Günther Noack" <gnoack@google.com>
Subject: Re: linux-next: Tree for May 16 (security/landlock/ruleset.c)
Date: Mon, 19 May 2025 12:15:30 -0700	[thread overview]
Message-ID: <202505191212.61EE1AE80@keescook> (raw)
In-Reply-To: <20250519.ba8eoZu3XaeJ@digikod.net>

On Mon, May 19, 2025 at 08:41:17PM +0200, Mickaël Salaün wrote:
> On Mon, May 19, 2025 at 11:19:53AM -0700, Kees Cook wrote:
> > On Mon, May 19, 2025 at 05:29:30PM +0200, Mickaël Salaün wrote:
> > > On Fri, May 16, 2025 at 07:54:14PM -0700, Randy Dunlap wrote:
> > > > 
> > > > 
> > > > On 5/16/25 3:24 AM, Stephen Rothwell wrote:
> > > > > Hi all,
> > > > > 
> > > > > Changes since 20250515:
> > > 
> > > Thanks for the report.
> > > 
> > > It is the same warning as reported here:
> > > https://lore.kernel.org/all/202501040747.S3LYfvYq-lkp@intel.com/
> > > 
> > > I don't know what the actual issue is though.
> > > 
> > > > 
> > > > on i386:
> > > > 
> > > > In file included from ../arch/x86/include/asm/string.h:3,
> > > >                  from ../include/linux/string.h:65,
> > > >                  from ../include/linux/bitmap.h:13,
> > > >                  from ../include/linux/cpumask.h:12,
> > > >                  from ../include/linux/smp.h:13,
> > > >                  from ../include/linux/lockdep.h:14,
> > > >                  from ../security/landlock/ruleset.c:16:
> > > > ../security/landlock/ruleset.c: In function 'create_rule':
> > > > ../arch/x86/include/asm/string_32.h:150:25: warning: '__builtin_memcpy' accessing 4294967295 bytes at offsets 20 and 0 overlaps 6442450943 bytes at offset -2147483648 [-Wrestrict]
> > > >   150 | #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
> > > >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~
> > > > ../security/landlock/ruleset.c:137:9: note: in expansion of macro 'memcpy'
> > > >   137 |         memcpy(new_rule->layers, layers,
> > > >       |         ^~~~~~
> > > > 
> > > > 
> > > > Full randconfig file is attached.
> > 
> > The trigger appears to be CONFIG_PROFILE_ALL_BRANCHES, and GCC getting
> > tricked into thinking check_mul_overflow() returns true:
> > 
> > In file included from ../arch/x86/include/asm/string.h:3,
> >                  from ../include/linux/string.h:65,
> >                  from ../include/linux/bitmap.h:13,
> >                  from ../include/linux/cpumask.h:12,
> >                  from ../include/linux/smp.h:13,
> >                  from ../include/linux/lockdep.h:14,
> >                  from ../security/landlock/ruleset.c:16:
> > ../security/landlock/ruleset.c: In function 'create_rule':
> > ../arch/x86/include/asm/string_32.h:150:25: warning: '__builtin_memcpy' accessing 4294967295 bytes at offsets 0 and 0 overlaps 6442450943 bytes at offset -2147483648 [-Wrestrict]
> >   150 | #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
> >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~
> > ../security/landlock/ruleset.c:137:9: note: in expansion of macro 'memcpy'
> >   137 |         memcpy(new_rule->layers, layers,
> >       |         ^~~~~~
> >   'create_rule': event 1
> > ../include/linux/compiler.h:69:46:
> >    68 |         (cond) ?                                        \
> >       |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >    69 |                 (__if_trace.miss_hit[1]++,1) :          \
> >       |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
> >       |                                              |
> >       |                                              (1) when the condition is evaluated to true
> >    70 |                 (__if_trace.miss_hit[0]++,0);           \
> >       |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
> > ../include/linux/compiler.h:57:69: note: in expansion of macro '__trace_if_value'
> >    57 | #define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
> >       |                                                                     ^~~~~~~~~~~~~~~~
> > ../include/linux/compiler.h:55:28: note: in expansion of macro '__trace_if_var'
> >    55 | #define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
> >       |                            ^~~~~~~~~~~~~~
> > ../include/linux/overflow.h:270:9: note: in expansion of macro 'if'
> >   270 |         if (check_mul_overflow(factor1, factor2, &bytes))
> >       |         ^~
> >   'create_rule': event 2
> > ../arch/x86/include/asm/string_32.h:150:25:
> >   150 | #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
> >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~
> >       |                         |
> >       |                         (2) out of array bounds here
> > ../security/landlock/ruleset.c:137:9: note: in expansion of macro 'memcpy'
> >   137 |         memcpy(new_rule->layers, layers,
> >       |         ^~~~~~
> > make[1]: Leaving directory '/srv/code/gcc-bug'
> 
> That's interesting...
> 
> > 
> > 
> > I'll take a look at ways to make either the overflow macros or memcpy
> > robust against this kind of weirdness...
> 
> Thanks!

I'm doing some build testing, but the below patch makes GCC happy.
Alternatively we could make CONFIG_PROFILE_ALL_BRANCHES=y depend on
CONFIG_FORTIFY_SOURCE=y ...


From 6fbf66fdfd0a7dac809b77faafdd72c60112bb8d Mon Sep 17 00:00:00 2001
From: Kees Cook <kees@kernel.org>
Date: Mon, 19 May 2025 11:52:06 -0700
Subject: [PATCH] string.h: Provide basic sanity checks for fallback memcpy()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Instead of defining memcpy() in terms of __builtin_memcpy() deep
in arch/x86/include/asm/string_32.h, notice that it is needed up in
the general string.h, as done with other common C String APIs. This
allows us to add basic sanity checking for pathological "size"
arguments to memcpy(). Besides the run-time checking benefit, this
avoids GCC trying to be very smart about value range tracking[1] when
CONFIG_PROFILE_ALL_BRANCHES=y but FORTIFY_SOURCE=n.

Link: https://lore.kernel.org/all/202505191117.C094A90F88@keescook/ [1]
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/all/202501040747.S3LYfvYq-lkp@intel.com/
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Closes: https://lore.kernel.org/all/e3754f69-1dea-4542-8de0-a567a14fb95b@infradead.org/
Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: "Mickaël Salaün" <mic@digikod.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: <x86@kernel.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Andy Shevchenko <andy@kernel.org>
Cc: Uros Bizjak <ubizjak@gmail.com>
Cc: <linux-hardening@vger.kernel.org>
---
 arch/x86/include/asm/string_32.h |  6 ------
 include/linux/string.h           | 13 +++++++++++++
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/string_32.h b/arch/x86/include/asm/string_32.h
index e9cce169bb4c..74397c95fa37 100644
--- a/arch/x86/include/asm/string_32.h
+++ b/arch/x86/include/asm/string_32.h
@@ -145,12 +145,6 @@ static __always_inline void *__constant_memcpy(void *to, const void *from,
 #define __HAVE_ARCH_MEMCPY
 extern void *memcpy(void *, const void *, size_t);
 
-#ifndef CONFIG_FORTIFY_SOURCE
-
-#define memcpy(t, f, n) __builtin_memcpy(t, f, n)
-
-#endif /* !CONFIG_FORTIFY_SOURCE */
-
 #define __HAVE_ARCH_MEMMOVE
 void *memmove(void *dest, const void *src, size_t n);
 
diff --git a/include/linux/string.h b/include/linux/string.h
index 01621ad0f598..ffcee31a14f9 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -3,6 +3,7 @@
 #define _LINUX_STRING_H_
 
 #include <linux/args.h>
+#include <linux/bug.h>
 #include <linux/array_size.h>
 #include <linux/cleanup.h>	/* for DEFINE_FREE() */
 #include <linux/compiler.h>	/* for inline */
@@ -390,7 +391,19 @@ static inline const char *kbasename(const char *path)
 
 #if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE)
 #include <linux/fortify-string.h>
+#else
+/* Basic sanity checking even without FORTIFY_SOURCE */
+# ifndef __HAVE_ARCH_MEMCPY
+#  define memcpy(t, f, n)					\
+	do {							\
+		typeof(n) __n = (n);				\
+		/* Skip impossible sizes. */			\
+		if (!WARN_ON(__n < 0 || __n == SIZE_MAX))	\
+			__builtin_memcpy(t, f, __n);		\
+	} while (0)
+# endif
 #endif
+
 #ifndef unsafe_memcpy
 #define unsafe_memcpy(dst, src, bytes, justification)		\
 	memcpy(dst, src, bytes)
-- 
2.34.1



-- 
Kees Cook

  reply	other threads:[~2025-05-19 19:15 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-16 10:24 linux-next: Tree for May 16 Stephen Rothwell
2025-05-16 21:03 ` linux-next: Tree for May 16 [drivers/platform/x86/amd/hsmp/hsmp_acpi.ko] Randy Dunlap
2025-05-17  2:54 ` linux-next: Tree for May 16 (security/landlock/ruleset.c) Randy Dunlap
2025-05-19 15:29   ` Mickaël Salaün
2025-05-19 18:19     ` Kees Cook
2025-05-19 18:41       ` Mickaël Salaün
2025-05-19 19:15         ` Kees Cook [this message]
2025-05-19 20:26           ` Randy Dunlap
2025-05-20 16:44             ` Kees Cook
2025-05-20 14:01           ` Andy Shevchenko
2025-05-20 16:47             ` Kees Cook
2025-05-20 14:45           ` Mickaël Salaün
2025-05-20 15:48             ` Randy Dunlap
2025-05-20 16:15             ` Kees Cook
2025-05-19 21:02 ` linux-next: Tree for May 16 (futex kernel-doc) Randy Dunlap
2025-05-20  7:59   ` Sebastian Andrzej Siewior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202505191212.61EE1AE80@keescook \
    --to=kees@kernel.org \
    --cc=gnoack@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-next@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mic@digikod.net \
    --cc=rdunlap@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=sfr@canb.auug.org.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.