From: Arnd Bergmann <arnd@arndb.de> To: Christoph Hellwig <hch@infradead.org>, Russell King <linux@armlinux.org.uk>, Alexander Viro <viro@zeniv.linux.org.uk> Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arch@vger.kernel.org, linux-mm@kvack.org, Arnd Bergmann <arnd@arndb.de> Subject: [PATCH v2 2/9] ARM: traps: use get_kernel_nofault instead of set_fs() Date: Fri, 18 Sep 2020 14:46:17 +0200 [thread overview] Message-ID: <20200918124624.1469673-3-arnd@arndb.de> (raw) In-Reply-To: <20200918124624.1469673-1-arnd@arndb.de> ARM uses set_fs() and __get_user() to allow the stack dumping code to access possibly invalid pointers carefully. These can be changed to the simpler get_kernel_nofault(), and allow the eventual removal of set_fs(). dump_instr() will print either kernel or user space pointers, depending on how it was called. For dump_mem(), I assume we are only interested in kernel pointers, and the only time that this is called with user_mode(regs)==true is when the regs themselves are unreliable as a result of the condition that caused the trap. Signed-off-by: Arnd Bergmann <arnd@arndb.de> --- arch/arm/kernel/traps.c | 47 ++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 17d5a785df28..c3964a283b63 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -122,17 +122,8 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, unsigned long top) { unsigned long first; - mm_segment_t fs; int i; - /* - * We need to switch to kernel mode so that we can use __get_user - * to safely read from kernel space. Note that we now dump the - * code first, just in case the backtrace kills us. - */ - fs = get_fs(); - set_fs(KERNEL_DS); - printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top); for (first = bottom & ~31; first < top; first += 32) { @@ -145,7 +136,7 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, for (p = first, i = 0; i < 8 && p < top; i++, p += 4) { if (p >= bottom && p < top) { unsigned long val; - if (__get_user(val, (unsigned long *)p) == 0) + if (get_kernel_nofault(val, (unsigned long *)p)) sprintf(str + i * 9, " %08lx", val); else sprintf(str + i * 9, " ????????"); @@ -153,11 +144,9 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, } printk("%s%04lx:%s\n", lvl, first & 0xffff, str); } - - set_fs(fs); } -static void __dump_instr(const char *lvl, struct pt_regs *regs) +static void dump_instr(const char *lvl, struct pt_regs *regs) { unsigned long addr = instruction_pointer(regs); const int thumb = thumb_mode(regs); @@ -173,10 +162,20 @@ static void __dump_instr(const char *lvl, struct pt_regs *regs) for (i = -4; i < 1 + !!thumb; i++) { unsigned int val, bad; - if (thumb) - bad = get_user(val, &((u16 *)addr)[i]); - else - bad = get_user(val, &((u32 *)addr)[i]); + if (!user_mode(regs)) { + if (thumb) { + u16 val16; + bad = get_kernel_nofault(val16, &((u16 *)addr)[i]); + val = val16; + } else { + bad = get_kernel_nofault(val, &((u32 *)addr)[i]); + } + } else { + if (thumb) + bad = get_user(val, &((u16 *)addr)[i]); + else + bad = get_user(val, &((u32 *)addr)[i]); + } if (!bad) p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ", @@ -189,20 +188,6 @@ static void __dump_instr(const char *lvl, struct pt_regs *regs) printk("%sCode: %s\n", lvl, str); } -static void dump_instr(const char *lvl, struct pt_regs *regs) -{ - mm_segment_t fs; - - if (!user_mode(regs)) { - fs = get_fs(); - set_fs(KERNEL_DS); - __dump_instr(lvl, regs); - set_fs(fs); - } else { - __dump_instr(lvl, regs); - } -} - #ifdef CONFIG_ARM_UNWIND static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk, const char *loglvl) -- 2.27.0
WARNING: multiple messages have this Message-ID (diff)
From: Arnd Bergmann <arnd@arndb.de> To: Christoph Hellwig <hch@infradead.org>, Russell King <linux@armlinux.org.uk>, Alexander Viro <viro@zeniv.linux.org.uk> Cc: linux-arch@vger.kernel.org, linux-mm@kvack.org, Arnd Bergmann <arnd@arndb.de>, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 2/9] ARM: traps: use get_kernel_nofault instead of set_fs() Date: Fri, 18 Sep 2020 14:46:17 +0200 [thread overview] Message-ID: <20200918124624.1469673-3-arnd@arndb.de> (raw) In-Reply-To: <20200918124624.1469673-1-arnd@arndb.de> ARM uses set_fs() and __get_user() to allow the stack dumping code to access possibly invalid pointers carefully. These can be changed to the simpler get_kernel_nofault(), and allow the eventual removal of set_fs(). dump_instr() will print either kernel or user space pointers, depending on how it was called. For dump_mem(), I assume we are only interested in kernel pointers, and the only time that this is called with user_mode(regs)==true is when the regs themselves are unreliable as a result of the condition that caused the trap. Signed-off-by: Arnd Bergmann <arnd@arndb.de> --- arch/arm/kernel/traps.c | 47 ++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 17d5a785df28..c3964a283b63 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -122,17 +122,8 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, unsigned long top) { unsigned long first; - mm_segment_t fs; int i; - /* - * We need to switch to kernel mode so that we can use __get_user - * to safely read from kernel space. Note that we now dump the - * code first, just in case the backtrace kills us. - */ - fs = get_fs(); - set_fs(KERNEL_DS); - printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top); for (first = bottom & ~31; first < top; first += 32) { @@ -145,7 +136,7 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, for (p = first, i = 0; i < 8 && p < top; i++, p += 4) { if (p >= bottom && p < top) { unsigned long val; - if (__get_user(val, (unsigned long *)p) == 0) + if (get_kernel_nofault(val, (unsigned long *)p)) sprintf(str + i * 9, " %08lx", val); else sprintf(str + i * 9, " ????????"); @@ -153,11 +144,9 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, } printk("%s%04lx:%s\n", lvl, first & 0xffff, str); } - - set_fs(fs); } -static void __dump_instr(const char *lvl, struct pt_regs *regs) +static void dump_instr(const char *lvl, struct pt_regs *regs) { unsigned long addr = instruction_pointer(regs); const int thumb = thumb_mode(regs); @@ -173,10 +162,20 @@ static void __dump_instr(const char *lvl, struct pt_regs *regs) for (i = -4; i < 1 + !!thumb; i++) { unsigned int val, bad; - if (thumb) - bad = get_user(val, &((u16 *)addr)[i]); - else - bad = get_user(val, &((u32 *)addr)[i]); + if (!user_mode(regs)) { + if (thumb) { + u16 val16; + bad = get_kernel_nofault(val16, &((u16 *)addr)[i]); + val = val16; + } else { + bad = get_kernel_nofault(val, &((u32 *)addr)[i]); + } + } else { + if (thumb) + bad = get_user(val, &((u16 *)addr)[i]); + else + bad = get_user(val, &((u32 *)addr)[i]); + } if (!bad) p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ", @@ -189,20 +188,6 @@ static void __dump_instr(const char *lvl, struct pt_regs *regs) printk("%sCode: %s\n", lvl, str); } -static void dump_instr(const char *lvl, struct pt_regs *regs) -{ - mm_segment_t fs; - - if (!user_mode(regs)) { - fs = get_fs(); - set_fs(KERNEL_DS); - __dump_instr(lvl, regs); - set_fs(fs); - } else { - __dump_instr(lvl, regs); - } -} - #ifdef CONFIG_ARM_UNWIND static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk, const char *loglvl) -- 2.27.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-09-18 12:47 UTC|newest] Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-09-18 12:46 [PATCH v2 0/9] ARM: remove set_fs callers and implementation Arnd Bergmann 2020-09-18 12:46 ` Arnd Bergmann 2020-09-18 12:46 ` [PATCH v2 1/9] mm/maccess: fix unaligned copy_{from,to}_kernel_nofault Arnd Bergmann 2020-09-18 12:46 ` [PATCH v2 1/9] mm/maccess: fix unaligned copy_{from, to}_kernel_nofault Arnd Bergmann 2020-09-18 12:46 ` Arnd Bergmann [this message] 2020-09-18 12:46 ` [PATCH v2 2/9] ARM: traps: use get_kernel_nofault instead of set_fs() Arnd Bergmann 2020-09-19 5:27 ` Christoph Hellwig 2020-09-19 5:27 ` Christoph Hellwig 2020-09-18 12:46 ` [PATCH v2 3/9] ARM: oabi-compat: add epoll_pwait handler Arnd Bergmann 2020-09-18 12:46 ` Arnd Bergmann 2020-09-21 12:54 ` Sasha Levin 2020-09-21 13:27 ` Arnd Bergmann 2020-09-18 12:46 ` [PATCH v2 4/9] ARM: syscall: always store thread_info->syscall Arnd Bergmann 2020-09-18 12:46 ` Arnd Bergmann 2020-09-18 12:46 ` [PATCH v2 5/9] ARM: oabi-compat: rework epoll_wait/epoll_pwait emulation Arnd Bergmann 2020-09-18 12:46 ` Arnd Bergmann 2020-09-19 5:32 ` Christoph Hellwig 2020-09-19 5:32 ` Christoph Hellwig 2020-09-26 18:30 ` Arnd Bergmann 2020-09-26 18:30 ` Arnd Bergmann 2020-09-26 18:30 ` Arnd Bergmann 2020-09-18 12:46 ` [PATCH v2 6/9] ARM: oabi-compat: rework sys_semtimedop emulation Arnd Bergmann 2020-09-18 12:46 ` Arnd Bergmann 2020-09-18 12:46 ` [PATCH v2 7/9] ARM: oabi-compat: rework fcntl64() emulation Arnd Bergmann 2020-09-18 12:46 ` Arnd Bergmann 2020-09-18 12:46 ` [PATCH v2 8/9] ARM: uaccess: add __{get,put}_kernel_nofault Arnd Bergmann 2020-09-18 12:46 ` Arnd Bergmann 2020-09-18 12:46 ` [PATCH v2 9/9] ARM: uaccess: remove set_fs() implementation Arnd Bergmann 2020-09-18 12:46 ` Arnd Bergmann 2020-09-19 5:27 ` [PATCH v2 0/9] ARM: remove set_fs callers and implementation Christoph Hellwig 2020-09-19 5:27 ` Christoph Hellwig 2020-09-25 13:40 ` Arnd Bergmann 2020-09-25 13:40 ` Arnd Bergmann 2020-09-25 13:40 ` Arnd Bergmann 2020-09-26 6:49 ` Christoph Hellwig 2020-09-26 6:49 ` Christoph Hellwig 2021-07-05 6:01 ` Christoph Hellwig 2021-07-05 6:01 ` Christoph Hellwig 2021-07-22 17:27 ` Arnd Bergmann 2021-07-22 17:27 ` Arnd Bergmann 2021-07-22 17:27 ` Arnd Bergmann 2020-09-19 8:19 ` Russell King - ARM Linux admin 2020-09-19 8:19 ` Russell King - ARM Linux admin 2020-09-25 14:08 ` Arnd Bergmann 2020-09-25 14:08 ` Arnd Bergmann 2020-09-25 14:08 ` Arnd Bergmann 2020-09-25 15:30 ` Arnd Bergmann 2020-09-25 15:30 ` Arnd Bergmann 2020-09-25 15:30 ` Arnd Bergmann
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200918124624.1469673-3-arnd@arndb.de \ --to=arnd@arndb.de \ --cc=hch@infradead.org \ --cc=linux-arch@vger.kernel.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=linux@armlinux.org.uk \ --cc=viro@zeniv.linux.org.uk \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.