diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-06-18 10:42:08 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-06-18 10:42:08 -0700 |
commit | 915ed9320cba9ddb5da3f3ee49a8ceeed85fb5cc (patch) | |
tree | d14322d5bff7b2a8fdc8ee934dd308982f430e6e /lib | |
parent | 29f785ff76b65696800b75c3d8e0b58e603bb1d0 (diff) | |
parent | 8c30d32b1a326bb120635a8b4836ec61cba454fa (diff) | |
download | linux-915ed9320cba9ddb5da3f3ee49a8ceeed85fb5cc.tar.gz linux-915ed9320cba9ddb5da3f3ee49a8ceeed85fb5cc.tar.bz2 linux-915ed9320cba9ddb5da3f3ee49a8ceeed85fb5cc.zip |
Merge tag 'meminit-v5.2-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull stack init fix from Kees Cook:
"This is a small update to the stack auto-initialization self-test code
to deal with the Clang initialization pattern.
It's been in linux-next for a couple weeks; I had waited a bit
wondering if anything more substantial was going to show up, but
nothing has, so I'm sending this now before it gets too late"
* tag 'meminit-v5.2-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
lib/test_stackinit: Handle Clang auto-initialization pattern
Diffstat (limited to 'lib')
-rw-r--r-- | lib/test_stackinit.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/lib/test_stackinit.c b/lib/test_stackinit.c index e97dc54b4fdf..2d7d257a430e 100644 --- a/lib/test_stackinit.c +++ b/lib/test_stackinit.c @@ -12,7 +12,7 @@ /* Exfiltration buffer. */ #define MAX_VAR_SIZE 128 -static char check_buf[MAX_VAR_SIZE]; +static u8 check_buf[MAX_VAR_SIZE]; /* Character array to trigger stack protector in all functions. */ #define VAR_BUFFER 32 @@ -106,9 +106,18 @@ static noinline __init int test_ ## name (void) \ \ /* Fill clone type with zero for per-field init. */ \ memset(&zero, 0x00, sizeof(zero)); \ + /* Clear entire check buffer for 0xFF overlap test. */ \ + memset(check_buf, 0x00, sizeof(check_buf)); \ /* Fill stack with 0xFF. */ \ ignored = leaf_ ##name((unsigned long)&ignored, 1, \ FETCH_ARG_ ## which(zero)); \ + /* Verify all bytes overwritten with 0xFF. */ \ + for (sum = 0, i = 0; i < target_size; i++) \ + sum += (check_buf[i] != 0xFF); \ + if (sum) { \ + pr_err(#name ": leaf fill was not 0xFF!?\n"); \ + return 1; \ + } \ /* Clear entire check buffer for later bit tests. */ \ memset(check_buf, 0x00, sizeof(check_buf)); \ /* Extract stack-defined variable contents. */ \ @@ -126,9 +135,9 @@ static noinline __init int test_ ## name (void) \ return 1; \ } \ \ - /* Look for any set bits in the check region. */ \ - for (i = 0; i < sizeof(check_buf); i++) \ - sum += (check_buf[i] != 0); \ + /* Look for any bytes still 0xFF in check region. */ \ + for (sum = 0, i = 0; i < target_size; i++) \ + sum += (check_buf[i] == 0xFF); \ \ if (sum == 0) \ pr_info(#name " ok\n"); \ @@ -162,13 +171,13 @@ static noinline __init int leaf_ ## name(unsigned long sp, \ * Keep this buffer around to make sure we've got a \ * stack frame of SOME kind... \ */ \ - memset(buf, (char)(sp && 0xff), sizeof(buf)); \ + 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), \ + (char)((sp & 0xff) | forced_mask), \ fill_size); \ } \ \ |