lkml.org 
[lkml]   [2016]   [Aug]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v4 35/57] x86/dumpstack: add recursion checking for all stacks
    Date
    in_exception_stack() has some recursion checking which makes sure the
    stack trace code never traverses a given exception stack more than once.
    Otherwise corruption could cause a stack to point to itself (directly or
    indirectly), resulting in an infinite loop.

    Extend the recursion checking to all stacks.

    Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
    ---
    arch/x86/kernel/dumpstack_32.c | 22 +++++++++++++++++++---
    arch/x86/kernel/dumpstack_64.c | 34 +++++++++++++++++++---------------
    2 files changed, 38 insertions(+), 18 deletions(-)

    diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
    index ca49102..c233f93 100644
    --- a/arch/x86/kernel/dumpstack_32.c
    +++ b/arch/x86/kernel/dumpstack_32.c
    @@ -81,16 +81,32 @@ int get_stack_info(unsigned long *stack, struct task_struct *task,
    task = task ? : current;

    if (in_task_stack(stack, task, info))
    - return 0;
    + goto recursion_check;

    if (task != current)
    goto unknown;

    if (in_hardirq_stack(stack, info))
    - return 0;
    + goto recursion_check;

    if (in_softirq_stack(stack, info))
    - return 0;
    + goto recursion_check;
    +
    + goto unknown;
    +
    +recursion_check:
    + /*
    + * Make sure we don't iterate through any given stack more than once.
    + * If it comes up a second time then there's something wrong going on:
    + * just break out and report an unknown stack type.
    + */
    + if (visit_mask) {
    + if (*visit_mask & (1UL << info->type))
    + goto unknown;
    + *visit_mask |= 1UL << info->type;
    + }
    +
    + return 0;

    unknown:
    info->type = STACK_TYPE_UNKNOWN;
    diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
    index 65a77bf..7a4029d 100644
    --- a/arch/x86/kernel/dumpstack_64.c
    +++ b/arch/x86/kernel/dumpstack_64.c
    @@ -47,8 +47,7 @@ void stack_type_str(enum stack_type type, const char **begin, const char **end)
    }
    }

    -static bool in_exception_stack(unsigned long *stack, struct stack_info *info,
    - unsigned long *visit_mask)
    +static bool in_exception_stack(unsigned long *stack, struct stack_info *info)
    {
    unsigned long *begin, *end;
    struct pt_regs *regs;
    @@ -64,15 +63,6 @@ static bool in_exception_stack(unsigned long *stack, struct stack_info *info,
    if (stack < begin || stack > end)
    continue;

    - /*
    - * Make sure we only iterate through an exception stack once.
    - * If it comes up for the second time then there's something
    - * wrong going on - just break and return NULL:
    - */
    - if (*visit_mask & (1U << k))
    - break;
    - *visit_mask |= 1U << k;
    -
    info->type = STACK_TYPE_EXCEPTION + k;
    info->begin = begin;
    info->end = end;
    @@ -114,16 +104,30 @@ int get_stack_info(unsigned long *stack, struct task_struct *task,
    task = task ? : current;

    if (in_task_stack(stack, task, info))
    - return 0;
    + goto recursion_check;

    if (task != current)
    goto unknown;

    - if (in_exception_stack(stack, info, visit_mask))
    - return 0;
    + if (in_exception_stack(stack, info))
    + goto recursion_check;

    if (in_irq_stack(stack, info))
    - return 0;
    + goto recursion_check;
    +
    + goto unknown;
    +
    +recursion_check:
    + /*
    + * Make sure we don't iterate through any given stack more than once.
    + * If it comes up a second time then there's something wrong going on:
    + * just break out and report an unknown stack type.
    + */
    + if (visit_mask) {
    + if (*visit_mask & (1UL << info->type))
    + goto unknown;
    + *visit_mask |= 1UL << info->type;
    + }

    return 0;

    --
    2.7.4
    \
     
     \ /
      Last update: 2016-09-17 09:57    [W:3.257 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site