]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Merge tag 'meminit-v5.2-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/kees...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 Jun 2019 17:42:08 +0000 (10:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 Jun 2019 17:42:08 +0000 (10:42 -0700)
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

lib/test_stackinit.c

index e97dc54b4fdf3fae180c4f276814a5fa5cd1aafd..2d7d257a430e6d24c78f6193419f96578496126e 100644 (file)
@@ -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);                              \
        }                                                       \
                                                                \