Linux Audio

Check our new training course

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