google / kernel-sanitizers

Linux Kernel Sanitizers, fast bug-detectors for the Linux kernel
https://google.github.io/kernel-sanitizers/
436 stars 87 forks source link

Is KASAN working properly? #219

Closed void0red closed 1 year ago

void0red commented 1 year ago

Here is a UAF bug report, however KASAN reports the mem used in ntfs was allocated and freed by tcp module. I don't know if kasan is working properly.

==================================================================
BUG: KASAN: use-after-free in ntfs_lookup_inode_by_name+0x7c/0x3970
Read of size 8 at addr ffff888112fb0800 by task syz-executor.5/5060

CPU: 0 PID: 5060 Comm: syz-executor.5 Not tainted 6.0.1 #54
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0xbe/0xfe
 print_address_description+0x7b/0x440
 print_report+0x11e/0x250
 kasan_report+0xf9/0x130
 ntfs_lookup_inode_by_name+0x7c/0x3970
 ntfs_fill_super+0x872f/0xc840
 mount_bdev+0x274/0x380
 ntfs_mount+0x4b/0x80
 legacy_get_tree+0xe9/0x180
 vfs_get_tree+0x8a/0x250
 do_new_mount+0x1e6/0x9a0
 __se_sys_mount+0x228/0x2d0
 do_syscall_64+0x41/0x90
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7f52e345dece
Code: 48 c7 c0 ff ff ff ff eb aa e8 be 0d 00 00 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 f3 0f 1e fa 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f52e09cde38 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 0000000020000200 RCX: 00007f52e345dece
RDX: 0000000020000000 RSI: 0000000020000100 RDI: 00007f52e09cde90
RBP: 00007f52e09cded0 R08: 00007f52e09cded0 R09: 0000000020000000
R10: 0000000000000000 R11: 0000000000000206 R12: 0000000020000000
R13: 0000000020000100 R14: 00007f52e09cde90 R15: 000000002007a5e0
 </TASK>

Allocated by task 25:
 __kasan_kmalloc+0xc4/0xf0
 __alloc_skb+0x197/0x3f0
 tcp_stream_alloc_skb+0x3e/0x2f0
 tcp_write_xmit+0xe4f/0x5c30
 __tcp_push_pending_frames+0x80/0x2b0
 tcp_rcv_established+0xbff/0x1910
 tcp_v4_do_rcv+0x6e5/0x940
 tcp_v4_rcv+0x1e65/0x2650
 ip_protocol_deliver_rcu+0x2cf/0x650
 ip_local_deliver_finish+0x23c/0x460
 ip_sublist_rcv_finish+0x35d/0x470
 ip_sublist_rcv+0x445/0x470
 ip_list_rcv+0x378/0x3b0
 __netif_receive_skb_list_core+0x7c9/0x7f0
 __netif_receive_skb_list+0x3e2/0x490
 netif_receive_skb_list_internal+0x40e/0x660
 napi_gro_receive+0x3d0/0x6d0
 e1000_clean_rx_irq+0xa78/0x12a0
 e1000_clean+0xc98/0x38a0
 __napi_poll+0xa6/0x3e0
 net_rx_action+0x629/0xea0
 __do_softirq+0x2f8/0x678

Freed by task 25:
 kasan_set_track+0x4c/0x70
 kasan_set_free_info+0x1f/0x40
 ____kasan_slab_free+0x124/0x1a0
 slab_free_freelist_hook+0xda/0x160
 kfree+0xc2/0x1b0
 skb_release_data+0x4c0/0x610
 __kfree_skb+0x4c/0x60
 tcp_ack+0x1ceb/0x5cc0
 tcp_rcv_established+0xb8f/0x1910
 tcp_v4_do_rcv+0x6e5/0x940
 tcp_v4_rcv+0x1e65/0x2650
 ip_protocol_deliver_rcu+0x2cf/0x650
 ip_local_deliver_finish+0x23c/0x460
 ip_sublist_rcv_finish+0x35d/0x470
 ip_sublist_rcv+0x445/0x470
 ip_list_rcv+0x378/0x3b0
 __netif_receive_skb_list_core+0x7c9/0x7f0
 __netif_receive_skb_list+0x3e2/0x490
 netif_receive_skb_list_internal+0x40e/0x660
 napi_complete_done+0x290/0x710
 e1000_clean+0xd01/0x38a0
 __napi_poll+0xa6/0x3e0
 net_rx_action+0x629/0xea0
 __do_softirq+0x2f8/0x678

The buggy address belongs to the object at ffff888112fb0800
 which belongs to the cache kmalloc-1k of size 1024
The buggy address is located 0 bytes inside of
 1024-byte region [ffff888112fb0800, ffff888112fb0c00)

The buggy address belongs to the physical page:
page:0000000037215a89 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x112fb0
head:0000000037215a89 order:3 compound_mapcount:0 compound_pincount:0
flags: 0x200000000010200(slab|head|node=0|zone=2)
raw: 0200000000010200 ffffea00009cd200 dead000000000002 ffff888100041dc0
loop2: detected capacity change from 0 to 4096
raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff888112fb0700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff888112fb0780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff888112fb0800: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                   ^
 ffff888112fb0880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff888112fb0900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
melver commented 1 year ago

This can happen if an object is reused by the slab allocator, and then freed (by the net subsystem), while some pointer (here in ntfs) is still hanging around. Once that memory is dereferenced, KASAN will report the UAF, however, the alloc and free stacks might no longer be related to the original allocation/free.

Either way, invalid memory was accessed.

The sequence could be:

  a = kmalloc(...);  // in ntfs
  kfree(a);
  ...
  b = kmalloc(...);  // in net, where b == a
  kfree(b);
  ...
  *a;  // UAF in ntfs
void0red commented 1 year ago

Thank you for your replay. The log above shows KASAN will only record the latest alloc/free?

melver commented 1 year ago

For any given slab object, yes. Separate objects (i.e. different addresses) have their own alloc/free stacks recorded.

However, normally KASAN places free'd objects into quarantine, to reduce the probability of reporting misleading alloc/free stacks. In the case above I suppose the quarantine was flushed.

void0red commented 1 year ago

Okay, I get it, thank you very much for your patient answer.