diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-06-18 13:42:08 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-06-18 13:42:08 -0400 |
| commit | 915ed9320cba9ddb5da3f3ee49a8ceeed85fb5cc (patch) | |
| tree | d14322d5bff7b2a8fdc8ee934dd308982f430e6e | |
| parent | 29f785ff76b65696800b75c3d8e0b58e603bb1d0 (diff) | |
| parent | 8c30d32b1a326bb120635a8b4836ec61cba454fa (diff) | |
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
| -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 @@ | |||
| 12 | 12 | ||
| 13 | /* Exfiltration buffer. */ | 13 | /* Exfiltration buffer. */ |
| 14 | #define MAX_VAR_SIZE 128 | 14 | #define MAX_VAR_SIZE 128 |
| 15 | static char check_buf[MAX_VAR_SIZE]; | 15 | static u8 check_buf[MAX_VAR_SIZE]; |
| 16 | 16 | ||
| 17 | /* Character array to trigger stack protector in all functions. */ | 17 | /* Character array to trigger stack protector in all functions. */ |
| 18 | #define VAR_BUFFER 32 | 18 | #define VAR_BUFFER 32 |
| @@ -106,9 +106,18 @@ static noinline __init int test_ ## name (void) \ | |||
| 106 | \ | 106 | \ |
| 107 | /* Fill clone type with zero for per-field init. */ \ | 107 | /* Fill clone type with zero for per-field init. */ \ |
| 108 | memset(&zero, 0x00, sizeof(zero)); \ | 108 | memset(&zero, 0x00, sizeof(zero)); \ |
| 109 | /* Clear entire check buffer for 0xFF overlap test. */ \ | ||
| 110 | memset(check_buf, 0x00, sizeof(check_buf)); \ | ||
| 109 | /* Fill stack with 0xFF. */ \ | 111 | /* Fill stack with 0xFF. */ \ |
| 110 | ignored = leaf_ ##name((unsigned long)&ignored, 1, \ | 112 | ignored = leaf_ ##name((unsigned long)&ignored, 1, \ |
| 111 | FETCH_ARG_ ## which(zero)); \ | 113 | FETCH_ARG_ ## which(zero)); \ |
| 114 | /* Verify all bytes overwritten with 0xFF. */ \ | ||
| 115 | for (sum = 0, i = 0; i < target_size; i++) \ | ||
| 116 | sum += (check_buf[i] != 0xFF); \ | ||
| 117 | if (sum) { \ | ||
| 118 | pr_err(#name ": leaf fill was not 0xFF!?\n"); \ | ||
| 119 | return 1; \ | ||
| 120 | } \ | ||
| 112 | /* Clear entire check buffer for later bit tests. */ \ | 121 | /* Clear entire check buffer for later bit tests. */ \ |
| 113 | memset(check_buf, 0x00, sizeof(check_buf)); \ | 122 | memset(check_buf, 0x00, sizeof(check_buf)); \ |
| 114 | /* Extract stack-defined variable contents. */ \ | 123 | /* Extract stack-defined variable contents. */ \ |
| @@ -126,9 +135,9 @@ static noinline __init int test_ ## name (void) \ | |||
| 126 | return 1; \ | 135 | return 1; \ |
| 127 | } \ | 136 | } \ |
| 128 | \ | 137 | \ |
| 129 | /* Look for any set bits in the check region. */ \ | 138 | /* Look for any bytes still 0xFF in check region. */ \ |
| 130 | for (i = 0; i < sizeof(check_buf); i++) \ | 139 | for (sum = 0, i = 0; i < target_size; i++) \ |
| 131 | sum += (check_buf[i] != 0); \ | 140 | sum += (check_buf[i] == 0xFF); \ |
| 132 | \ | 141 | \ |
| 133 | if (sum == 0) \ | 142 | if (sum == 0) \ |
| 134 | pr_info(#name " ok\n"); \ | 143 | pr_info(#name " ok\n"); \ |
| @@ -162,13 +171,13 @@ static noinline __init int leaf_ ## name(unsigned long sp, \ | |||
| 162 | * Keep this buffer around to make sure we've got a \ | 171 | * Keep this buffer around to make sure we've got a \ |
| 163 | * stack frame of SOME kind... \ | 172 | * stack frame of SOME kind... \ |
| 164 | */ \ | 173 | */ \ |
| 165 | memset(buf, (char)(sp && 0xff), sizeof(buf)); \ | 174 | memset(buf, (char)(sp & 0xff), sizeof(buf)); \ |
| 166 | /* Fill variable with 0xFF. */ \ | 175 | /* Fill variable with 0xFF. */ \ |
| 167 | if (fill) { \ | 176 | if (fill) { \ |
| 168 | fill_start = &var; \ | 177 | fill_start = &var; \ |
| 169 | fill_size = sizeof(var); \ | 178 | fill_size = sizeof(var); \ |
| 170 | memset(fill_start, \ | 179 | memset(fill_start, \ |
| 171 | (char)((sp && 0xff) | forced_mask), \ | 180 | (char)((sp & 0xff) | forced_mask), \ |
| 172 | fill_size); \ | 181 | fill_size); \ |
| 173 | } \ | 182 | } \ |
| 174 | \ | 183 | \ |
