• Dave Marchevsky's avatar
    bpf: Refcount task stack in bpf_get_task_stack · 06ab134c
    Dave Marchevsky authored
    On x86 the struct pt_regs * grabbed by task_pt_regs() points to an
    offset of task->stack. The pt_regs are later dereferenced in
    __bpf_get_stack (e.g. by user_mode() check). This can cause a fault if
    the task in question exits while bpf_get_task_stack is executing, as
    warned by task_stack_page's comment:
    
    * When accessing the stack of a non-current task that might exit, use
    * try_get_task_stack() instead.  task_stack_page will return a pointer
    * that could get freed out from under you.
    
    Taking the comment's advice and using try_get_task_stack() and
    put_task_stack() to hold task->stack refcount, or bail early if it's
    already 0. Incrementing stack_refcount will ensure the task's stack
    sticks around while we're using its data.
    
    I noticed this bug while testing a bpf task iter similar to
    bpf_iter_task_stack in selftests, except mine grabbed user stack, and
    getting intermittent crashes, which resulted in dumps like:
    
      BUG: unable to handle page fault for address: ...
    06ab134c
stackmap.c 18.5 KB