From patchwork Mon Oct 3 06:41:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Reshetova, Elena" X-Patchwork-Id: 9360073 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2CFAD607D8 for ; Mon, 3 Oct 2016 06:43:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E8702886C for ; Mon, 3 Oct 2016 06:43:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 131B3288D5; Mon, 3 Oct 2016 06:43:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id BD5972886C for ; Mon, 3 Oct 2016 06:43:49 +0000 (UTC) Received: (qmail 23690 invoked by uid 550); 3 Oct 2016 06:42:36 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: kernel-hardening@lists.openwall.com Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 22434 invoked from network); 3 Oct 2016 06:42:30 -0000 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,288,1473145200"; d="scan'208";a="1048760080" From: Elena Reshetova To: kernel-hardening@lists.openwall.com Cc: keescook@chromium.org, Hans Liljestrand , Elena Reshetova , David Windsor Date: Mon, 3 Oct 2016 09:41:26 +0300 Message-Id: <1475476886-26232-14-git-send-email-elena.reshetova@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1475476886-26232-1-git-send-email-elena.reshetova@intel.com> References: <1475476886-26232-1-git-send-email-elena.reshetova@intel.com> Subject: [kernel-hardening] [RFC PATCH 13/13] lkdtm: add tests for atomic over-/underflow X-Virus-Scanned: ClamAV using ClamSMTP From: Hans Liljestrand This adds additional tests for modified atomic functions. Signed-off-by: Hans Liljestrand Signed-off-by: Elena Reshetova Signed-off-by: David Windsor --- drivers/misc/lkdtm.h | 17 ++++ drivers/misc/lkdtm_bugs.c | 205 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/misc/lkdtm_core.c | 17 ++++ 3 files changed, 239 insertions(+) diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h index cfa1039..224713a 100644 --- a/drivers/misc/lkdtm.h +++ b/drivers/misc/lkdtm.h @@ -20,7 +20,24 @@ void lkdtm_HARDLOCKUP(void); void lkdtm_SPINLOCKUP(void); void lkdtm_HUNG_TASK(void); void lkdtm_ATOMIC_UNDERFLOW(void); +void lkdtm_ATOMIC_DEC_RETURN_UNDERFLOW(void); +void lkdtm_ATOMIC_SUB_UNDERFLOW(void); +void lkdtm_ATOMIC_SUB_RETURN_UNDERFLOW(void); void lkdtm_ATOMIC_OVERFLOW(void); +void lkdtm_ATOMIC_INC_RETURN_OVERFLOW(void); +void lkdtm_ATOMIC_ADD_OVERFLOW(void); +void lkdtm_ATOMIC_ADD_RETURN_OVERFLOW(void); +void lkdtm_ATOMIC_ADD_UNLESS_OVERFLOW(void); +void lkdtm_ATOMIC_INC_AND_TEST_OVERFLOW(void); +void lkdtm_ATOMIC_LONG_UNDERFLOW(void); +void lkdtm_ATOMIC_LONG_DEC_RETURN_UNDERFLOW(void); +void lkdtm_ATOMIC_LONG_SUB_UNDERFLOW(void); +void lkdtm_ATOMIC_LONG_SUB_RETURN_UNDERFLOW(void); +void lkdtm_ATOMIC_LONG_OVERFLOW(void); +void lkdtm_ATOMIC_LONG_INC_RETURN_OVERFLOW(void); +void lkdtm_ATOMIC_LONG_ADD_OVERFLOW(void); +void lkdtm_ATOMIC_LONG_ADD_RETURN_OVERFLOW(void); +void lkdtm_ATOMIC_LONG_SUB_AND_TEST(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 f336206..f6a09c6 100644 --- a/drivers/misc/lkdtm_bugs.c +++ b/drivers/misc/lkdtm_bugs.c @@ -140,6 +140,42 @@ void lkdtm_ATOMIC_UNDERFLOW(void) atomic_dec(&under); } +void lkdtm_ATOMIC_DEC_RETURN_UNDERFLOW(void) +{ + atomic_t under = ATOMIC_INIT(INT_MIN); + + pr_info("attempting good atomic_dec_return\n"); + atomic_inc(&under); + atomic_dec_return(&under); + + pr_info("attempting bad atomic_dec_return\n"); + atomic_dec_return(&under); +} + +void lkdtm_ATOMIC_SUB_UNDERFLOW(void) { + atomic_t under = ATOMIC_INIT(INT_MIN); + + pr_info("attempting good atomic subtract\n"); + atomic_add(10, &under); + atomic_sub(10, &under); + + pr_info("attempting bad atomic subtract underflow\n"); + atomic_sub(10, &under); +} + +void lkdtm_ATOMIC_SUB_RETURN_UNDERFLOW(void) +{ + atomic_t under = ATOMIC_INIT(INT_MIN); + + pr_info("attempting good atomic_sub_return\n"); + atomic_add(10, &under); + atomic_sub_return(10, &under); + + pr_info("attempting bad atomic_sub_return underflow\n"); + atomic_sub_return(10, &under); + +} + void lkdtm_ATOMIC_OVERFLOW(void) { atomic_t over = ATOMIC_INIT(INT_MAX); @@ -214,3 +250,172 @@ void lkdtm_CORRUPT_LIST_DEL(void) else pr_err("list_del() corruption not detected!\n"); } + +void lkdtm_ATOMIC_INC_RETURN_OVERFLOW(void) +{ + atomic_t over = ATOMIC_INIT(INT_MAX); + + pr_info("attempting good atomic_inc_return\n"); + atomic_dec(&over); + atomic_inc_return(&over); + + pr_info("attempting bad atomic_inc_return overflow\n"); + atomic_inc_return(&over); +} + +void lkdtm_ATOMIC_ADD_OVERFLOW(void) { + atomic_t over = ATOMIC_INIT(INT_MAX); + + pr_info("attempting good atomic add\n"); + atomic_sub(10, &over); + atomic_add(10, &over); + + pr_info("attempting bad atomic add overflow\n"); + atomic_add(10, &over); +} + +void lkdtm_ATOMIC_ADD_RETURN_OVERFLOW(void) +{ + atomic_t over = ATOMIC_INIT(INT_MAX); + + pr_info("attempting good atomic_add_return\n"); + atomic_sub(10, &over); + atomic_add_return(10, &over); + + pr_info("attempting bad atomic_add_return overflow\n"); + atomic_add_return(10, &over); +} + +void lkdtm_ATOMIC_ADD_UNLESS_OVERFLOW(void) +{ + atomic_t over = ATOMIC_INIT(INT_MAX); + + pr_info("attempting good atomic_add_unless\n"); + atomic_sub(10, &over); + atomic_add_unless(&over, 10, 0); + + pr_info("attempting bad atomic_add_unless overflow\n"); + atomic_add_unless(&over, 10, 0); +} + +void lkdtm_ATOMIC_INC_AND_TEST_OVERFLOW(void) +{ + atomic_t over = ATOMIC_INIT(INT_MAX); + + pr_info("attempting good atomic_inc_and_test\n"); + atomic_dec(&over); + atomic_inc_and_test(&over); + + pr_info("attempting bad atomic_inc_and_test overflow\n"); + atomic_inc_and_test(&over); +} + +void lkdtm_ATOMIC_LONG_UNDERFLOW(void) +{ + atomic_long_t under = ATOMIC_LONG_INIT(LONG_MIN); + + pr_info("attempting good atomic_long_dec\n"); + atomic_long_inc(&under); + atomic_long_dec(&under); + + pr_info("attempting bad atomic_long_dec underflow\n"); + atomic_long_dec(&under); +} + +void lkdtm_ATOMIC_LONG_DEC_RETURN_UNDERFLOW(void) +{ + atomic_long_t under = ATOMIC_LONG_INIT(LONG_MIN); + + pr_info("attempting good atomic_long_dec_return\n"); + atomic_long_inc(&under); + atomic_long_dec_return(&under); + + pr_info("attempting bad atomic_long_dec_return underflow\n"); + atomic_long_dec_return(&under); +} + +void lkdtm_ATOMIC_LONG_SUB_UNDERFLOW(void) +{ + atomic_long_t under = ATOMIC_INIT(LONG_MIN); + + pr_info("attempting good atomic_long_sub\n"); + atomic_long_add(10, &under); + atomic_long_sub(10, &under); + + pr_info("attempting bad atomic_long_sub underflow\n"); + atomic_long_sub(10, &under); + +} + +void lkdtm_ATOMIC_LONG_SUB_RETURN_UNDERFLOW(void) +{ + atomic_long_t under = ATOMIC_INIT(LONG_MIN); + + pr_info("attempting good atomic_long_sub_return \n"); + atomic_long_add(10, &under); + atomic_long_sub_return(10, &under); + + pr_info("attempting bad atomic_long_sub_return underflow\n"); + atomic_long_sub_return(10, &under); + +} + +void lkdtm_ATOMIC_LONG_OVERFLOW(void) +{ + atomic_long_t over = ATOMIC_LONG_INIT(LONG_MAX); + + pr_info("attempting good atomic_long_inc\n"); + atomic_long_dec(&over); + atomic_long_inc(&over); + + pr_info("attempting bad atomic_long_inc overflow\n"); + atomic_long_inc(&over); +} + +void lkdtm_ATOMIC_LONG_INC_RETURN_OVERFLOW(void) +{ + atomic_long_t over = ATOMIC_LONG_INIT(LONG_MAX); + + pr_info("attempting good atomic_ong_inc_return\n"); + atomic_long_dec(&over); + atomic_long_inc_return(&over); + + pr_info("attempting bad atomic_long_inc_return overflow\n"); + atomic_long_inc_return(&over); +} + +void lkdtm_ATOMIC_LONG_ADD_OVERFLOW(void) +{ + atomic_long_t over = ATOMIC_LONG_INIT(LONG_MAX); + + pr_info("attempting good atomic_long_add\n"); + atomic_long_sub(10, &over); + atomic_long_add(10, &over); + + pr_info("attempting bad atomic_long_add overflow\n"); + atomic_long_add(10, &over); +} + +void lkdtm_ATOMIC_LONG_ADD_RETURN_OVERFLOW(void) +{ + atomic_long_t over = ATOMIC_LONG_INIT(LONG_MAX); + + pr_info("attempting good atomic_long_add_return\n"); + atomic_long_sub(10, &over); + atomic_long_add_return(10, &over); + + pr_info("attempting bad atomic_long_add_return overflow\n"); + atomic_long_add_return(10, &over); +} + +void lkdtm_ATOMIC_LONG_SUB_AND_TEST(void) +{ + atomic_long_t over = ATOMIC_LONG_INIT(LONG_MIN); + + pr_info("attempting good atomic_long_sub_and_test\n"); + atomic_long_add(10, &over); + atomic_long_sub_and_test(10, &over); + + pr_info("attempting bad atomic_long_sub_and_test overflow\n"); + atomic_long_sub_and_test(10, &over); +} diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index 7eeb71a..4b05803 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c @@ -221,7 +221,24 @@ struct crashtype crashtypes[] = { CRASHTYPE(WRITE_RO_AFTER_INIT), CRASHTYPE(WRITE_KERN), CRASHTYPE(ATOMIC_UNDERFLOW), + CRASHTYPE(ATOMIC_DEC_RETURN_UNDERFLOW), + CRASHTYPE(ATOMIC_SUB_UNDERFLOW), + CRASHTYPE(ATOMIC_SUB_RETURN_UNDERFLOW), CRASHTYPE(ATOMIC_OVERFLOW), + CRASHTYPE(ATOMIC_INC_RETURN_OVERFLOW), + CRASHTYPE(ATOMIC_ADD_OVERFLOW), + CRASHTYPE(ATOMIC_ADD_RETURN_OVERFLOW), + CRASHTYPE(ATOMIC_ADD_UNLESS_OVERFLOW), + CRASHTYPE(ATOMIC_INC_AND_TEST_OVERFLOW), + CRASHTYPE(ATOMIC_LONG_UNDERFLOW), + CRASHTYPE(ATOMIC_LONG_DEC_RETURN_UNDERFLOW), + CRASHTYPE(ATOMIC_LONG_SUB_UNDERFLOW), + CRASHTYPE(ATOMIC_LONG_SUB_RETURN_UNDERFLOW), + CRASHTYPE(ATOMIC_LONG_OVERFLOW), + CRASHTYPE(ATOMIC_LONG_INC_RETURN_OVERFLOW), + CRASHTYPE(ATOMIC_LONG_ADD_OVERFLOW), + CRASHTYPE(ATOMIC_LONG_ADD_RETURN_OVERFLOW), + CRASHTYPE(ATOMIC_LONG_SUB_AND_TEST), CRASHTYPE(USERCOPY_HEAP_SIZE_TO), CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), CRASHTYPE(USERCOPY_HEAP_FLAG_TO),