lkml.org 
[lkml]   [2022]   [Jul]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 07/31] net: rose: fix UAF bug caused by rose_t0timer_expiry
    Date
    From: Duoming Zhou <duoming@zju.edu.cn>

    commit 148ca04518070910739dfc4eeda765057856403d upstream.

    There are UAF bugs caused by rose_t0timer_expiry(). The
    root cause is that del_timer() could not stop the timer
    handler that is running and there is no synchronization.
    One of the race conditions is shown below:

    (thread 1) | (thread 2)
    | rose_device_event
    | rose_rt_device_down
    | rose_remove_neigh
    rose_t0timer_expiry | rose_stop_t0timer(rose_neigh)
    ... | del_timer(&neigh->t0timer)
    | kfree(rose_neigh) //[1]FREE
    neigh->dce_mode //[2]USE |

    The rose_neigh is deallocated in position [1] and use in
    position [2].

    The crash trace triggered by POC is like below:

    BUG: KASAN: use-after-free in expire_timers+0x144/0x320
    Write of size 8 at addr ffff888009b19658 by task swapper/0/0
    ...
    Call Trace:
    <IRQ>
    dump_stack_lvl+0xbf/0xee
    print_address_description+0x7b/0x440
    print_report+0x101/0x230
    ? expire_timers+0x144/0x320
    kasan_report+0xed/0x120
    ? expire_timers+0x144/0x320
    expire_timers+0x144/0x320
    __run_timers+0x3ff/0x4d0
    run_timer_softirq+0x41/0x80
    __do_softirq+0x233/0x544
    ...

    This patch changes rose_stop_ftimer() and rose_stop_t0timer()
    in rose_remove_neigh() to del_timer_sync() in order that the
    timer handler could be finished before the resources such as
    rose_neigh and so on are deallocated. As a result, the UAF
    bugs could be mitigated.

    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
    Link: https://lore.kernel.org/r/20220705125610.77971-1-duoming@zju.edu.cn
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/rose/rose_route.c | 4 ++--
    1 file changed, 2 insertions(+), 2 deletions(-)

    --- a/net/rose/rose_route.c
    +++ b/net/rose/rose_route.c
    @@ -230,8 +230,8 @@ static void rose_remove_neigh(struct ros
    {
    struct rose_neigh *s;

    - rose_stop_ftimer(rose_neigh);
    - rose_stop_t0timer(rose_neigh);
    + del_timer_sync(&rose_neigh->ftimer);
    + del_timer_sync(&rose_neigh->t0timer);

    skb_queue_purge(&rose_neigh->queue);


    \
     
     \ /
      Last update: 2022-07-11 11:13    [W:5.261 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site