diff options
author | Kees Cook <keescook@chromium.org> | 2017-02-04 02:26:50 +0300 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-02-10 11:04:20 +0300 |
commit | ff86b30010eee8249dc244ce1868b886bbee6449 (patch) | |
tree | dcfe7ed064e89cdc61c5e61391c4639cdd3bf964 /drivers/misc | |
parent | 10383aea2f445bce9b2a2b308def08134b438c8e (diff) | |
download | linux-ff86b30010eee8249dc244ce1868b886bbee6449.tar.xz |
lkdtm: Convert to refcount_t testing
Since we'll be using refcount_t instead of atomic_t for refcounting,
change the LKDTM tests to reflect the new interface and test conditions.
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Hans Liljestrand <ishkamiel@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: arnd@arndb.de
Cc: dhowells@redhat.com
Cc: dwindsor@gmail.com
Cc: elena.reshetova@intel.com
Cc: gregkh@linuxfoundation.org
Cc: h.peter.anvin@intel.com
Cc: kernel-hardening@lists.openwall.com
Cc: will.deacon@arm.com
Link: http://lkml.kernel.org/r/1486164412-7338-3-git-send-email-keescook@chromium.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/lkdtm.h | 8 | ||||
-rw-r--r-- | drivers/misc/lkdtm_bugs.c | 87 | ||||
-rw-r--r-- | drivers/misc/lkdtm_core.c | 8 |
3 files changed, 85 insertions, 18 deletions
diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h index cfa1039c62e7..67d27be60405 100644 --- a/drivers/misc/lkdtm.h +++ b/drivers/misc/lkdtm.h @@ -19,8 +19,12 @@ void lkdtm_SOFTLOCKUP(void); void lkdtm_HARDLOCKUP(void); void lkdtm_SPINLOCKUP(void); void lkdtm_HUNG_TASK(void); -void lkdtm_ATOMIC_UNDERFLOW(void); -void lkdtm_ATOMIC_OVERFLOW(void); +void lkdtm_REFCOUNT_SATURATE_INC(void); +void lkdtm_REFCOUNT_SATURATE_ADD(void); +void lkdtm_REFCOUNT_ZERO_DEC(void); +void lkdtm_REFCOUNT_ZERO_INC(void); +void lkdtm_REFCOUNT_ZERO_SUB(void); +void lkdtm_REFCOUNT_ZERO_ADD(void); void lkdtm_CORRUPT_LIST_ADD(void); void lkdtm_CORRUPT_LIST_DEL(void); diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c index 91edd0b55e5c..cba0837aee2e 100644 --- a/drivers/misc/lkdtm_bugs.c +++ b/drivers/misc/lkdtm_bugs.c @@ -6,6 +6,7 @@ */ #include "lkdtm.h" #include <linux/list.h> +#include <linux/refcount.h> #include <linux/sched.h> struct lkdtm_list { @@ -129,28 +130,86 @@ void lkdtm_HUNG_TASK(void) schedule(); } -void lkdtm_ATOMIC_UNDERFLOW(void) +void lkdtm_REFCOUNT_SATURATE_INC(void) { - atomic_t under = ATOMIC_INIT(INT_MIN); + refcount_t over = REFCOUNT_INIT(UINT_MAX - 1); - pr_info("attempting good atomic increment\n"); - atomic_inc(&under); - atomic_dec(&under); + pr_info("attempting good refcount decrement\n"); + refcount_dec(&over); + refcount_inc(&over); - pr_info("attempting bad atomic underflow\n"); - atomic_dec(&under); + 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_ATOMIC_OVERFLOW(void) +void lkdtm_REFCOUNT_ZERO_SUB(void) { - atomic_t over = ATOMIC_INIT(INT_MAX); + 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"); +} - pr_info("attempting good atomic decrement\n"); - atomic_dec(&over); - atomic_inc(&over); +void lkdtm_REFCOUNT_ZERO_INC(void) +{ + refcount_t zero = REFCOUNT_INIT(0); - pr_info("attempting bad atomic overflow\n"); - atomic_inc(&over); + 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) diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index 7eeb71a75549..16e4cf110930 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c @@ -220,8 +220,12 @@ struct crashtype crashtypes[] = { CRASHTYPE(WRITE_RO), CRASHTYPE(WRITE_RO_AFTER_INIT), CRASHTYPE(WRITE_KERN), - CRASHTYPE(ATOMIC_UNDERFLOW), - CRASHTYPE(ATOMIC_OVERFLOW), + CRASHTYPE(REFCOUNT_SATURATE_INC), + CRASHTYPE(REFCOUNT_SATURATE_ADD), + CRASHTYPE(REFCOUNT_ZERO_DEC), + CRASHTYPE(REFCOUNT_ZERO_INC), + CRASHTYPE(REFCOUNT_ZERO_SUB), + CRASHTYPE(REFCOUNT_ZERO_ADD), CRASHTYPE(USERCOPY_HEAP_SIZE_TO), CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), CRASHTYPE(USERCOPY_HEAP_FLAG_TO), |