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>
This commit is contained in:
parent
10383aea2f
commit
ff86b30010
|
@ -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);
|
||||
|
||||
|
|
|
@ -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_ATOMIC_OVERFLOW(void)
|
||||
void lkdtm_REFCOUNT_SATURATE_ADD(void)
|
||||
{
|
||||
atomic_t over = ATOMIC_INIT(INT_MAX);
|
||||
refcount_t over = REFCOUNT_INIT(UINT_MAX - 1);
|
||||
|
||||
pr_info("attempting good atomic decrement\n");
|
||||
atomic_dec(&over);
|
||||
atomic_inc(&over);
|
||||
pr_info("attempting good refcount decrement\n");
|
||||
refcount_dec(&over);
|
||||
refcount_inc(&over);
|
||||
|
||||
pr_info("attempting bad atomic overflow\n");
|
||||
atomic_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)
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue