Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lkdtm/heap: Add init_on_alloc tests

Add SLAB and page allocator tests for init_on_alloc. Testing for
init_on_free was already happening via the poisoning tests.

Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20210623203936.3151093-10-keescook@chromium.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Kees Cook and committed by
Greg Kroah-Hartman
37a0ca7f b61ce4d8

+72
+2
drivers/misc/lkdtm/core.c
··· 127 127 CRASHTYPE(READ_AFTER_FREE), 128 128 CRASHTYPE(WRITE_BUDDY_AFTER_FREE), 129 129 CRASHTYPE(READ_BUDDY_AFTER_FREE), 130 + CRASHTYPE(SLAB_INIT_ON_ALLOC), 131 + CRASHTYPE(BUDDY_INIT_ON_ALLOC), 130 132 CRASHTYPE(SLAB_FREE_DOUBLE), 131 133 CRASHTYPE(SLAB_FREE_CROSS), 132 134 CRASHTYPE(SLAB_FREE_PAGE),
+65
drivers/misc/lkdtm/heap.c
··· 174 174 kfree(val); 175 175 } 176 176 177 + void lkdtm_SLAB_INIT_ON_ALLOC(void) 178 + { 179 + u8 *first; 180 + u8 *val; 181 + 182 + first = kmalloc(512, GFP_KERNEL); 183 + if (!first) { 184 + pr_info("Unable to allocate 512 bytes the first time.\n"); 185 + return; 186 + } 187 + 188 + memset(first, 0xAB, 512); 189 + kfree(first); 190 + 191 + val = kmalloc(512, GFP_KERNEL); 192 + if (!val) { 193 + pr_info("Unable to allocate 512 bytes the second time.\n"); 194 + return; 195 + } 196 + if (val != first) { 197 + pr_warn("Reallocation missed clobbered memory.\n"); 198 + } 199 + 200 + if (memchr(val, 0xAB, 512) == NULL) { 201 + pr_info("Memory appears initialized (%x, no earlier values)\n", *val); 202 + } else { 203 + pr_err("FAIL: Slab was not initialized\n"); 204 + pr_expected_config_param(CONFIG_INIT_ON_ALLOC_DEFAULT_ON, "init_on_alloc"); 205 + } 206 + kfree(val); 207 + } 208 + 209 + void lkdtm_BUDDY_INIT_ON_ALLOC(void) 210 + { 211 + u8 *first; 212 + u8 *val; 213 + 214 + first = (u8 *)__get_free_page(GFP_KERNEL); 215 + if (!first) { 216 + pr_info("Unable to allocate first free page\n"); 217 + return; 218 + } 219 + 220 + memset(first, 0xAB, PAGE_SIZE); 221 + free_page((unsigned long)first); 222 + 223 + val = (u8 *)__get_free_page(GFP_KERNEL); 224 + if (!val) { 225 + pr_info("Unable to allocate second free page\n"); 226 + return; 227 + } 228 + 229 + if (val != first) { 230 + pr_warn("Reallocation missed clobbered memory.\n"); 231 + } 232 + 233 + if (memchr(val, 0xAB, PAGE_SIZE) == NULL) { 234 + pr_info("Memory appears initialized (%x, no earlier values)\n", *val); 235 + } else { 236 + pr_err("FAIL: Slab was not initialized\n"); 237 + pr_expected_config_param(CONFIG_INIT_ON_ALLOC_DEFAULT_ON, "init_on_alloc"); 238 + } 239 + free_page((unsigned long)val); 240 + } 241 + 177 242 void lkdtm_SLAB_FREE_DOUBLE(void) 178 243 { 179 244 int *val;
+2
drivers/misc/lkdtm/lkdtm.h
··· 86 86 void lkdtm_READ_AFTER_FREE(void); 87 87 void lkdtm_WRITE_BUDDY_AFTER_FREE(void); 88 88 void lkdtm_READ_BUDDY_AFTER_FREE(void); 89 + void lkdtm_SLAB_INIT_ON_ALLOC(void); 90 + void lkdtm_BUDDY_INIT_ON_ALLOC(void); 89 91 void lkdtm_SLAB_FREE_DOUBLE(void); 90 92 void lkdtm_SLAB_FREE_CROSS(void); 91 93 void lkdtm_SLAB_FREE_PAGE(void);
+1
tools/testing/selftests/lkdtm/config
··· 5 5 CONFIG_HARDENED_USERCOPY=y 6 6 # CONFIG_HARDENED_USERCOPY_FALLBACK is not set 7 7 CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y 8 + CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
+2
tools/testing/selftests/lkdtm/tests.txt
··· 21 21 READ_AFTER_FREE call trace:|Memory correctly poisoned 22 22 #WRITE_BUDDY_AFTER_FREE Corrupts memory on failure 23 23 READ_BUDDY_AFTER_FREE call trace:|Memory correctly poisoned 24 + SLAB_INIT_ON_ALLOC Memory appears initialized 25 + BUDDY_INIT_ON_ALLOC Memory appears initialized 24 26 SLAB_FREE_DOUBLE 25 27 SLAB_FREE_CROSS 26 28 SLAB_FREE_PAGE