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

Configure Feed

Select the types of activity you want to include in your feed.

at v4.15-rc9 144 lines 3.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * This is for all the tests relating directly to heap memory, including 4 * page allocation and slab allocations. 5 */ 6#include "lkdtm.h" 7#include <linux/slab.h> 8#include <linux/sched.h> 9 10/* 11 * This tries to stay within the next largest power-of-2 kmalloc cache 12 * to avoid actually overwriting anything important if it's not detected 13 * correctly. 14 */ 15void lkdtm_OVERWRITE_ALLOCATION(void) 16{ 17 size_t len = 1020; 18 u32 *data = kmalloc(len, GFP_KERNEL); 19 20 data[1024 / sizeof(u32)] = 0x12345678; 21 kfree(data); 22} 23 24void lkdtm_WRITE_AFTER_FREE(void) 25{ 26 int *base, *again; 27 size_t len = 1024; 28 /* 29 * The slub allocator uses the first word to store the free 30 * pointer in some configurations. Use the middle of the 31 * allocation to avoid running into the freelist 32 */ 33 size_t offset = (len / sizeof(*base)) / 2; 34 35 base = kmalloc(len, GFP_KERNEL); 36 pr_info("Allocated memory %p-%p\n", base, &base[offset * 2]); 37 pr_info("Attempting bad write to freed memory at %p\n", 38 &base[offset]); 39 kfree(base); 40 base[offset] = 0x0abcdef0; 41 /* Attempt to notice the overwrite. */ 42 again = kmalloc(len, GFP_KERNEL); 43 kfree(again); 44 if (again != base) 45 pr_info("Hmm, didn't get the same memory range.\n"); 46} 47 48void lkdtm_READ_AFTER_FREE(void) 49{ 50 int *base, *val, saw; 51 size_t len = 1024; 52 /* 53 * The slub allocator uses the first word to store the free 54 * pointer in some configurations. Use the middle of the 55 * allocation to avoid running into the freelist 56 */ 57 size_t offset = (len / sizeof(*base)) / 2; 58 59 base = kmalloc(len, GFP_KERNEL); 60 if (!base) { 61 pr_info("Unable to allocate base memory.\n"); 62 return; 63 } 64 65 val = kmalloc(len, GFP_KERNEL); 66 if (!val) { 67 pr_info("Unable to allocate val memory.\n"); 68 kfree(base); 69 return; 70 } 71 72 *val = 0x12345678; 73 base[offset] = *val; 74 pr_info("Value in memory before free: %x\n", base[offset]); 75 76 kfree(base); 77 78 pr_info("Attempting bad read from freed memory\n"); 79 saw = base[offset]; 80 if (saw != *val) { 81 /* Good! Poisoning happened, so declare a win. */ 82 pr_info("Memory correctly poisoned (%x)\n", saw); 83 BUG(); 84 } 85 pr_info("Memory was not poisoned\n"); 86 87 kfree(val); 88} 89 90void lkdtm_WRITE_BUDDY_AFTER_FREE(void) 91{ 92 unsigned long p = __get_free_page(GFP_KERNEL); 93 if (!p) { 94 pr_info("Unable to allocate free page\n"); 95 return; 96 } 97 98 pr_info("Writing to the buddy page before free\n"); 99 memset((void *)p, 0x3, PAGE_SIZE); 100 free_page(p); 101 schedule(); 102 pr_info("Attempting bad write to the buddy page after free\n"); 103 memset((void *)p, 0x78, PAGE_SIZE); 104 /* Attempt to notice the overwrite. */ 105 p = __get_free_page(GFP_KERNEL); 106 free_page(p); 107 schedule(); 108} 109 110void lkdtm_READ_BUDDY_AFTER_FREE(void) 111{ 112 unsigned long p = __get_free_page(GFP_KERNEL); 113 int saw, *val; 114 int *base; 115 116 if (!p) { 117 pr_info("Unable to allocate free page\n"); 118 return; 119 } 120 121 val = kmalloc(1024, GFP_KERNEL); 122 if (!val) { 123 pr_info("Unable to allocate val memory.\n"); 124 free_page(p); 125 return; 126 } 127 128 base = (int *)p; 129 130 *val = 0x12345678; 131 base[0] = *val; 132 pr_info("Value in memory before free: %x\n", base[0]); 133 free_page(p); 134 pr_info("Attempting to read from freed memory\n"); 135 saw = base[0]; 136 if (saw != *val) { 137 /* Good! Poisoning happened, so declare a win. */ 138 pr_info("Memory correctly poisoned (%x)\n", saw); 139 BUG(); 140 } 141 pr_info("Buddy page was not poisoned\n"); 142 143 kfree(val); 144}