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