Received: by 10.213.65.68 with SMTP id h4csp2530652imn; Mon, 9 Apr 2018 05:09:07 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/RnyoGR9SPq1jNQJJk485nV+RD4VosWJgvtIL4/PZGusoLKIkXaM7h73ZJEv2ax8+vFs2n X-Received: by 10.98.60.146 with SMTP id b18mr29258808pfk.36.1523275747674; Mon, 09 Apr 2018 05:09:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523275747; cv=none; d=google.com; s=arc-20160816; b=SEnqu5k9lHR/NUORZxkZyNDvc/fCBU9i12rS68D8NqAFoLgEdS++2RIbhzTAtBgv3v ZnSFeOMNh+Uw0waP1WClfgDic4/GUawzF0pbiwyyZspk3P1V0PvejzqYlVdxFleUDWXR OplG1UkQtsAMlffge97qqUni5rWW+gL+klT6yyiQlAuocSvWmt7Kt6ceD7y0Mkszn21J /ycsY+a/rkyXoMvvdnCU7/VoacJfKuEse8tEFogcUtp0k4SqiQQ2szfACofinU1cJSw1 TXvIYpnu1nLVy4pVzRjBjjx8Fa3Tx1atm+JNkVErjLojown8cR/df2KU2nUO88CeZdIT k2/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=OO4MCep2Vgr8RC0TiPbOpkksdvxbBTXB+tEq2zvklQA=; b=j+KOblmiDKyq/l3emo4F1k27E+LvamNni8b4bk7AdMksZQUFxD+0TqiuYifRJb9nla BxnPrtvgv4MPnUiwswxKcIx2USPvISGkuryHw799ovuiI9e8+t8TzkJarlJ61txIO7Tu EFs3AydVedF6EAW39ybqNcdebEFYrpmt4Y2pEEGwsbXBqyFufC9WSVxgvPvaKIW9r3AR nVsjboVm+ZWfsBmR1YQZV1xsjzaH/AnvGlskcyhsrds9EWK83nAAsQe22swbmOOdfl6d ihy45pudZn3BFjbKAJf6iZLF0kIxz3dxoH6pjkJG85IKEaGNR2Q/sjcCDM5jcOLWEA4h XvMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=R0+XbIdX; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f31-v6si190876plb.212.2018.04.09.05.08.30; Mon, 09 Apr 2018 05:09:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=R0+XbIdX; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752370AbeDIMDv (ORCPT + 99 others); Mon, 9 Apr 2018 08:03:51 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:39031 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751931AbeDIMDs (ORCPT ); Mon, 9 Apr 2018 08:03:48 -0400 Received: by mail-wm0-f68.google.com with SMTP id f125so16251785wme.4 for ; Mon, 09 Apr 2018 05:03:47 -0700 (PDT) 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=OO4MCep2Vgr8RC0TiPbOpkksdvxbBTXB+tEq2zvklQA=; b=R0+XbIdX2JP0FFllEZ4g3VPN0QSNJxJZ1kXWs4k9LLCQFQLEmG3zVoUwjdqdBPpIN0 eTh+QX3oN4vWc4VpzUPT1GwDgUxE0tc97nP2RJF1IdLZgAZkxHxQexSRjnm+Hr+49Sqj JOAiZY/aBrBckoOaRsgjoLqDP3qhI2UxNjkSaPYo15eIzN4Uzeub/qacWmVXHFDPveHS kmnzF7myBS9LXhD9aTCzZJEG9t/EURnN5E4LfjC0ltqNC51k2MQkong5gTjpuJRhHkXy DN2X2ZxbR+7V/Rf/DanhmoUlSLUuqII9cBPKvBksyJs5AzYmUJ1d+tspfK6gw9NHiiaY 9Rng== 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=OO4MCep2Vgr8RC0TiPbOpkksdvxbBTXB+tEq2zvklQA=; b=dPb7xkf4ANffsEEhG/gHUAswe9bGRiP+V4WxCo+JhVPgxdumJcw5s7uxZ5bO5OVgdN W3hRMDh5nOzj/oYpwfbZmBy58WLResarCab+86WSyWRV2ieFD6ExUreNL0JmIh2F4C0Y DCZQUcwS6nNLvjGXBNiv/sEN0fKUtcWq0oIUmrnbUnL7FxvMzJt2+ldJDU7EYDV3Rr3R Zg3HQI0QtPvtKB5emNFDw3UDIKjjAI2gZ8tB/UxHmcyoAdqA8KskKS+8f4wQqONEwuSF lOvBZ2L4f1wJPAkaf5evywHnV0Ygi0dBOISrPHxFS5AGN4tXBGcb0BYJ2Tb/hHNoShwF MCvA== X-Gm-Message-State: ALQs6tBVb+XUaJFr70kVzk51vWqUMrBr5Wu4ApAE0d714q9Jt9D4rWUA xmBkIZ36yqU2SP0qmKASwrM= X-Received: by 10.28.190.23 with SMTP id o23mr19762207wmf.53.1523275426804; Mon, 09 Apr 2018 05:03:46 -0700 (PDT) Received: from sahara-ad.darkmatter.uae (bba421079.alshamil.net.ae. [83.110.21.201]) by smtp.gmail.com with ESMTPSA id 59sm280435wro.35.2018.04.09.05.03.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Apr 2018 05:03:46 -0700 (PDT) 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, psodagud@codeaurora.org, jpoimboe@redhat.com, mingo@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/3] stacktrace: move arch_within_stack_frames from thread_info.h Date: Mon, 9 Apr 2018 15:59:14 +0400 Message-Id: <1523275156-29087-2-git-send-email-kpark3469@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1523275156-29087-1-git-send-email-kpark3469@gmail.com> References: <1523275156-29087-1-git-send-email-kpark3469@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sahara Since the inlined arch_within_stack_frames function was placed within asm/thread_info.h, using stacktrace functions to unwind stack was restricted. Now in order to have this function use more abundant apis, it is moved to architecture's stacktrace.c. And, it is changed from inline to noinline function to clearly have three depth calls like: do_usercopy_stack() copy_[to|from]_user() : inline check_copy_size() : inline __check_object_size() check_stack_object() arch_within_stack_frames() With this change, the x86's implementation was slightly changed also. Signed-off-by: Sahara Reviewed-by: Kees Cook --- arch/x86/include/asm/thread_info.h | 51 +------------------------------------- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/stacktrace.c | 49 ++++++++++++++++++++++++++++++++++++ include/linux/page_ext.h | 1 - include/linux/stacktrace.h | 24 ++++++++++++++++++ include/linux/thread_info.h | 21 ---------------- mm/usercopy.c | 2 +- 7 files changed, 76 insertions(+), 74 deletions(-) diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index a5d9521..e25d70a 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -156,59 +156,10 @@ struct thread_info { * * preempt_count needs to be 1 initially, until the scheduler is functional. */ -#ifndef __ASSEMBLY__ - -/* - * Walks up the stack frames to make sure that the specified object is - * entirely contained by a single stack frame. - * - * Returns: - * GOOD_FRAME if within a frame - * BAD_STACK if placed across a frame boundary (or outside stack) - * NOT_STACK unable to determine (no frame pointers, etc) - */ -static inline int arch_within_stack_frames(const void * const stack, - const void * const stackend, - const void *obj, unsigned long len) -{ -#if defined(CONFIG_FRAME_POINTER) - const void *frame = NULL; - const void *oldframe; - - oldframe = __builtin_frame_address(1); - if (oldframe) - frame = __builtin_frame_address(2); - /* - * low ----------------------------------------------> high - * [saved bp][saved ip][args][local vars][saved bp][saved ip] - * ^----------------^ - * allow copies only within here - */ - while (stack <= frame && frame < stackend) { - /* - * If obj + len extends past the last frame, this - * check won't pass and the next frame will be 0, - * causing us to bail out and correctly report - * the copy as invalid. - */ - if (obj + len <= frame) - return obj >= oldframe + 2 * sizeof(void *) ? - GOOD_FRAME : BAD_STACK; - oldframe = frame; - frame = *(const void * const *)frame; - } - return BAD_STACK; -#else - return NOT_STACK; -#endif -} - -#else /* !__ASSEMBLY__ */ - +#ifdef __ASSEMBLY__ #ifdef CONFIG_X86_64 # define cpu_current_top_of_stack (cpu_tss_rw + TSS_sp1) #endif - #endif #ifdef CONFIG_COMPAT diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 02d6f5c..3b8afd5 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -70,7 +70,7 @@ obj-$(CONFIG_IA32_EMULATION) += tls.o obj-y += step.o obj-$(CONFIG_INTEL_TXT) += tboot.o obj-$(CONFIG_ISA_DMA_API) += i8237.o -obj-$(CONFIG_STACKTRACE) += stacktrace.o +obj-y += stacktrace.o obj-y += cpu/ obj-y += acpi/ obj-y += reboot.o diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c index 093f2ea..ff178a0 100644 --- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c @@ -12,6 +12,54 @@ #include #include + +/* + * Walks up the stack frames to make sure that the specified object is + * entirely contained by a single stack frame. + * + * Returns: + * GOOD_FRAME if within a frame + * BAD_STACK if placed across a frame boundary (or outside stack) + * NOT_STACK unable to determine (no frame pointers, etc) + */ +int arch_within_stack_frames(const void * const stack, + const void * const stackend, + const void *obj, unsigned long len) +{ +#if defined(CONFIG_FRAME_POINTER) + const void *frame = NULL; + const void *oldframe; + + oldframe = __builtin_frame_address(2); + if (oldframe) + frame = __builtin_frame_address(3); + /* + * low ----------------------------------------------> high + * [saved bp][saved ip][args][local vars][saved bp][saved ip] + * ^----------------^ + * allow copies only within here + */ + while (stack <= frame && frame < stackend) { + /* + * If obj + len extends past the last frame, this + * check won't pass and the next frame will be 0, + * causing us to bail out and correctly report + * the copy as invalid. + */ + if (obj + len <= frame) + return obj >= oldframe + 2 * sizeof(void *) ? + GOOD_FRAME : BAD_STACK; + oldframe = frame; + frame = *(const void * const *)frame; + } + return BAD_STACK; +#else + return NOT_STACK; +#endif +} + +#ifdef CONFIG_STACKTRACE + static int save_stack_address(struct stack_trace *trace, unsigned long addr, bool nosched) { @@ -241,3 +289,4 @@ void save_stack_trace_user(struct stack_trace *trace) if (trace->nr_entries < trace->max_entries) trace->entries[trace->nr_entries++] = ULONG_MAX; } +#endif /* CONFIG_STACKTRACE */ diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h index ca5461e..f3b7dd9 100644 --- a/include/linux/page_ext.h +++ b/include/linux/page_ext.h @@ -3,7 +3,6 @@ #define __LINUX_PAGE_EXT_H #include -#include #include struct pglist_data; diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index ba29a06..60bb988 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h @@ -7,6 +7,30 @@ struct task_struct; struct pt_regs; +/* + * For per-arch arch_within_stack_frames() implementations, defined in + * kernel/stacktrace.c. + */ +enum { + BAD_STACK = -1, + NOT_STACK = 0, + GOOD_FRAME, + GOOD_STACK, +}; + +#ifdef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES +extern int arch_within_stack_frames(const void * const stack, + const void * const stackend, + const void *obj, unsigned long len); +#else +static inline int arch_within_stack_frames(const void * const stack, + const void * const stackend, + const void *obj, unsigned long len) +{ + return NOT_STACK; +} +#endif + #ifdef CONFIG_STACKTRACE struct stack_trace { unsigned int nr_entries, max_entries; diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index 34f053a..5403851 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -23,18 +23,6 @@ #endif #include - -/* - * For per-arch arch_within_stack_frames() implementations, defined in - * asm/thread_info.h. - */ -enum { - BAD_STACK = -1, - NOT_STACK = 0, - GOOD_FRAME, - GOOD_STACK, -}; - #include #ifdef __KERNEL__ @@ -92,15 +80,6 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag) #define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED) -#ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES -static inline int arch_within_stack_frames(const void * const stack, - const void * const stackend, - const void *obj, unsigned long len) -{ - return 0; -} -#endif - #ifdef CONFIG_HARDENED_USERCOPY extern void __check_object_size(const void *ptr, unsigned long n, bool to_user); diff --git a/mm/usercopy.c b/mm/usercopy.c index e9e9325..6a74776 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include /* -- 2.7.4