Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4a2524d authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "lkdtm/heap: Avoid edge and middle of slabs"

parents 346ce0bb af7a794f
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -97,9 +97,8 @@ noinline void lkdtm_CORRUPT_STACK(void)
	/* Use default char array length that triggers stack protection. */
	char data[8] __aligned(sizeof(void *));

	__lkdtm_CORRUPT_STACK(&data);

	pr_info("Corrupted stack containing char array ...\n");
	pr_info("Corrupting stack containing char array ...\n");
	__lkdtm_CORRUPT_STACK((void *)&data);
}

/* Same as above but will only get a canary with -fstack-protector-strong */
@@ -110,9 +109,8 @@ noinline void lkdtm_CORRUPT_STACK_STRONG(void)
		unsigned long *ptr;
	} data __aligned(sizeof(void *));

	__lkdtm_CORRUPT_STACK(&data);

	pr_info("Corrupted stack containing union ...\n");
	pr_info("Corrupting stack containing union ...\n");
	__lkdtm_CORRUPT_STACK((void *)&data);
}

void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void)
+5 −4
Original line number Diff line number Diff line
@@ -54,11 +54,12 @@ void lkdtm_READ_AFTER_FREE(void)
	int *base, *val, saw;
	size_t len = 1024;
	/*
	 * The slub allocator uses the first word to store the free
	 * pointer in some configurations. Use the middle of the
	 * allocation to avoid running into the freelist
	 * The slub allocator will use the either the first word or
	 * the middle of the allocation to store the free pointer,
	 * depending on configurations. Store in the second word to
	 * avoid running into the freelist.
	 */
	size_t offset = (len / sizeof(*base)) / 2;
	size_t offset = sizeof(*base);

	base = kmalloc(len, GFP_KERNEL);
	if (!base) {
+15 −7
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ static noinline void execute_location(void *dst, bool write)
	}
	pr_info("attempting bad execution at %px\n", func);
	func();
	pr_err("FAIL: func returned\n");
}

static void execute_user_location(void *dst)
@@ -75,20 +76,22 @@ static void execute_user_location(void *dst)
		return;
	pr_info("attempting bad execution at %px\n", func);
	func();
	pr_err("FAIL: func returned\n");
}

void lkdtm_WRITE_RO(void)
{
	/* Explicitly cast away "const" for the test. */
	unsigned long *ptr = (unsigned long *)&rodata;
	/* Explicitly cast away "const" for the test and make volatile. */
	volatile unsigned long *ptr = (unsigned long *)&rodata;

	pr_info("attempting bad rodata write at %px\n", ptr);
	*ptr ^= 0xabcd1234;
	pr_err("FAIL: survived bad write\n");
}

void lkdtm_WRITE_RO_AFTER_INIT(void)
{
	unsigned long *ptr = &ro_after_init;
	volatile unsigned long *ptr = &ro_after_init;

	/*
	 * Verify we were written to during init. Since an Oops
@@ -102,12 +105,13 @@ void lkdtm_WRITE_RO_AFTER_INIT(void)

	pr_info("attempting bad ro_after_init write at %px\n", ptr);
	*ptr ^= 0xabcd1234;
	pr_err("FAIL: survived bad write\n");
}

void lkdtm_WRITE_KERN(void)
{
	size_t size;
	unsigned char *ptr;
	volatile unsigned char *ptr;

	if ((unsigned long)do_overwritten < (unsigned long)do_nothing)
		size = (unsigned long)do_nothing -
@@ -118,8 +122,9 @@ void lkdtm_WRITE_KERN(void)
	ptr = (unsigned char *)do_overwritten;

	pr_info("attempting bad %zu byte write at %px\n", size, ptr);
	memcpy(ptr, (unsigned char *)do_nothing, size);
	memcpy((void *)ptr, (unsigned char *)do_nothing, size);
	flush_icache_range((unsigned long)ptr, (unsigned long)(ptr + size));
	pr_err("FAIL: survived bad write\n");

	do_overwritten();
}
@@ -198,9 +203,11 @@ void lkdtm_ACCESS_USERSPACE(void)
	pr_info("attempting bad read at %px\n", ptr);
	tmp = *ptr;
	tmp += 0xc0dec0de;
	pr_err("FAIL: survived bad read\n");

	pr_info("attempting bad write at %px\n", ptr);
	*ptr = tmp;
	pr_err("FAIL: survived bad write\n");

	vm_munmap(user_addr, PAGE_SIZE);
}
@@ -208,19 +215,20 @@ void lkdtm_ACCESS_USERSPACE(void)
void lkdtm_ACCESS_NULL(void)
{
	unsigned long tmp;
	unsigned long *ptr = (unsigned long *)NULL;
	volatile unsigned long *ptr = (unsigned long *)NULL;

	pr_info("attempting bad read at %px\n", ptr);
	tmp = *ptr;
	tmp += 0xc0dec0de;
	pr_err("FAIL: survived bad read\n");

	pr_info("attempting bad write at %px\n", ptr);
	*ptr = tmp;
	pr_err("FAIL: survived bad write\n");
}

void __init lkdtm_perms_init(void)
{
	/* Make sure we can write to __ro_after_init values during __init */
	ro_after_init |= 0xAA;

}
+5 −2
Original line number Diff line number Diff line
@@ -304,19 +304,22 @@ void lkdtm_USERCOPY_KERNEL(void)
		return;
	}

	pr_info("attempting good copy_to_user from kernel rodata\n");
	pr_info("attempting good copy_to_user from kernel rodata: %px\n",
		test_text);
	if (copy_to_user((void __user *)user_addr, test_text,
			 unconst + sizeof(test_text))) {
		pr_warn("copy_to_user failed unexpectedly?!\n");
		goto free_user;
	}

	pr_info("attempting bad copy_to_user from kernel text\n");
	pr_info("attempting bad copy_to_user from kernel text: %px\n",
		vm_mmap);
	if (copy_to_user((void __user *)user_addr, vm_mmap,
			 unconst + PAGE_SIZE)) {
		pr_warn("copy_to_user failed, but lacked Oops\n");
		goto free_user;
	}
	pr_err("FAIL: survived bad copy_to_user()\n");

free_user:
	vm_munmap(user_addr, PAGE_SIZE);