Received: by 10.213.65.68 with SMTP id h4csp2236816imn; Sun, 8 Apr 2018 23:14:31 -0700 (PDT) X-Google-Smtp-Source: AIpwx49WnSy1fdx+6OCMnhDKXEeeSfSeaff6o99ULGvzgNhAhG5lrlxrBUSUsr+G21TB7wgrdwOZ X-Received: by 2002:a17:902:728f:: with SMTP id d15-v6mr36481304pll.227.1523254471815; Sun, 08 Apr 2018 23:14:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523254471; cv=none; d=google.com; s=arc-20160816; b=lT1vbCexokpj4Yup2IHyZifqqGyICuGHlqAyLnBP3kBW4DAFrvw5kqEqcKSeVlgAzh DEoMYZvznsfqoi4jYi2BPV3WUG2x2AbjZmDhsvlRlK6G+ssdwrRTHJTu4m4WE8QGryCb o5U1hTdyCgT2TXCDpoz29Ioy+Zbbepgw51+rkIAbeH9cg7DM3Eyd0VtPkCGLxfzcYdR5 NUYe18LZrj0FeQqpU6RJLVb8ahMJANZi5tHH9dqrgOxYsnz5L9AkBXDKxpzGOg39xhwI dF/w2CmPUhYmmwX65JvFGqt5vr51UYotL0ijG6E61ffigrEjcOi69pzB5MC/s8SqfM8n zRBA== 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=1dlE/GdUgaKA1rvIF6ZidH8Qsgf8dZGqVCGV9RyHFbY=; b=H9hy2nbuThVNt8D8T6byhfFK6dEK1Zk2L8f33RKKccJBfPO2BKCeRu1OX9OHV9QASE I/RksyYa3HF79vcnkdcpM753fW4vC5ZvssDNziQaj2H4RoTV7jH93gCVf6MsIVZPpwgY Bv9SJ2RcOpuNN215nzopsSrH84y618JWTvFeoTddEugnh/MzkDE9XEcOLM3cJ7ErgZA0 1mRcKJrS37r3YiE3eiefn3FjwKK4x4YZc+zLZayjTZeMR+64rF8V/2dqHSsT1smYMc1s ldUMYJeUayZIbFYcZ5he6BeOWFDxAhdHdEhs4rrSCdh9IXAjF8D4XEr/DdSWwhIHO7qU yQww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=lCIvAzcC; 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 p68si10668487pga.751.2018.04.08.23.13.54; Sun, 08 Apr 2018 23:14:31 -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=lCIvAzcC; 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 S1751731AbeDIGK6 (ORCPT + 99 others); Mon, 9 Apr 2018 02:10:58 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:32959 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751633AbeDIGK4 (ORCPT ); Mon, 9 Apr 2018 02:10:56 -0400 Received: by mail-wr0-f195.google.com with SMTP id z73so7900800wrb.0 for ; Sun, 08 Apr 2018 23:10:55 -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=1dlE/GdUgaKA1rvIF6ZidH8Qsgf8dZGqVCGV9RyHFbY=; b=lCIvAzcCnpMaFwS8brSnZCZ1qajiOqRwTc8B4Efev0K05rIhxF6Q6VYUrmO4+qRqwu cQRSg4D6zr/nr3nLnOVS4+KzOIVnEP0iCygUQZJDOtQiKh+/b4eRFn51kPfm+fVCWFBb bjvZ5kiQK5C3ExDFg1b4Dh0IN4pUcrAoyXo+e0/G4ZQ9/hAyFh37pG78vvkS3SilmP2e IOjCr+NYR7TJ3JMmuXOjgq4PtfPJwT7CBcu5CYfGP0qGV9VtMSiu3zK3CzALyRDyAtBo CezPRgrdcvrGFIyp/zmvFBGAr5r4N3jYWVMoL9Cxkl3fRoF0Kb1bdldkEdW+GFt+aVMy NQsw== 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=1dlE/GdUgaKA1rvIF6ZidH8Qsgf8dZGqVCGV9RyHFbY=; b=t5AU1IUIMOTsD5aIwhbgxaOF6HUY6vVfv1lUou4atklNnQLC+LH50/vCAbBrJq43p1 EXCI1MH6cOB+jq5NkDC2W+lKOdUGYMBg3SH4Wkrx5Fvsx3Abadc3UzED0giITUuszo9f zai5ITUEzUcbNDm0yH1jweGumj/vcShvYyxNbkn6ap2sh84MsO014ODXcW1THbsht9BV dM3DfvSLXxLiQXZ+LhiIPfldhXx4Pv0HsXfesZbvh0fjfyqN17P4hzh6RoIqaBaKBAeW JpbgbXt5SLtx/7yS6TUjCHEYl8WIUUaF1qNEtfeY+Suiwz+MCzICMPIcUhchPpFIiBz7 FEKw== X-Gm-Message-State: AElRT7ERk/tq129xDlFljlL+uX35wbEgXtGzRarrAjsXO697FcIB/gk0 +F/ECtKVxpbs1XTXa5AA7zE= X-Received: by 10.223.143.7 with SMTP id p7mr23838951wrb.207.1523254254919; Sun, 08 Apr 2018 23:10:54 -0700 (PDT) Received: from sahara-ad.darkmatter.uae (bba421079.alshamil.net.ae. [83.110.21.201]) by smtp.gmail.com with ESMTPSA id 185sm23240237wmj.46.2018.04.08.23.10.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 08 Apr 2018 23:10:54 -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 v2 1/3] stacktrace: move arch_within_stack_frames from thread_info.h Date: Mon, 9 Apr 2018 10:06:07 +0400 Message-Id: <1523253969-31699-2-git-send-email-kpark3469@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1523253969-31699-1-git-send-email-kpark3469@gmail.com> References: <1523253969-31699-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. And, linux/stacktrace.h includes asm/stacktrace.h from now on. Signed-off-by: Sahara Reviewed-by: Kees Cook --- arch/arm/kernel/stacktrace.c | 1 - arch/arm64/kernel/stacktrace.c | 1 - arch/mips/kernel/stacktrace.c | 1 - arch/mips/oprofile/backtrace.c | 1 - arch/sh/kernel/stacktrace.c | 1 - arch/sparc/kernel/stacktrace.c | 1 - arch/um/kernel/stacktrace.c | 1 - arch/unicore32/kernel/process.c | 1 - arch/unicore32/kernel/stacktrace.c | 2 -- arch/x86/include/asm/thread_info.h | 51 +------------------------------------- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/stacktrace.c | 50 ++++++++++++++++++++++++++++++++++++- arch/xtensa/kernel/stacktrace.c | 1 - include/linux/page_ext.h | 1 - include/linux/stacktrace.h | 25 +++++++++++++++++++ include/linux/thread_info.h | 21 ---------------- kernel/sysctl.c | 1 - mm/usercopy.c | 2 +- 18 files changed, 77 insertions(+), 87 deletions(-) diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index a56e7c8..d7d629b 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -4,7 +4,6 @@ #include #include -#include #include #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index d5718a0..33c4028 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -25,7 +25,6 @@ #include #include -#include /* * AArch64 PCS assigns the frame pointer to x29. diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c index 7c7c902..0b44e10 100644 --- a/arch/mips/kernel/stacktrace.c +++ b/arch/mips/kernel/stacktrace.c @@ -8,7 +8,6 @@ #include #include #include -#include /* * Save stack-backtrace addresses into a stack_trace buffer: diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c index 806fb79..845ff8c 100644 --- a/arch/mips/oprofile/backtrace.c +++ b/arch/mips/oprofile/backtrace.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c index 7a73d27..7a7ac4c 100644 --- a/arch/sh/kernel/stacktrace.c +++ b/arch/sh/kernel/stacktrace.c @@ -16,7 +16,6 @@ #include #include #include -#include static int save_stack_stack(void *data, char *name) { diff --git a/arch/sparc/kernel/stacktrace.c b/arch/sparc/kernel/stacktrace.c index be4c14c..42cdf86 100644 --- a/arch/sparc/kernel/stacktrace.c +++ b/arch/sparc/kernel/stacktrace.c @@ -5,7 +5,6 @@ #include #include #include -#include #include "kstack.h" diff --git a/arch/um/kernel/stacktrace.c b/arch/um/kernel/stacktrace.c index ebe7bcf..a0d556e 100644 --- a/arch/um/kernel/stacktrace.c +++ b/arch/um/kernel/stacktrace.c @@ -14,7 +14,6 @@ #include #include #include -#include void dump_trace(struct task_struct *tsk, const struct stacktrace_ops *ops, diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index 2bc10b8..ffca651 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c @@ -36,7 +36,6 @@ #include #include -#include #include "setup.h" diff --git a/arch/unicore32/kernel/stacktrace.c b/arch/unicore32/kernel/stacktrace.c index 9976e76..f9cd2a4 100644 --- a/arch/unicore32/kernel/stacktrace.c +++ b/arch/unicore32/kernel/stacktrace.c @@ -14,8 +14,6 @@ #include #include -#include - #if defined(CONFIG_FRAME_POINTER) /* * Unwind the current stack frame and store the new register values in the 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..f433a33 100644 --- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c @@ -9,9 +9,56 @@ #include #include #include -#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 +288,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/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c index 0df4080..ab831d8 100644 --- a/arch/xtensa/kernel/stacktrace.c +++ b/arch/xtensa/kernel/stacktrace.c @@ -12,7 +12,6 @@ #include #include -#include #include #include 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..4fd061e 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h @@ -3,10 +3,35 @@ #define __LINUX_STACKTRACE_H #include +#include 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/kernel/sysctl.c b/kernel/sysctl.c index bdf7090..782c3e4 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -73,7 +73,6 @@ #ifdef CONFIG_X86 #include -#include #include #endif #ifdef CONFIG_SPARC 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