diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-05 11:08:17 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-05 11:08:17 -0700 |
commit | bafb0762cb6a906eb4105cccfb3bcd90be7f40d2 (patch) | |
tree | 14ecb87c33bcf909e5b95c27cd694ded4ac1478c /drivers/misc/lkdtm_bugs.c | |
parent | 44b1671fae88ce95b8c7b53acbc6ba71ca67db00 (diff) | |
parent | 3a6430ce462172caac7c73f4afd550ab0f105737 (diff) |
Merge tag 'char-misc-4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH:
"Here is the big char/misc driver update for 4.14-rc1.
Lots of different stuff in here, it's been an active development cycle
for some reason. Highlights are:
- updated binder driver, this brings binder up to date with what
shipped in the Android O release, plus some more changes that
happened since then that are in the Android development trees.
- coresight updates and fixes
- mux driver file renames to be a bit "nicer"
- intel_th driver updates
- normal set of hyper-v updates and changes
- small fpga subsystem and driver updates
- lots of const code changes all over the driver trees
- extcon driver updates
- fmc driver subsystem upadates
- w1 subsystem minor reworks and new features and drivers added
- spmi driver updates
Plus a smattering of other minor driver updates and fixes.
All of these have been in linux-next with no reported issues for a
while"
* tag 'char-misc-4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (244 commits)
ANDROID: binder: don't queue async transactions to thread.
ANDROID: binder: don't enqueue death notifications to thread todo.
ANDROID: binder: Don't BUG_ON(!spin_is_locked()).
ANDROID: binder: Add BINDER_GET_NODE_DEBUG_INFO ioctl
ANDROID: binder: push new transactions to waiting threads.
ANDROID: binder: remove proc waitqueue
android: binder: Add page usage in binder stats
android: binder: fixup crash introduced by moving buffer hdr
drivers: w1: add hwmon temp support for w1_therm
drivers: w1: refactor w1_slave_show to make the temp reading functionality separate
drivers: w1: add hwmon support structures
eeprom: idt_89hpesx: Support both ACPI and OF probing
mcb: Fix an error handling path in 'chameleon_parse_cells()'
MCB: add support for SC31 to mcb-lpc
mux: make device_type const
char: virtio: constify attribute_group structures.
Documentation/ABI: document the nvmem sysfs files
lkdtm: fix spelling mistake: "incremeted" -> "incremented"
perf: cs-etm: Fix ETMv4 CONFIGR entry in perf.data file
nvmem: include linux/err.h from header
...
Diffstat (limited to 'drivers/misc/lkdtm_bugs.c')
-rw-r--r-- | drivers/misc/lkdtm_bugs.c | 134 |
1 files changed, 48 insertions, 86 deletions
diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c index d9028ef50fbe..9e0b4f959987 100644 --- a/drivers/misc/lkdtm_bugs.c +++ b/drivers/misc/lkdtm_bugs.c @@ -6,9 +6,9 @@ */ #include "lkdtm.h" #include <linux/list.h> -#include <linux/refcount.h> #include <linux/sched.h> #include <linux/sched/signal.h> +#include <linux/sched/task_stack.h> #include <linux/uaccess.h> struct lkdtm_list { @@ -85,16 +85,31 @@ void lkdtm_OVERFLOW(void) static noinline void __lkdtm_CORRUPT_STACK(void *stack) { - memset(stack, 'a', 64); + memset(stack, '\xff', 64); } +/* This should trip the stack canary, not corrupt the return address. */ noinline void lkdtm_CORRUPT_STACK(void) { /* Use default char array length that triggers stack protection. */ - char data[8]; + char data[8] __aligned(sizeof(void *)); + + __lkdtm_CORRUPT_STACK(&data); + + pr_info("Corrupted stack containing char array ...\n"); +} + +/* Same as above but will only get a canary with -fstack-protector-strong */ +noinline void lkdtm_CORRUPT_STACK_STRONG(void) +{ + union { + unsigned short shorts[4]; + unsigned long *ptr; + } data __aligned(sizeof(void *)); + __lkdtm_CORRUPT_STACK(&data); - pr_info("Corrupted stack with '%16s'...\n", data); + pr_info("Corrupted stack containing union ...\n"); } void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void) @@ -137,88 +152,6 @@ void lkdtm_HUNG_TASK(void) schedule(); } -void lkdtm_REFCOUNT_SATURATE_INC(void) -{ - refcount_t over = REFCOUNT_INIT(UINT_MAX - 1); - - pr_info("attempting good refcount decrement\n"); - refcount_dec(&over); - refcount_inc(&over); - - pr_info("attempting bad refcount inc overflow\n"); - refcount_inc(&over); - refcount_inc(&over); - if (refcount_read(&over) == UINT_MAX) - pr_err("Correctly stayed saturated, but no BUG?!\n"); - else - pr_err("Fail: refcount wrapped\n"); -} - -void lkdtm_REFCOUNT_SATURATE_ADD(void) -{ - refcount_t over = REFCOUNT_INIT(UINT_MAX - 1); - - pr_info("attempting good refcount decrement\n"); - refcount_dec(&over); - refcount_inc(&over); - - pr_info("attempting bad refcount add overflow\n"); - refcount_add(2, &over); - if (refcount_read(&over) == UINT_MAX) - pr_err("Correctly stayed saturated, but no BUG?!\n"); - else - pr_err("Fail: refcount wrapped\n"); -} - -void lkdtm_REFCOUNT_ZERO_DEC(void) -{ - refcount_t zero = REFCOUNT_INIT(1); - - pr_info("attempting bad refcount decrement to zero\n"); - refcount_dec(&zero); - if (refcount_read(&zero) == 0) - pr_err("Stayed at zero, but no BUG?!\n"); - else - pr_err("Fail: refcount went crazy\n"); -} - -void lkdtm_REFCOUNT_ZERO_SUB(void) -{ - refcount_t zero = REFCOUNT_INIT(1); - - pr_info("attempting bad refcount subtract past zero\n"); - if (!refcount_sub_and_test(2, &zero)) - pr_info("wrap attempt was noticed\n"); - if (refcount_read(&zero) == 1) - pr_err("Correctly stayed above 0, but no BUG?!\n"); - else - pr_err("Fail: refcount wrapped\n"); -} - -void lkdtm_REFCOUNT_ZERO_INC(void) -{ - refcount_t zero = REFCOUNT_INIT(0); - - pr_info("attempting bad refcount increment from zero\n"); - refcount_inc(&zero); - if (refcount_read(&zero) == 0) - pr_err("Stayed at zero, but no BUG?!\n"); - else - pr_err("Fail: refcount went past zero\n"); -} - -void lkdtm_REFCOUNT_ZERO_ADD(void) -{ - refcount_t zero = REFCOUNT_INIT(0); - - pr_info("attempting bad refcount addition from zero\n"); - refcount_add(2, &zero); - if (refcount_read(&zero) == 0) - pr_err("Stayed at zero, but no BUG?!\n"); - else - pr_err("Fail: refcount went past zero\n"); -} - void lkdtm_CORRUPT_LIST_ADD(void) { /* @@ -282,6 +215,7 @@ void lkdtm_CORRUPT_LIST_DEL(void) pr_err("list_del() corruption not detected!\n"); } +/* Test if unbalanced set_fs(KERNEL_DS)/set_fs(USER_DS) check exists. */ void lkdtm_CORRUPT_USER_DS(void) { pr_info("setting bad task size limit\n"); @@ -290,3 +224,31 @@ void lkdtm_CORRUPT_USER_DS(void) /* Make sure we do not keep running with a KERNEL_DS! */ force_sig(SIGKILL, current); } + +/* Test that VMAP_STACK is actually allocating with a leading guard page */ +void lkdtm_STACK_GUARD_PAGE_LEADING(void) +{ + const unsigned char *stack = task_stack_page(current); + const unsigned char *ptr = stack - 1; + volatile unsigned char byte; + + pr_info("attempting bad read from page below current stack\n"); + + byte = *ptr; + + pr_err("FAIL: accessed page before stack!\n"); +} + +/* Test that VMAP_STACK is actually allocating with a trailing guard page */ +void lkdtm_STACK_GUARD_PAGE_TRAILING(void) +{ + const unsigned char *stack = task_stack_page(current); + const unsigned char *ptr = stack + THREAD_SIZE; + volatile unsigned char byte; + + pr_info("attempting bad read from page above current stack\n"); + + byte = *ptr; + + pr_err("FAIL: accessed page after stack!\n"); +} |