lkml.org 
[lkml]   [2021]   [Jul]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 02/10] ARM: traps: use get_kernel_nofault instead of set_fs()
    Date
    From: Arnd Bergmann <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.

    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
    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 64308e3a5d0c..10dd3ef1f398 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.29.2
    \
     
     \ /
      Last update: 2021-07-26 16:12    [W:4.723 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site