KASAN: use-after-free Read in hci_send_acl
Original report of the bug: https://syzkaller.appspot.com/bug?id=2e1943a94647f7732dd6fc60368642d6e8dc91b1
Our system SyzScope detects arbitrary address write in this bug.
Fuzzer tested kernel version: ac3a0c84
Upstream patch : Bluetooth: verify AMP hci_chan before amp_destroy
Primitive 1: Arbitrary address write in skb_queue_tail
Bug Impact Analysis:
The vulnerable object was freed in hci_disconn_loglink_complete_evt
static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
...
hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
if (!hchan)
goto unlock;
amp_destroy_logical_link(hchan, ev->reason); //hchan was freed inside
unlock:
hci_dev_unlock(hdev);
}
Then the same freed object was used in hci_queue_acl,
void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
{
struct hci_dev *hdev = chan->conn->hdev;
BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
hci_queue_acl(chan, &chan->data_q, skb, flags); //chan is the freed object, so chan->data_q can take any arbitrary value
queue_work(hdev->workqueue, &hdev->tx_work);
}
In hci_queue_acl, the second argument was passed to skb_queue_tail->__skb_queue_tail->__skb_queue_before->__skb_insert
static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, struct sk_buff *skb, __u16 flags)
{
...
list = skb_shinfo(skb)->frag_list;
if (!list) {
/* Non fragmented */
BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
skb_queue_tail(queue, skb); //queue came from the freed object
...
}
static inline void __skb_queue_tail(struct sk_buff_head *list,
struct sk_buff *newsk)
{
__skb_queue_before(list, (struct sk_buff *)list, newsk); //list came from the freed object
}
static inline void __skb_queue_before(struct sk_buff_head *list,
struct sk_buff *next,
struct sk_buff *newsk)
{
__skb_insert(newsk, next->prev, next, list); //next and list came from the freed object
}
static inline void __skb_insert(struct sk_buff *newsk,
struct sk_buff *prev, struct sk_buff *next,
struct sk_buff_head *list)
{
WRITE_ONCE(newsk->next, next);
WRITE_ONCE(newsk->prev, prev);
WRITE_ONCE(next->prev, newsk); //next->prev can point to arbitrary memory address
WRITE_ONCE(prev->next, newsk); //prev->next can point to arbitrary memory address
list->qlen++;
}
In __skb_insert, both next and prev came from freed object, therefore next->prev and prev->next can point to an arbitrary memory address. These are arbitrary address writes.
Trace in high level:
|__asan_load8 mm/kasan/generic.c:186
|hci_send_acl net/bluetooth/hci_core.c:3991 (Triggered the original UAF read)
|skb_queue_tail net/bluetooth/hci_core.c:3956
|skb_queue_tail ./include/linux/skbuff.h:1895 (Triggered a new impact: Arbitrary address write)
Trace in detail:
0xffffffff84e1ee57
hci_send_acl net/bluetooth/hci_core.c:3991 (Triggered the original UAF read)
--------------------------------------
0xffffffff84e1ee6b
hci_send_acl net/bluetooth/hci_core.c:3991
--------------------------------------
0xffffffff84e1ee86
hci_send_acl ./include/linux/skbuff.h:2097
--------------------------------------
0xffffffff84e1ee95
hci_send_acl ./include/linux/skbuff.h:2097
--------------------------------------
0xffffffff84e1eeb2
hci_send_acl net/bluetooth/hci_core.c:3937
--------------------------------------
0xffffffff84e1eec4
hci_send_acl net/bluetooth/hci_core.c:3939
--------------------------------------
0xffffffff84e1eedb
hci_send_acl net/bluetooth/hci_core.c:3939
--------------------------------------
0xffffffff84e1eee0
hci_send_acl net/bluetooth/hci_core.c:3939
--------------------------------------
0xffffffff84e1f22b
hci_send_acl net/bluetooth/hci_core.c:3944
--------------------------------------
0xffffffff84e1f230
hci_send_acl net/bluetooth/hci_core.c:3944
--------------------------------------
0xffffffff84e1f239
hci_send_acl net/bluetooth/hci_core.c:3944
--------------------------------------
0xffffffff84e1ef60
hci_send_acl net/bluetooth/hci_core.c:3920
--------------------------------------
0xffffffff84508b10
skb_push net/core/skbuff.c:1881
--------------------------------------
0xffffffff84508b25
skb_push net/core/skbuff.c:1881
--------------------------------------
0xffffffff84508b32
skb_push net/core/skbuff.c:1881
--------------------------------------
0xffffffff84508b52
skb_push net/core/skbuff.c:1882
--------------------------------------
0xffffffff84508b64
skb_push net/core/skbuff.c:1883
--------------------------------------
0xffffffff84508b72
skb_push net/core/skbuff.c:1885
--------------------------------------
0xffffffff84508b77
skb_push net/core/skbuff.c:1885
--------------------------------------
0xffffffff84e1ef71
hci_send_acl ./include/linux/skbuff.h:2490
--------------------------------------
0xffffffff84e1ef7e
hci_send_acl ./include/linux/skbuff.h:2490
--------------------------------------
0xffffffff84e1ef9e
hci_send_acl ./include/linux/skbuff.h:2490
--------------------------------------
0xffffffff84e1efbe
hci_send_acl ./include/linux/skbuff.h:2490
--------------------------------------
0xffffffff84e1efeb
hci_send_acl net/bluetooth/hci_core.c:3923
--------------------------------------
0xffffffff84e1f011
hci_send_acl net/bluetooth/hci_core.c:3924
--------------------------------------
0xffffffff84e1f01f
hci_send_acl net/bluetooth/hci_core.c:3924
--------------------------------------
0xffffffff84e1f030
hci_send_acl ./include/linux/skbuff.h:1391
--------------------------------------
0xffffffff84e1f045
hci_send_acl ./include/linux/skbuff.h:1391
--------------------------------------
0xffffffff84e1f059
hci_send_acl ./include/linux/skbuff.h:1391
--------------------------------------
0xffffffff84e1f243
hci_send_acl net/bluetooth/hci_core.c:3956
--------------------------------------
0xffffffff84e1f248
hci_send_acl net/bluetooth/hci_core.c:3956
--------------------------------------
0xffffffff845080d0
skb_queue_tail ./include/linux/spinlock.h:328
--------------------------------------
0xffffffff845080e8
skb_queue_tail ./include/linux/spinlock.h:328
--------------------------------------
0xffffffff85675490
_raw_spin_lock_irqsave ./arch/x86/include/asm/paravirt.h:787
--------------------------------------
0xffffffff856754a7
_raw_spin_lock_irqsave ./arch/x86/include/asm/paravirt.h:787
--------------------------------------
0xffffffff856754b1
_raw_spin_lock_irqsave ./arch/x86/include/asm/paravirt.h:765
--------------------------------------
0xffffffff811afa40
native_save_fl arch/x86/kernel/irqflags.S:11
--------------------------------------
0xffffffff856754b8
_raw_spin_lock_irqsave ./arch/x86/include/asm/paravirt.h:765
--------------------------------------
0xffffffff856754c7
_raw_spin_lock_irqsave ./arch/x86/include/asm/paravirt.h:788
--------------------------------------
0xffffffff856754d1
_raw_spin_lock_irqsave ./arch/x86/include/asm/paravirt.h:775
--------------------------------------
0xffffffff8120b8d0
native_irq_disable ./arch/x86/include/asm/irqflags.h:49
--------------------------------------
0xffffffff8120b8d1
native_irq_disable ./arch/x86/include/asm/irqflags.h:49
--------------------------------------
0xffffffff856754d8
_raw_spin_lock_irqsave ./include/linux/spinlock_api_smp.h:108
--------------------------------------
0xffffffff81533930
trace_hardirqs_off kernel/trace/trace_preemptirq.c:76
--------------------------------------
0xffffffff81533942
trace_hardirqs_off kernel/trace/trace_preemptirq.c:76
--------------------------------------
0xffffffff85656b30
lockdep_hardirqs_off ./arch/x86/include/asm/current.h:15
--------------------------------------
0xffffffff85656b93
lockdep_hardirqs_off kernel/locking/lockdep.c:3757
--------------------------------------
0xffffffff8153394b
trace_hardirqs_off kernel/trace/trace_preemptirq.c:78
--------------------------------------
0xffffffff8153395b
trace_hardirqs_off kernel/trace/trace_preemptirq.c:78
--------------------------------------
0xffffffff8153395f
trace_hardirqs_off kernel/trace/trace_preemptirq.c:79
--------------------------------------
0xffffffff81533964
trace_hardirqs_off kernel/trace/trace_preemptirq.c:79
--------------------------------------
0xffffffff81533985
trace_hardirqs_off ./arch/x86/include/asm/preempt.h:26
--------------------------------------
0xffffffff81533999
trace_hardirqs_off kernel/trace/trace_preemptirq.c:82
--------------------------------------
0xffffffff8153399e
trace_hardirqs_off kernel/trace/trace_preemptirq.c:82
--------------------------------------
0xffffffff815339b4
trace_hardirqs_off ./arch/x86/include/asm/jump_label.h:34
--------------------------------------
0xffffffff81533989
trace_hardirqs_off ./arch/x86/include/asm/preempt.h:26
--------------------------------------
0xffffffff8153398e
trace_hardirqs_off ./arch/x86/include/asm/preempt.h:26
--------------------------------------
0xffffffff856754dd
_raw_spin_lock_irqsave ./include/linux/spinlock_api_smp.h:109
--------------------------------------
0xffffffff81382eb0
preempt_count_add kernel/sched/core.c:3870
--------------------------------------
0xffffffff81382ec5
preempt_count_add ./arch/x86/include/asm/preempt.h:79
--------------------------------------
0xffffffff81382ed6
preempt_count_add ./arch/x86/include/asm/preempt.h:26
--------------------------------------
0xffffffff81382ee7
preempt_count_add ./arch/x86/include/asm/preempt.h:26
--------------------------------------
0xffffffff81382efc
preempt_count_add ./include/linux/ftrace.h:816
--------------------------------------
0xffffffff813e4c20
in_lock_functions kernel/locking/spinlock.c:396
--------------------------------------
0xffffffff813e4c2b
in_lock_functions kernel/locking/spinlock.c:396
--------------------------------------
0xffffffff81382f08
preempt_count_add ./include/linux/ftrace.h:818
--------------------------------------
0xffffffff81382f2f
preempt_count_add ./include/linux/ftrace.h:820
--------------------------------------
0xffffffff813e4c20
in_lock_functions kernel/locking/spinlock.c:396
--------------------------------------
0xffffffff813e4c37
in_lock_functions kernel/locking/spinlock.c:396
--------------------------------------
0xffffffff81382f3f
preempt_count_add ./include/linux/ftrace.h:821
--------------------------------------
0xffffffff81382f0c
preempt_count_add ./arch/x86/include/asm/current.h:15
--------------------------------------
0xffffffff81382f22
preempt_count_add ./arch/x86/include/asm/current.h:15
--------------------------------------
0xffffffff856754e7
_raw_spin_lock_irqsave ./include/linux/spinlock_api_smp.h:110
--------------------------------------
0xffffffff813dfae0
lock_acquire kernel/locking/lockdep.c:4931
--------------------------------------
0xffffffff85675503
_raw_spin_lock_irqsave ./include/linux/spinlock_api_smp.h:117
--------------------------------------
0xffffffff813e85c0
do_raw_spin_lock kernel/locking/spinlock_debug.c:111
--------------------------------------
0xffffffff813e8630
do_raw_spin_lock kernel/locking/spinlock_debug.c:112
--------------------------------------
0xffffffff813e8640
do_raw_spin_lock kernel/locking/spinlock_debug.c:84
--------------------------------------
0xffffffff813e864d
do_raw_spin_lock kernel/locking/spinlock_debug.c:84
--------------------------------------
0xffffffff813e8664
do_raw_spin_lock kernel/locking/spinlock_debug.c:85
--------------------------------------
0xffffffff813e8671
do_raw_spin_lock kernel/locking/spinlock_debug.c:85
--------------------------------------
0xffffffff813e8685
do_raw_spin_lock ./include/asm-generic/qspinlock.h:76
--------------------------------------
0xffffffff813e869a
do_raw_spin_lock ./include/linux/instrumented.h:71
--------------------------------------
0xffffffff813e86a8
do_raw_spin_lock ./arch/x86/include/asm/atomic.h:204
--------------------------------------
0xffffffff813e86bd
do_raw_spin_lock kernel/locking/spinlock_debug.c:115
--------------------------------------
0xffffffff813e86cd
do_raw_spin_lock kernel/locking/spinlock_debug.c:91
--------------------------------------
0xffffffff813e86da
do_raw_spin_lock ./arch/x86/include/asm/current.h:15
--------------------------------------
0xffffffff813e870d
do_raw_spin_lock kernel/locking/spinlock_debug.c:92
--------------------------------------
0xffffffff8567550b
_raw_spin_lock_irqsave ./include/linux/spinlock_api_smp.h:121
--------------------------------------
0xffffffff845080f4
skb_queue_tail ./include/linux/spinlock.h:328
--------------------------------------
0xffffffff84508100
skb_queue_tail ./include/linux/skbuff.h:2034
--------------------------------------
0xffffffff8450810c
skb_queue_tail ./include/linux/skbuff.h:1892
--------------------------------------
0xffffffff8450811a
skb_queue_tail ./include/linux/skbuff.h:1893
--------------------------------------
0xffffffff8450812b
skb_queue_tail ./include/linux/skbuff.h:1895(Triggered a new bug: Arbitrary address write)
--------------------------------------
Total 142 basic block