Commit c2efa538 authored by Kees Cook's avatar Kees Cook
Browse files

lib: stackinit: Adjust target string to 8 bytes for m68k



For reasons I cannot understand, m68k moves the start of the stack frame
for consecutive calls to the same function if the function's test
variable is larger than 8 bytes. This was only happening for the char
array test (obviously), so adjust the length of the string for m68k
only. I want the array size to be longer than "unsigned long" for every
given architecture, so the other remain unchanged.

Additionally adjust the error message to be a bit more clear about
what's happened, and move the KUNIT check outside of the consecutive
calls to minimize what happens between them.

Reported-by: default avatarGuenter Roeck <linux@roeck-us.net>
Closes: https://lore.kernel.org/lkml/a0d10d50-2720-4ecd-a2c6-c2c5e5aeee65@roeck-us.net/


Tested-by: default avatarGuenter Roeck <linux@roeck-us.net>
Reported-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Closes: https://lore.kernel.org/r/CAMuHMdX_g1tbiUL9PUQdqaegrEzCNN3GtbSvSBFYAL4TzvstFg@mail.gmail.com
Closes: https://lore.kernel.org/r/CAMuHMdW6N40+0gGQ+LSrN64Mo4A0-ELAm0pR3gWQ0mNanyBuUQ@mail.gmail.com


Tested-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Link: https://lore.kernel.org/all/a4bf4063-194f-4740-9c1d-88f9ab38b778@roeck-us.net


Signed-off-by: default avatarKees Cook <keescook@chromium.org>
parent d4be85d0
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -63,7 +63,16 @@ static bool stackinit_range_contains(char *haystack_start, size_t haystack_size,
#define FETCH_ARG_STRING(var)		var
#define FETCH_ARG_STRUCT(var)		&var

/*
 * On m68k, if the leaf function test variable is longer than 8 bytes,
 * the start of the stack frame moves. 8 is sufficiently large to
 * test m68k char arrays, but leave it at 16 for other architectures.
 */
#ifdef CONFIG_M68K
#define FILL_SIZE_STRING		8
#else
#define FILL_SIZE_STRING		16
#endif

#define INIT_CLONE_SCALAR		/**/
#define INIT_CLONE_STRING		[FILL_SIZE_STRING]
@@ -165,19 +174,23 @@ static noinline void test_ ## name (struct kunit *test) \
	/* Verify all bytes overwritten with 0xFF. */		\
	for (sum = 0, i = 0; i < target_size; i++)		\
		sum += (check_buf[i] != 0xFF);			\
	KUNIT_ASSERT_EQ_MSG(test, sum, 0,			\
			    "leaf fill was not 0xFF!?\n");	\
	/* Clear entire check buffer for later bit tests. */	\
	memset(check_buf, 0x00, sizeof(check_buf));		\
	/* Extract stack-defined variable contents. */		\
	ignored = leaf_ ##name((unsigned long)&ignored, 0,	\
				FETCH_ARG_ ## which(zero));	\
	/*							\
	 * Delay the sum test to here to do as little as	\
	 * possible between the two leaf function calls.	\
	 */							\
	KUNIT_ASSERT_EQ_MSG(test, sum, 0,			\
			    "leaf fill was not 0xFF!?\n");	\
								\
	/* Validate that compiler lined up fill and target. */	\
	KUNIT_ASSERT_TRUE_MSG(test,				\
		stackinit_range_contains(fill_start, fill_size,	\
			    target_start, target_size),		\
		"stack fill missed target!? "			\
		"stackframe was not the same between calls!? "	\
		"(fill %zu wide, target offset by %d)\n",	\
		fill_size,					\
		(int)((ssize_t)(uintptr_t)fill_start -		\