From patchwork Thu Feb 2 12:50:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: kpark3469@gmail.com X-Patchwork-Id: 9551753 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 4C4C060236 for ; Thu, 2 Feb 2017 12:51:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 36FE028329 for ; Thu, 2 Feb 2017 12:51:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2BC0B2838D; Thu, 2 Feb 2017 12:51:06 +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.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID 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 274A128329 for ; Thu, 2 Feb 2017 12:51:04 +0000 (UTC) Received: (qmail 15447 invoked by uid 550); 2 Feb 2017 12:51:03 -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: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 15368 invoked from network); 2 Feb 2017 12:51:02 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Pvcr2ico4GqMzoMYIs0ncvMbeHX4Pmtjq4kJgpQL8Y8=; b=CEkHYUpIXs+OCeKK9TM34jWXCfv20W8gaHlVVnRf43+8EgNasExmKCKaWA+V+SvXK6 WKBTVHY+mpzMrKIaMIgRPeyQhz4xEVbP3Gz0XTrAC2UvVuYbx/y82uUnZ/T+R9FeikSs d/+fqM21+yGsnq9IDmFUPHdGMu+DvW5fkz++0sS9CsABRJa+fE/Ftjep5ukj0e5lqZr8 HRvOBP+qOJ1M43V0KH571fEmWdFo3Q9TGqsEK5D9QrXxdqmikNRU6oEKGnHh+sTa6GLD sPs9TibP1KNh9wDrrAnCRFaUzdlKioa5ZIG3Fp5YXU58bbv/qRkiH7kIR0takeWAw2+O 6+NA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Pvcr2ico4GqMzoMYIs0ncvMbeHX4Pmtjq4kJgpQL8Y8=; b=iruseso/gXEdwGAL7ug+lFasG4ePHjhR8KPV7xEUWjhSf4p9fsR588+T2L+B/t+NLp QTw6Ld4imbNzoq9SnIER0ZsQRGRPtaGShhA1uLbXpbJkBDqT8s8zEm/BuioXDA9/9Y3I ESX8ewFFbnss6in0mkqnqp5/Pv9ASLdXsHfm5WL3lfx5mhx3qs+/kUuUlJ9xK+gJQE8z a89CRQ3Zek/35xkaY+6ZBfZfUeEx/NtAi1tO4Mg7DOFYeYwWXFXPpPE5ns1ItmPOSbYw R3E7LciPZKegoS/O7Kik8BtdngPcZLM4kkgHedgUaTsHqUo7zv219GzEPSoSSS8DPopr t/ow== X-Gm-Message-State: AIkVDXLbIw0IGZpP1TUs7W9sZqJI5hRuTlXoH4PMK0HfA3uGBGlo5wXIPpdMj4BOrXUXaQ== X-Received: by 10.223.134.15 with SMTP id 15mr8691326wrv.102.1486039851135; Thu, 02 Feb 2017 04:50:51 -0800 (PST) From: kpark3469@gmail.com To: kernel-hardening@lists.openwall.com Cc: catalin.marinas@arm.com, keescook@chromium.org, will.deacon@arm.com, mark.rutland@arm.com, james.morse@arm.com, panand@redhat.com, keun-o.park@darkmatter.ae Date: Thu, 2 Feb 2017 16:50:24 +0400 Message-Id: <1486039824-8470-3-git-send-email-kpark3469@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1486039824-8470-2-git-send-email-kpark3469@gmail.com> References: <1486039824-8470-1-git-send-email-kpark3469@gmail.com> <1486039824-8470-2-git-send-email-kpark3469@gmail.com> Subject: [kernel-hardening] [PATCH v2 3/3] lkdtm: add tests for dynamic array in local stack X-Virus-Scanned: ClamAV using ClamSMTP From: Sahara This seems an unusual case in kernel. But, when an array is dynamically created, this variable can be placed ahead of current frame pointer. This patch tests this dynamic array case. Signed-off-by: Sahara Reported-by: AKASHI Takahiro Suggested-by: Kees Cook --- drivers/misc/lkdtm_usercopy.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/misc/lkdtm_usercopy.c b/drivers/misc/lkdtm_usercopy.c index 1dd6114..898a323 100644 --- a/drivers/misc/lkdtm_usercopy.c +++ b/drivers/misc/lkdtm_usercopy.c @@ -7,6 +7,7 @@ #include #include #include +#include #include /* @@ -33,7 +34,14 @@ static noinline unsigned char *trick_compiler(unsigned char *stack) static noinline unsigned char *do_usercopy_stack_callee(int value) { - unsigned char buf[32]; + /* + * buf[128] is big enough to put it in the position ahead of + * check_stack_object()'s frame pointer. Because dynamically allocated + * array can be placed between check_stack_object()'s frame pointer and + * do_usercopy_stack()'s frame pointer, we need an object which exists + * ahead of check_stack_object()'s frame pointer. + */ + unsigned char buf[128]; int i; /* Exercise stack to avoid everything living in registers. */ @@ -49,6 +57,7 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame) unsigned long user_addr; unsigned char good_stack[32]; unsigned char *bad_stack; + unsigned int array_size; int i; /* Exercise stack to avoid everything living in registers. */ @@ -72,7 +81,9 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame) return; } + array_size = get_random_int() & 0x0f; if (to_user) { + unsigned char array[array_size]; pr_info("attempting good copy_to_user of local stack\n"); if (copy_to_user((void __user *)user_addr, good_stack, unconst + sizeof(good_stack))) { @@ -80,6 +91,13 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame) goto free_user; } + pr_info("attempting good copy_to_user of callee stack\n"); + if (copy_to_user((void __user *)user_addr, array, + unconst + sizeof(array))) { + pr_warn("copy_to_user failed unexpectedly?!\n"); + goto free_user; + } + pr_info("attempting bad copy_to_user of distant stack\n"); if (copy_to_user((void __user *)user_addr, bad_stack, unconst + sizeof(good_stack))) { @@ -87,6 +105,7 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame) goto free_user; } } else { + unsigned char array[array_size]; /* * There isn't a safe way to not be protected by usercopy * if we're going to write to another thread's stack. @@ -101,6 +120,13 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame) goto free_user; } + pr_info("attempting good copy_from_user of callee stack\n"); + if (copy_from_user(array, (void __user *)user_addr, + unconst + sizeof(array))) { + pr_warn("copy_from_user failed unexpectedly?!\n"); + goto free_user; + } + pr_info("attempting bad copy_from_user of distant stack\n"); if (copy_from_user(bad_stack, (void __user *)user_addr, unconst + sizeof(good_stack))) {