]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
lkdtm: Convert to refcount_t testing
authorKees Cook <keescook@chromium.org>
Fri, 3 Feb 2017 23:26:50 +0000 (15:26 -0800)
committerIngo Molnar <mingo@kernel.org>
Fri, 10 Feb 2017 08:04:20 +0000 (09:04 +0100)
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>
drivers/misc/lkdtm.h
drivers/misc/lkdtm_bugs.c
drivers/misc/lkdtm_core.c

index cfa1039c62e725289cfe74aebb7a36de92b22eb2..67d27be60405489580e7d794ae4263984301e98a 100644 (file)
@@ -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);
 
index 91edd0b55e5ce99e955708d7c5425515fd7740bd..cba0837aee2ed1a2b12d2b2a1802b25b769aaba1 100644 (file)
@@ -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)
index 7eeb71a755499f94cb576902200472145c331e25..16e4cf1109306e954455539324adf4c12ddfd110 100644 (file)
@@ -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),