• Maxim Mikityanskiy's avatar
    Bluetooth: L2CAP: Fix use-after-free caused by l2cap_reassemble_sdu · 3aff8aac
    Maxim Mikityanskiy authored
    Fix the race condition between the following two flows that run in
    parallel:
    
    1. l2cap_reassemble_sdu -> chan->ops->recv (l2cap_sock_recv_cb) ->
       __sock_queue_rcv_skb.
    
    2. bt_sock_recvmsg -> skb_recv_datagram, skb_free_datagram.
    
    An SKB can be queued by the first flow and immediately dequeued and
    freed by the second flow, therefore the callers of l2cap_reassemble_sdu
    can't use the SKB after that function returns. However, some places
    continue accessing struct l2cap_ctrl that resides in the SKB's CB for a
    short time after l2cap_reassemble_sdu returns, leading to a
    use-after-free condition (the stack trace is below, line numbers for
    kernel 5.19.8).
    
    Fix it by keeping a local copy of struct l2cap_ctrl.
    
    BUG: KASAN: use-after-free in l2cap_rx_state_recv (net/bluetooth/l2cap_core.c:6906) bluetooth
    Read of size 1 at addr ffff88812025f2f0 by task kworker/u17:3/43169
    
    Workqueue: hci0 hci_rx_work [bluetooth]
    Call Trace:
     <TASK>
     dump_stack_lvl (lib/dump_stack.c:107 (discriminator 4))
     print_report.cold (mm/kasan/report.c:314 mm/kasan/report.c:429)
     ? l2cap_rx_state_recv (net/bluetooth/l2cap_core.c:6906) bluetooth
     kasan_report (mm/kasan/report.c:162 mm/kasan/report.c:493)
     ? l2cap_rx_state_recv (net/bluetooth/l2cap_core.c:6906) bluetooth
     l2cap_rx_state_recv (net/bluetooth/l2cap_core.c:6906) bluetooth
     l2cap_rx (net/bluetooth/l2cap_core.c:7236 net/bluetooth/l2cap_core.c:7271) bluetooth
     ret_from_fork (arch/x86/entry/entry_64.S:306)
     </TASK>
    
    Allocated by task 43169:
     kasan_save_stack (mm/kasan/common.c:39)
     __kasan_slab_alloc (mm/kasan/common.c:45 mm/kasan/common.c:436 mm/kasan/common.c:469)
     kmem_cache_alloc_node (mm/slab.h:750 mm/slub.c:3243 mm/slub.c:3293)
     __alloc_skb (net/core/skbuff.c:414)
     l2cap_recv_frag (./include/net/bluetooth/bluetooth.h:425 net/bluetooth/l2cap_core.c:8329) bluetooth
     l2cap_recv_acldata (net/bluetooth/l2cap_core.c:8442) bluetooth
     hci_rx_work (net/bluetooth/hci_core.c:3642 net/bluetooth/hci_core.c:3832) bluetooth
     process_one_work (kernel/workqueue.c:2289)
     worker_thread (./include/linux/list.h:292 kernel/workqueue.c:2437)
     kthread (kernel/kthread.c:376)
     ret_from_fork (arch/x86/entry/entry_64.S:306)
    
    Freed by task 27920:
     kasan_save_stack (mm/kasan/common.c:39)
     kasan_set_track (mm/kasan/common.c:45)
     kasan_set_free_info (mm/kasan/generic.c:372)
     ____kasan_slab_free (mm/kasan/common.c:368 mm/kasan/common.c:328)
     slab_free_freelist_hook (mm/slub.c:1780)
     kmem_cache_free (mm/slub.c:3536 mm/slub.c:3553)
     skb_free_datagram (./include/net/sock.h:1578 ./include/net/sock.h:1639 net/core/datagram.c:323)
     bt_sock_recvmsg (net/bluetooth/af_bluetooth.c:295) bluetooth
     l2cap_sock_recvmsg (net/bluetooth/l2cap_sock.c:1212) bluetooth
     sock_read_iter (net/socket.c:1087)
     new_sync_read (./include/linux/fs.h:2052 fs/read_write.c:401)
     vfs_read (fs/read_write.c:482)
     ksys_read (fs/read_write.c:620)
     do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80)
     entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120)
    
    Link: https://lore.kernel.org/linux-bluetooth/CAKErNvoqga1WcmoR3-0875esY6TVWFQDandbVZncSiuGPBQXLA@mail.gmail.com/T/#u
    Fixes: d2a7ac5d ("Bluetooth: Add the ERTM receive state machine")
    Fixes: 4b51dae9 ("Bluetooth: Add streaming mode receive and incoming packet classifier")
    Signed-off-by: default avatarMaxim Mikityanskiy <maxtram95@gmail.com>
    Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
    3aff8aac
l2cap_core.c 201 KB