On Tue, Feb 27, 2024 at 02:19:07PM -0800, Kees Cook wrote:
It is basically doing this: static void *fill_start, *target_start; static size_t fill_size, target_size; static noinline int leaf_char_array_none(unsigned long sp, bool fill, unsigned char *arg) { char buf[32]; unsigned char var[16]; target_start = &var; target_size = sizeof(var); /* * Keep this buffer around to make sure we've got a * stack frame of SOME kind... */ memset(buf, (char)(sp & 0xff), sizeof(buf)); /* Fill variable with 0xFF. */ if (fill) { fill_start = &var; fill_size = sizeof(var); memset(fill_start, (char)((sp & 0xff) | forced_mask), fill_size); } /* Silence "never initialized" warnings. */ do_nothing_char_array(var); /* Exfiltrate "var". */ memcpy(check_buf, target_start, target_size); return (int)buf[0] | (int)buf[sizeof(buf) - 1]; } and it's called as: ignored = leaf_char_array_none((unsigned long)&ignored, 1, zero); ... ignored = leaf_char_array_none((unsigned long)&ignored, 0, zero); The first call remembers where "var" is in the stack frame via the fill_start assignment, and the second call records where "var" is via the target_start assignment. The complaint is that it _changes_ between the two calls. ... Oh, I think I see what's happened. Between the two calls, the stack grows (and is for some reason not reclaimed) due to the KUNIT checks between the two leaf calls. Yes, moving that fixes it. I'll send a patch!
Oh, no, that wasn't it. Something else is happening. The stack pointer isn't moving between them. Is there anything special about character arrays on m68k? -- Kees Cook