netrom: Fix use-after-free caused by accept on already connected socket
Subsystems (2)
PATCH v2 1/1 netrom: Fix use-after-free caused by accept on already connected socket
If listen() and accept() are called on an AF_NETROM socket that has already been connect()ed, accept() succeeds in connecting. This is because nr_accept() dequeues the skb queued in sk->sk_receive_queue in nr_connect().
This causes nr_accept() to allocate and return a sock with the sk of the parent AF_NETROM socket. And here's where use-after-free can happen through complex race conditions:
```
cpu0 cpu1
1. socket_2 = socket(AF_NETROM)
listen(socket_2)
accepted_socket = accept(socket_2) // loopback connection with socket_1
2. socket_1 = socket(AF_NETROM)
nr_create() // sk refcount : 1
connect(socket_1) // loopback connection with socket_2
nr_connect()
nr_establish_data_link()
nr_write_internal()
nr_transmit_buffer()
nr_route_frame()
nr_loopback_queue()
nr_loopback_timer()
nr_rx_frame()
nr_process_rx_frame()
nr_state3_machine()
nr_queue_rx_frame()
sock_queue_rcv_skb()
sock_queue_rcv_skb_reason()
__sock_queue_rcv_skb()
__skb_queue_tail(list, skb); // list : sk->sk_receive_queue
3. listen(socket_1)
nr_listen()
uaf_socket = accept(socket_1)
nr_accept()
skb_dequeue(&sk->sk_receive_queue);
4. close(accepted_socket)
nr_release()
nr_write_internal(sk, NR_DISCREQ)
nr_transmit_buffer() // NR_DISCREQ
nr_route_frame()
nr_loopback_queue()
nr_loopback_timer()
nr_rx_frame() // sk : socket_1's sk
nr_process_rx_frame() // NR_STATE_3
nr_state3_machine() // NR_DISCREQ
nr_disconnect()
nr_sk(sk)->state = NR_STATE_0;
5. close(socket_1) // sk refcount : 3
nr_release() // NR_STATE_0
sock_put(sk); // sk refcount : 0
sk_free(sk);
close(uaf_socket)
nr_release()
sock_hold(sk); // UAF
```KASAN report by syzbot:
``` BUG: KASAN: use-after-free in nr_release+0x66/0x460 net/netrom/af_netrom.c:520 Write of size 4 at addr ffff8880235d8080 by task syz-executor564/5128 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:306 [inline] print_report+0x15e/0x461 mm/kasan/report.c:417 kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 check_region_inline mm/kasan/generic.c:183 [inline] kasan_check_range+0x141/0x190 mm/kasan/generic.c:189 instrument_atomic_read_write include/linux/instrumented.h:102 [inline] atomic_fetch_add_relaxed include/linux/atomic/atomic-instrumented.h:116 [inline] __refcount_add include/linux/refcount.h:193 [inline] __refcount_inc include/linux/refcount.h:250 [inline] refcount_inc include/linux/refcount.h:267 [inline] sock_hold include/net/sock.h:775 [inline] nr_release+0x66/0x460 net/netrom/af_netrom.c:520 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f6c19e3c9b9 Code: Unable to access opcode bytes at 0x7f6c19e3c98f. RSP: 002b:00007fffd4ba2ce8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: 0000000000000116 RBX: 0000000000000003 RCX: 00007f6c19e3c9b9 RDX: 0000000000000318 RSI: 00000000200bd000 RDI: 0000000000000006 RBP: 0000000000000003 R08: 000000000000000d R09: 000000000000000d R10: 0000000000000000 R11: 0000000000000246 R12: 000055555566a2c0 R13: 0000000000000011 R14: 0000000000000000 R15: 0000000000000000 </TASK> Allocated by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:371 [inline] ____kasan_kmalloc mm/kasan/common.c:330 [inline] __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380 kasan_kmalloc include/linux/kasan.h:211 [inline] __do_kmalloc_node mm/slab_common.c:968 [inline] __kmalloc+0x5a/0xd0 mm/slab_common.c:981 kmalloc include/linux/slab.h:584 [inline] sk_prot_alloc+0x140/0x290 net/core/sock.c:2038 sk_alloc+0x3a/0x7a0 net/core/sock.c:2091 nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433 __sock_create+0x359/0x790 net/socket.c:1515 sock_create net/socket.c:1566 [inline] __sys_socket_create net/socket.c:1603 [inline] __sys_socket_create net/socket.c:1588 [inline] __sys_socket+0x133/0x250 net/socket.c:1636 __do_sys_socket net/socket.c:1649 [inline] __se_sys_socket net/socket.c:1647 [inline] __x64_sys_socket+0x73/0xb0 net/socket.c:1647 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Freed by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] __cache_free mm/slab.c:3394 [inline] __do_kmem_cache_free mm/slab.c:3580 [inline] __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_release+0x39e/0x460 net/netrom/af_netrom.c:554 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd ```
To fix this problem, nr_listen() returns -EINVAL for sockets that successfully nr_connect().
--- net/netrom/af_netrom.c | 5 +++++ 1 file changed, 5 insertions(+)
net/netrom/af_netrom.c +5 -0
@@ -400,6 +400,11 @@ static int nr_listen(struct socket *sock, int backlog)struct sock *sk = sock->sk;lock_sock (sk); +if (sock->state !=SS_UNCONNECTED ) { +release_sock (sk); +return -EINVAL ; + } +if (sk->sk_state !=TCP_LISTEN ) {memset (&nr_sk (sk)->user_addr,0 ,AX25_ADDR_LEN ); sk->sk_max_ack_backlog = backlog;
Signature · 1 line
2.25.1
Hi,
I think the diff looks good but changelog is not correct.
From: Hyunwoo Kim <[email protected]> Date: Mon, 23 Jan 2023 09:22:33 -0800
Quoted 4 lines
If
listen()andaccept()are called on anAF_NETROMsocket that has already been connect()ed,accept()succeeds in connecting. This is becausenr_accept()dequeues the skb queued insk->sk_receive_queueinnr_connect().
This sentence is misleading. The skb sent by nr_connect() is queued up for the peer's sk_receive_queue (socket_2 below), and also the reply is not queued for connect()er (socket_1) because it is NR_CONNACK and just consumed by nr_state1_machine() to transition to NR_STATE_3 and TCP_ESTABLISHED.
Quoted 3 lines
This causes
nr_accept()to allocate and return a sock with the sk of the parentAF_NETROMsocket.
This happens because the peer (socket_2) sends some data by nr_sendmsg(), whose type is NR_INFO and the data is queued up for the connect()er's (socket_1) sk_receive_queue by
- nr_state3_machine
- nr_queue_rx_frame
- sock_queue_rcv_skb
Quoted 5 lines
And here's where use-after-free
can happen through complex race conditions:
```
cpu0 cpu1
1.socket_2=socket(AF_NETROM)
Quoted 8 lines
listen(socket_2)
accepted_socket=accept(socket_2)// loopback connection withsocket_1
2.socket_1=socket(AF_NETROM)
nr_create()// sk refcount : 1
connect(socket_1)// loopback connection withsocket_2
nr_connect()
nr_establish_data_link()
nr_write_internal()
This is NR_CONNREQ for socket_2.
Quoted 6 lines
nr_transmit_buffer()
nr_route_frame()
nr_loopback_queue()
nr_loopback_timer()
nr_rx_frame()
nr_process_rx_frame()So, nr_process_rx_frame() is not called from nr_rx_frame() because the kernel finds socket_2 by nr_find_listener(), and creates accepted_socket, and then responds with NR_CONNACK to socket_1.
And accepted_socket sends some data with NR_INFO, then, nr_state3_machine() is called for socket_1 and the skb with sk pointing socket_1 is queued for socket_1's sk_receive_queue.
I think this part is lacking in this UAF scenario.
What do you think ?
Quoted 5 lines
nr_state3_machine()
nr_queue_rx_frame()
sock_queue_rcv_skb()
sock_queue_rcv_skb_reason()
__sock_queue_rcv_skb()Quoted 8 lines
__skb_queue_tail(list, skb); // list : sk->sk_receive_queue
3. listen(socket_1)
nr_listen()
uaf_socket = accept(socket_1)
nr_accept()
skb_dequeue(&sk->sk_receive_queue);
4. close(accepted_socket)And I guess this close() is not so important in this case. Even if we don't close the socket cleanly, the UAF will happen, right ? (it might be caused in a different place like timer though)
Quoted 152 lines
nr_release()nr_write_internal(sk, NR_DISCREQ)
nr_transmit_buffer()//NR_DISCREQ
nr_route_frame()nr_loopback_queue()nr_loopback_timer()
nr_rx_frame()// sk : socket_1's sk
nr_process_rx_frame()//NR_STATE_3
nr_state3_machine()//NR_DISCREQ
nr_disconnect()nr_sk(sk)->state =NR_STATE_0;
5.close(socket_1)// sk refcount : 3
nr_release()//NR_STATE_0
sock_put(sk); // sk refcount : 0
sk_free(sk);
close(uaf_socket)
nr_release()
sock_hold(sk); // UAF``` KASAN report by syzbot: ``` BUG: KASAN: use-after-free in nr_release+0x66/0x460 net/netrom/af_netrom.c:520 Write of size 4 at addr ffff8880235d8080 by task syz-executor564/5128 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:306 [inline] print_report+0x15e/0x461 mm/kasan/report.c:417 kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 check_region_inline mm/kasan/generic.c:183 [inline] kasan_check_range+0x141/0x190 mm/kasan/generic.c:189 instrument_atomic_read_write include/linux/instrumented.h:102 [inline] atomic_fetch_add_relaxed include/linux/atomic/atomic-instrumented.h:116 [inline] __refcount_add include/linux/refcount.h:193 [inline] __refcount_inc include/linux/refcount.h:250 [inline] refcount_inc include/linux/refcount.h:267 [inline] sock_hold include/net/sock.h:775 [inline] nr_release+0x66/0x460 net/netrom/af_netrom.c:520 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f6c19e3c9b9 Code: Unable to access opcode bytes at 0x7f6c19e3c98f. RSP: 002b:00007fffd4ba2ce8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: 0000000000000116 RBX: 0000000000000003 RCX: 00007f6c19e3c9b9 RDX: 0000000000000318 RSI: 00000000200bd000 RDI: 0000000000000006 RBP: 0000000000000003 R08: 000000000000000d R09: 000000000000000d R10: 0000000000000000 R11: 0000000000000246 R12: 000055555566a2c0 R13: 0000000000000011 R14: 0000000000000000 R15: 0000000000000000 </TASK> Allocated by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:371 [inline] ____kasan_kmalloc mm/kasan/common.c:330 [inline] __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380 kasan_kmalloc include/linux/kasan.h:211 [inline] __do_kmalloc_node mm/slab_common.c:968 [inline] __kmalloc+0x5a/0xd0 mm/slab_common.c:981 kmalloc include/linux/slab.h:584 [inline] sk_prot_alloc+0x140/0x290 net/core/sock.c:2038 sk_alloc+0x3a/0x7a0 net/core/sock.c:2091 nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433 __sock_create+0x359/0x790 net/socket.c:1515 sock_create net/socket.c:1566 [inline] __sys_socket_create net/socket.c:1603 [inline] __sys_socket_create net/socket.c:1588 [inline] __sys_socket+0x133/0x250 net/socket.c:1636 __do_sys_socket net/socket.c:1649 [inline] __se_sys_socket net/socket.c:1647 [inline] __x64_sys_socket+0x73/0xb0 net/socket.c:1647 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Freed by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] __cache_free mm/slab.c:3394 [inline] __do_kmem_cache_free mm/slab.c:3580 [inline] __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_release+0x39e/0x460 net/netrom/af_netrom.c:554 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd```
To fix this problem,
nr_listen()returns-EINVALfor sockets that successfullynr_connect().Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")Reported-by [email protected]Signed-off-by Hyunwoo Kim <[email protected]>--- net/netrom/af_netrom.c | 5 +++++ 1 file changed, 5 insertions(+)net/netrom/af_netrom.c +5
-0@@ -400,6 +400,11 @@ static int nr_listen(struct socket *sock, int backlog)struct sock *sk = sock->sk;lock_sock (sk); +if (sock->state !=SS_UNCONNECTED ) { +release_sock (sk); +return -EINVAL ; + } +if (sk->sk_state !=TCP_LISTEN ) {memset (&nr_sk (sk)->user_addr,0 ,AX25_ADDR_LEN ); sk->sk_max_ack_backlog = backlog;Signature · 1 line
2.25.1
Quoted 22 lines · Kuniyuki Iwashima
Hi,
I think the diff looks good but changelog is not correct.
From: Hyunwoo Kim <[email protected]> Date: Mon, 23 Jan 2023 09:22:33 -0800Quoted 4 lines
If
listen()andaccept()are called on anAF_NETROMsocket that has already been connect()ed,accept()succeeds in connecting. This is becausenr_accept()dequeues the skb queued insk->sk_receive_queueinnr_connect().This sentence is misleading. The skb sent by
nr_connect()is queued up for the peer'ssk_receive_queue(socket_2below), and also the reply is not queued for connect()er (socket_1) because it isNR_CONNACKand just consumed bynr_state1_machine()to transition toNR_STATE_3andTCP_ESTABLISHED.Quoted 3 lines
This causes
nr_accept()to allocate and return a sock with the sk of the parentAF_NETROMsocket.
Quoted 7 lines
This happens because the peer (
socket_2) sends some data bynr_sendmsg(), whose type isNR_INFOand the data is queued up for the connect()er's (socket_1)sk_receive_queueby-
nr_state3_machine
-nr_queue_rx_frame
-sock_queue_rcv_skb
you're right.
I misanalyzed nr_rx_frame(). sorry.
Quoted 53 lines
Quoted 15 lines
And here's where use-after-free
can happen through complex race conditions:
```
cpu0 cpu1
1.socket_2=socket(AF_NETROM)listen(socket_2)
accepted_socket=accept(socket_2)// loopback connection withsocket_1
2.socket_1=socket(AF_NETROM)
nr_create()// sk refcount : 1
connect(socket_1)// loopback connection withsocket_2
nr_connect()
nr_establish_data_link()
nr_write_internal()This is
NR_CONNREQforsocket_2.Quoted 6 lines
nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() nr_process_rx_frame()So,
nr_process_rx_frame()is not called fromnr_rx_frame()because the kernel findssocket_2bynr_find_listener(), and createsaccepted_socket, and then responds withNR_CONNACKtosocket_1.And
accepted_socketsends some data withNR_INFO, then,nr_state3_machine()is called forsocket_1and the skb with sk pointingsocket_1is queued for socket_1'ssk_receive_queue.I think this part is lacking in this UAF scenario.
What do you think ?
Quoted 5 lines
nr_state3_machine() nr_queue_rx_frame() sock_queue_rcv_skb() sock_queue_rcv_skb_reason() __sock_queue_rcv_skb()Quoted 8 lines
__skb_queue_tail(list, skb); // list : sk->sk_receive_queue 3. listen(socket_1) nr_listen() uaf_socket = accept(socket_1) nr_accept() skb_dequeue(&sk->sk_receive_queue); 4. close(accepted_socket)
Quoted 3 lines
And I guess this
close()is not so important in this case. Even if we don't close the socket cleanly, the UAF will happen, right ? (it might be caused in a different place like timer though)
IMHO, I think this close(accepted_socket) is a necessary procedure.
This is because case NR_STATE_3: in nr_release() is executed here,
and nr_write_internal(sk, NR_DISCREQ) ~ nr_disconnect() sets socket_1's sk to NR_STATE_0. If sk of socket_1 is not set to NR_STATE_0, case NR_STATE_3: is executed instead of case NR_STATE_0: in close(socket_1) and sk is not released.
This means you will not be able to trigger UAF on close(uaf_socket).
What do you think?
So the modified flow chart looks like this:
```
cpu0 cpu1
1. socket_2 = socket(AF_NETROM)
.
.
listen(socket_2)
accepted_socket = accept(socket_2)
2. socket_1 = socket(AF_NETROM)
nr_create() // sk refcount : 1
connect(socket_1)
nr_connect()
nr_establish_data_link()
nr_write_internal()
nr_transmit_buffer()
nr_route_frame()
nr_loopback_queue()
nr_loopback_timer()
nr_rx_frame()
nr_process_rx_frame()
nr_state1_machine()
nr->state = NR_STATE_3;
3. write(accepted_socket)
nr_sendmsg()
nr_output()
nr_kick()
nr_send_iframe()
nr_transmit_buffer()
nr_route_frame()
nr_loopback_queue()
nr_loopback_timer()
nr_process_rx_frame(sk, skb); // sk : socket_1's sk
nr_state3_machine()
nr_queue_rx_frame()
sock_queue_rcv_skb()
sock_queue_rcv_skb_reason()
__sock_queue_rcv_skb()
__skb_queue_tail(list, skb); // list : socket_1's sk->sk_receive_queue
4. listen(socket_1)
nr_listen()
uaf_socket = accept(socket_1)
nr_accept()
skb_dequeue(&sk->sk_receive_queue);
5. close(accepted_socket)
nr_release()
nr_write_internal(sk, NR_DISCREQ)
nr_transmit_buffer() // NR_DISCREQ
nr_route_frame()
nr_loopback_queue()
nr_loopback_timer()
nr_rx_frame() // sk : socket_1's sk
nr_process_rx_frame() // NR_STATE_3
nr_state3_machine() // NR_DISCREQ
nr_disconnect()
nr_sk(sk)->state = NR_STATE_0;
6. close(socket_1) // sk refcount : 3
nr_release() // NR_STATE_0
sock_put(sk); // sk refcount : 0
sk_free(sk);
close(uaf_socket)
nr_release()
sock_hold(sk); // UAF
```Anything wrong?
Quoted 153 lines
Quoted 153 lines
nr_release()nr_write_internal(sk, NR_DISCREQ)
nr_transmit_buffer()//NR_DISCREQ
nr_route_frame()nr_loopback_queue()nr_loopback_timer()
nr_rx_frame()// sk : socket_1's sk
nr_process_rx_frame()//NR_STATE_3
nr_state3_machine()//NR_DISCREQ
nr_disconnect()nr_sk(sk)->state =NR_STATE_0;
5.close(socket_1)// sk refcount : 3
nr_release()//NR_STATE_0
sock_put(sk); // sk refcount : 0
sk_free(sk);
close(uaf_socket)
nr_release()
sock_hold(sk); // UAF``` KASAN report by syzbot: ``` BUG: KASAN: use-after-free in nr_release+0x66/0x460 net/netrom/af_netrom.c:520 Write of size 4 at addr ffff8880235d8080 by task syz-executor564/5128 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:306 [inline] print_report+0x15e/0x461 mm/kasan/report.c:417 kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 check_region_inline mm/kasan/generic.c:183 [inline] kasan_check_range+0x141/0x190 mm/kasan/generic.c:189 instrument_atomic_read_write include/linux/instrumented.h:102 [inline] atomic_fetch_add_relaxed include/linux/atomic/atomic-instrumented.h:116 [inline] __refcount_add include/linux/refcount.h:193 [inline] __refcount_inc include/linux/refcount.h:250 [inline] refcount_inc include/linux/refcount.h:267 [inline] sock_hold include/net/sock.h:775 [inline] nr_release+0x66/0x460 net/netrom/af_netrom.c:520 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f6c19e3c9b9 Code: Unable to access opcode bytes at 0x7f6c19e3c98f. RSP: 002b:00007fffd4ba2ce8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: 0000000000000116 RBX: 0000000000000003 RCX: 00007f6c19e3c9b9 RDX: 0000000000000318 RSI: 00000000200bd000 RDI: 0000000000000006 RBP: 0000000000000003 R08: 000000000000000d R09: 000000000000000d R10: 0000000000000000 R11: 0000000000000246 R12: 000055555566a2c0 R13: 0000000000000011 R14: 0000000000000000 R15: 0000000000000000 </TASK> Allocated by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:371 [inline] ____kasan_kmalloc mm/kasan/common.c:330 [inline] __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380 kasan_kmalloc include/linux/kasan.h:211 [inline] __do_kmalloc_node mm/slab_common.c:968 [inline] __kmalloc+0x5a/0xd0 mm/slab_common.c:981 kmalloc include/linux/slab.h:584 [inline] sk_prot_alloc+0x140/0x290 net/core/sock.c:2038 sk_alloc+0x3a/0x7a0 net/core/sock.c:2091 nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433 __sock_create+0x359/0x790 net/socket.c:1515 sock_create net/socket.c:1566 [inline] __sys_socket_create net/socket.c:1603 [inline] __sys_socket_create net/socket.c:1588 [inline] __sys_socket+0x133/0x250 net/socket.c:1636 __do_sys_socket net/socket.c:1649 [inline] __se_sys_socket net/socket.c:1647 [inline] __x64_sys_socket+0x73/0xb0 net/socket.c:1647 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Freed by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] __cache_free mm/slab.c:3394 [inline] __do_kmem_cache_free mm/slab.c:3580 [inline] __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_release+0x39e/0x460 net/netrom/af_netrom.c:554 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd```
To fix this problem,
nr_listen()returns-EINVALfor sockets that successfullynr_connect().Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")Reported-by [email protected]Signed-off-by Hyunwoo Kim <[email protected]>--- net/netrom/af_netrom.c | 5 +++++ 1 file changed, 5 insertions(+)net/netrom/af_netrom.c +5
-0@@ -400,6 +400,11 @@ static int nr_listen(struct socket *sock, int backlog)struct sock *sk = sock->sk;lock_sock (sk); +if (sock->state !=SS_UNCONNECTED ) { +release_sock (sk); +return -EINVAL ; + } +if (sk->sk_state !=TCP_LISTEN ) {memset (&nr_sk (sk)->user_addr,0 ,AX25_ADDR_LEN ); sk->sk_max_ack_backlog = backlog;Signature · 1 line
2.25.1
From: Hyunwoo Kim <[email protected]> Date: Wed, 25 Jan 2023 01:17:10 -0800
Quoted 91 lines · Kuniyuki Iwashima
Quoted 22 lines
Hi,
I think the diff looks good but changelog is not correct.
From: Hyunwoo Kim <[email protected]> Date: Mon, 23 Jan 2023 09:22:33 -0800Quoted 4 lines
If
listen()andaccept()are called on anAF_NETROMsocket that has already been connect()ed,accept()succeeds in connecting. This is becausenr_accept()dequeues the skb queued insk->sk_receive_queueinnr_connect().This sentence is misleading. The skb sent by
nr_connect()is queued up for the peer'ssk_receive_queue(socket_2below), and also the reply is not queued for connect()er (socket_1) because it isNR_CONNACKand just consumed bynr_state1_machine()to transition toNR_STATE_3andTCP_ESTABLISHED.Quoted 3 lines
This causes
nr_accept()to allocate and return a sock with the sk of the parentAF_NETROMsocket.Quoted 7 lines
This happens because the peer (
socket_2) sends some data bynr_sendmsg(), whose type isNR_INFOand the data is queued up for the connect()er's (socket_1)sk_receive_queueby-
nr_state3_machine
-nr_queue_rx_frame
-sock_queue_rcv_skbyou're right.
I misanalyzednr_rx_frame(). sorry.Quoted 53 lines
Quoted 15 lines
And here's where use-after-free
can happen through complex race conditions:
```
cpu0 cpu1
1.socket_2=socket(AF_NETROM)listen(socket_2)
accepted_socket=accept(socket_2)// loopback connection withsocket_1
2.socket_1=socket(AF_NETROM)
nr_create()// sk refcount : 1
connect(socket_1)// loopback connection withsocket_2
nr_connect()
nr_establish_data_link()
nr_write_internal()This is
NR_CONNREQforsocket_2.Quoted 6 lines
nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() nr_process_rx_frame()So,
nr_process_rx_frame()is not called fromnr_rx_frame()because the kernel findssocket_2bynr_find_listener(), and createsaccepted_socket, and then responds withNR_CONNACKtosocket_1.And
accepted_socketsends some data withNR_INFO, then,nr_state3_machine()is called forsocket_1and the skb with sk pointingsocket_1is queued for socket_1'ssk_receive_queue.I think this part is lacking in this UAF scenario.
What do you think ?
Quoted 5 lines
nr_state3_machine() nr_queue_rx_frame() sock_queue_rcv_skb() sock_queue_rcv_skb_reason() __sock_queue_rcv_skb()Quoted 8 lines
__skb_queue_tail(list, skb); // list : sk->sk_receive_queue 3. listen(socket_1) nr_listen() uaf_socket = accept(socket_1) nr_accept() skb_dequeue(&sk->sk_receive_queue); 4. close(accepted_socket)Quoted 3 lines
And I guess this
close()is not so important in this case. Even if we don't close the socket cleanly, the UAF will happen, right ? (it might be caused in a different place like timer though)
Quoted 5 lines
IMHO, I think this
close(accepted_socket)is a necessary procedure.
This is becausecase NR_STATE_3:innr_release()is executed here,
andnr_write_internal(sk, NR_DISCREQ)~nr_disconnect()sets socket_1's sk toNR_STATE_0. If sk ofsocket_1is not set toNR_STATE_0,case NR_STATE_3:is executed instead ofcase NR_STATE_0:inclose(socket_1)and sk is not released.
No, it's released by the heartbeat timer. The heartbeat timer finally calls nr_destroy_socket() as SOCK_DESTROY is flagged to the sk.
Quoted 1 line
This means you will not be able to trigger UAF on
close(uaf_socket).
I didn't say close(uaf_socket) is not needed, I mean we can trigger UAF without close(__accepted_socket__).
Quoted 17 lines
What do you think?
So the modified flow chart looks like this:
```cpu0 cpu1 1. socket_2 = socket(AF_NETROM) . . listen(socket_2) accepted_socket = accept(socket_2) 2. socket_1 = socket(AF_NETROM) nr_create() // sk refcount : 1 connect(socket_1) nr_connect() nr_establish_data_link() nr_write_internal()
Quoted 8 lines
nr_transmit_buffer()
nr_route_frame()
nr_loopback_queue()
nr_loopback_timer()
nr_rx_frame()
nr_process_rx_frame()
nr_state1_machine()
nr->state = NR_STATE_3;If you write the connect()'s stack trace, you should note the state change at the socket_1 side by NR_CONNACK. The NR_STATE_3 here is for socket_2 by NR_CONNREQ. We don't need the details of socket_2.
Otherwise, you should just write connect(socket_1) only like the step 1 (socket(), listen() etc).
Quoted 198 lines
3. write(accepted_socket) nr_sendmsg() nr_output() nr_kick() nr_send_iframe() nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_process_rx_frame(sk, skb); // sk : socket_1's sk nr_state3_machine() nr_queue_rx_frame() sock_queue_rcv_skb() sock_queue_rcv_skb_reason() __sock_queue_rcv_skb() __skb_queue_tail(list, skb); // list : socket_1's sk->sk_receive_queue 4. listen(socket_1) nr_listen() uaf_socket = accept(socket_1) nr_accept() skb_dequeue(&sk->sk_receive_queue); 5. close(accepted_socket) nr_release() nr_write_internal(sk, NR_DISCREQ) nr_transmit_buffer() // NR_DISCREQ nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() // sk : socket_1's sk nr_process_rx_frame() // NR_STATE_3 nr_state3_machine() // NR_DISCREQ nr_disconnect() nr_sk(sk)->state = NR_STATE_0; 6. close(socket_1) // sk refcount : 3 nr_release() // NR_STATE_0 sock_put(sk); // sk refcount : 0 sk_free(sk); close(uaf_socket) nr_release() sock_hold(sk); // UAF```
Anything wrong?
Quoted 153 lines
Quoted 153 lines
nr_release()nr_write_internal(sk, NR_DISCREQ)
nr_transmit_buffer()//NR_DISCREQ
nr_route_frame()nr_loopback_queue()nr_loopback_timer()
nr_rx_frame()// sk : socket_1's sk
nr_process_rx_frame()//NR_STATE_3
nr_state3_machine()//NR_DISCREQ
nr_disconnect()nr_sk(sk)->state =NR_STATE_0;
5.close(socket_1)// sk refcount : 3
nr_release()//NR_STATE_0
sock_put(sk); // sk refcount : 0
sk_free(sk);
close(uaf_socket)
nr_release()
sock_hold(sk); // UAF``` KASAN report by syzbot: ``` BUG: KASAN: use-after-free in nr_release+0x66/0x460 net/netrom/af_netrom.c:520 Write of size 4 at addr ffff8880235d8080 by task syz-executor564/5128 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:306 [inline] print_report+0x15e/0x461 mm/kasan/report.c:417 kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 check_region_inline mm/kasan/generic.c:183 [inline] kasan_check_range+0x141/0x190 mm/kasan/generic.c:189 instrument_atomic_read_write include/linux/instrumented.h:102 [inline] atomic_fetch_add_relaxed include/linux/atomic/atomic-instrumented.h:116 [inline] __refcount_add include/linux/refcount.h:193 [inline] __refcount_inc include/linux/refcount.h:250 [inline] refcount_inc include/linux/refcount.h:267 [inline] sock_hold include/net/sock.h:775 [inline] nr_release+0x66/0x460 net/netrom/af_netrom.c:520 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f6c19e3c9b9 Code: Unable to access opcode bytes at 0x7f6c19e3c98f. RSP: 002b:00007fffd4ba2ce8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: 0000000000000116 RBX: 0000000000000003 RCX: 00007f6c19e3c9b9 RDX: 0000000000000318 RSI: 00000000200bd000 RDI: 0000000000000006 RBP: 0000000000000003 R08: 000000000000000d R09: 000000000000000d R10: 0000000000000000 R11: 0000000000000246 R12: 000055555566a2c0 R13: 0000000000000011 R14: 0000000000000000 R15: 0000000000000000 </TASK> Allocated by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:371 [inline] ____kasan_kmalloc mm/kasan/common.c:330 [inline] __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380 kasan_kmalloc include/linux/kasan.h:211 [inline] __do_kmalloc_node mm/slab_common.c:968 [inline] __kmalloc+0x5a/0xd0 mm/slab_common.c:981 kmalloc include/linux/slab.h:584 [inline] sk_prot_alloc+0x140/0x290 net/core/sock.c:2038 sk_alloc+0x3a/0x7a0 net/core/sock.c:2091 nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433 __sock_create+0x359/0x790 net/socket.c:1515 sock_create net/socket.c:1566 [inline] __sys_socket_create net/socket.c:1603 [inline] __sys_socket_create net/socket.c:1588 [inline] __sys_socket+0x133/0x250 net/socket.c:1636 __do_sys_socket net/socket.c:1649 [inline] __se_sys_socket net/socket.c:1647 [inline] __x64_sys_socket+0x73/0xb0 net/socket.c:1647 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Freed by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] __cache_free mm/slab.c:3394 [inline] __do_kmem_cache_free mm/slab.c:3580 [inline] __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_release+0x39e/0x460 net/netrom/af_netrom.c:554 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd```
To fix this problem,
nr_listen()returns-EINVALfor sockets that successfullynr_connect().Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")Reported-by [email protected]Signed-off-by Hyunwoo Kim <[email protected]>--- net/netrom/af_netrom.c | 5 +++++ 1 file changed, 5 insertions(+)net/netrom/af_netrom.c +5
-0@@ -400,6 +400,11 @@ static int nr_listen(struct socket *sock, int backlog)struct sock *sk = sock->sk;lock_sock (sk); +if (sock->state !=SS_UNCONNECTED ) { +release_sock (sk); +return -EINVAL ; + } +if (sk->sk_state !=TCP_LISTEN ) {memset (&nr_sk (sk)->user_addr,0 ,AX25_ADDR_LEN ); sk->sk_max_ack_backlog = backlog;Signature · 1 line
2.25.1
Quoted 99 lines · Kuniyuki Iwashima
From: Hyunwoo Kim <[email protected]> Date: Wed, 25 Jan 2023 01:17:10 -0800Quoted 91 lines · Kuniyuki Iwashima
Quoted 22 lines
Hi,
I think the diff looks good but changelog is not correct.
From: Hyunwoo Kim <[email protected]> Date: Mon, 23 Jan 2023 09:22:33 -0800Quoted 4 lines
If
listen()andaccept()are called on anAF_NETROMsocket that has already been connect()ed,accept()succeeds in connecting. This is becausenr_accept()dequeues the skb queued insk->sk_receive_queueinnr_connect().This sentence is misleading. The skb sent by
nr_connect()is queued up for the peer'ssk_receive_queue(socket_2below), and also the reply is not queued for connect()er (socket_1) because it isNR_CONNACKand just consumed bynr_state1_machine()to transition toNR_STATE_3andTCP_ESTABLISHED.Quoted 3 lines
This causes
nr_accept()to allocate and return a sock with the sk of the parentAF_NETROMsocket.Quoted 7 lines
This happens because the peer (
socket_2) sends some data bynr_sendmsg(), whose type isNR_INFOand the data is queued up for the connect()er's (socket_1)sk_receive_queueby-
nr_state3_machine
-nr_queue_rx_frame
-sock_queue_rcv_skbyou're right.
I misanalyzednr_rx_frame(). sorry.Quoted 53 lines
Quoted 15 lines
And here's where use-after-free
can happen through complex race conditions:
```
cpu0 cpu1
1.socket_2=socket(AF_NETROM)listen(socket_2)
accepted_socket=accept(socket_2)// loopback connection withsocket_1
2.socket_1=socket(AF_NETROM)
nr_create()// sk refcount : 1
connect(socket_1)// loopback connection withsocket_2
nr_connect()
nr_establish_data_link()
nr_write_internal()This is
NR_CONNREQforsocket_2.Quoted 6 lines
nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() nr_process_rx_frame()So,
nr_process_rx_frame()is not called fromnr_rx_frame()because the kernel findssocket_2bynr_find_listener(), and createsaccepted_socket, and then responds withNR_CONNACKtosocket_1.And
accepted_socketsends some data withNR_INFO, then,nr_state3_machine()is called forsocket_1and the skb with sk pointingsocket_1is queued for socket_1'ssk_receive_queue.I think this part is lacking in this UAF scenario.
What do you think ?
Quoted 5 lines
nr_state3_machine() nr_queue_rx_frame() sock_queue_rcv_skb() sock_queue_rcv_skb_reason() __sock_queue_rcv_skb()Quoted 8 lines
__skb_queue_tail(list, skb); // list : sk->sk_receive_queue 3. listen(socket_1) nr_listen() uaf_socket = accept(socket_1) nr_accept() skb_dequeue(&sk->sk_receive_queue); 4. close(accepted_socket)Quoted 3 lines
And I guess this
close()is not so important in this case. Even if we don't close the socket cleanly, the UAF will happen, right ? (it might be caused in a different place like timer though)Quoted 5 lines
IMHO, I think this
close(accepted_socket)is a necessary procedure.
This is becausecase NR_STATE_3:innr_release()is executed here,
andnr_write_internal(sk, NR_DISCREQ)~nr_disconnect()sets socket_1's sk toNR_STATE_0. If sk ofsocket_1is not set toNR_STATE_0,case NR_STATE_3:is executed instead ofcase NR_STATE_0:inclose(socket_1)and sk is not released.
Quoted 8 lines
No, it's released by the heartbeat timer. The heartbeat timer finally calls
nr_destroy_socket()asSOCK_DESTROYis flagged to the sk.Quoted 1 line
This means you will not be able to trigger UAF on
close(uaf_socket).I didn't say
close(uaf_socket)is not needed, I mean we can trigger UAF withoutclose(__accepted_socket__).
ok. understand. The reason why I put close(accepted_socket) is because Freed by task in the KASAN log I attached to the patch description is as follows:
``` Freed by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] __cache_free mm/slab.c:3394 [inline] __do_kmem_cache_free mm/slab.c:3580 [inline] __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_release+0x39e/0x460 net/netrom/af_netrom.c:554 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd ```
If, as you say, heartbeat is running and UAF is triggered, the KASAN Freed log will look like this:
``` Freed by task 14094: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2e/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x160/0x1c0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] slab_free_hook mm/slub.c:1781 [inline] slab_free_freelist_hook+0x8b/0x1c0 mm/slub.c:1807 slab_free mm/slub.c:3787 [inline] __kmem_cache_free+0xaf/0x3b0 mm/slub.c:3800 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_heartbeat_expiry+0x1d7/0x460 net/netrom/nr_timer.c:148 call_timer_fn+0x1da/0x7c0 kernel/time/timer.c:1700 expire_timers+0x2c6/0x5c0 kernel/time/timer.c:1751 __run_timers kernel/time/timer.c:2022 [inline] __run_timers kernel/time/timer.c:1995 [inline] run_timer_softirq+0x326/0x910 kernel/time/timer.c:2035 __do_softirq+0x1fb/0xadc kernel/softirq.c:571 ```
Anyway, I'm trying to keep close(accepted_socket) in the flow chart because the KASAN log I added to the first patch description is the first one.
Quoted 28 lines
Quoted 19 lines
What do you think?
So the modified flow chart looks like this:
```cpu0 cpu1 1. socket_2 = socket(AF_NETROM) . . listen(socket_2) accepted_socket = accept(socket_2) 2. socket_1 = socket(AF_NETROM) nr_create() // sk refcount : 1 connect(socket_1) nr_connect() nr_establish_data_link() nr_write_internal()Quoted 8 lines
nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() nr_process_rx_frame() nr_state1_machine() nr->state = NR_STATE_3;
Quoted 6 lines
If you write the connect()'s stack trace, you should note the state change at the
socket_1side byNR_CONNACK. TheNR_STATE_3here is forsocket_2byNR_CONNREQ. We don't need the details ofsocket_2.Otherwise, you should just write
connect(socket_1)only like the step 1 (socket(),listen()etc).
So, the modified flow chart is:
```
cpu0 cpu1
1. socket_2 = socket(AF_NETROM)
.
.
listen(socket_2)
accepted_socket = accept(socket_2)
2. socket_1 = socket(AF_NETROM)
nr_create() // sk refcount : 1
connect(socket_1)
3. write(accepted_socket)
nr_sendmsg()
nr_output()
nr_kick()
nr_send_iframe()
nr_transmit_buffer()
nr_route_frame()
nr_loopback_queue()
nr_loopback_timer()
nr_rx_frame()
nr_process_rx_frame(sk, skb); // sk : socket_1's sk
nr_state3_machine()
nr_queue_rx_frame()
sock_queue_rcv_skb()
sock_queue_rcv_skb_reason()
__sock_queue_rcv_skb()
__skb_queue_tail(list, skb); // list : socket_1's sk->sk_receive_queue
4. listen(socket_1)
nr_listen()
uaf_socket = accept(socket_1)
nr_accept()
skb_dequeue(&sk->sk_receive_queue);
5. close(accepted_socket)
nr_release()
nr_write_internal(sk, NR_DISCREQ)
nr_transmit_buffer() // NR_DISCREQ
nr_route_frame()
nr_loopback_queue()
nr_loopback_timer()
nr_rx_frame() // sk : socket_1's sk
nr_process_rx_frame() // NR_STATE_3
nr_state3_machine() // NR_DISCREQ
nr_disconnect()
nr_sk(sk)->state = NR_STATE_0;
6. close(socket_1) // sk refcount : 3
nr_release() // NR_STATE_0
sock_put(sk); // sk refcount : 0
sk_free(sk);
close(uaf_socket)
nr_release()
sock_hold(sk); // UAF
```And sorry for sending the v3 netrom patch first.
I received an email that the v2 x25 patch with the wrong patch description was applied to the tree,
so I made a v3 x25 patch in a hurry and sent the netrom as well.
Quoted 200 lines
Quoted 200 lines
3. write(accepted_socket) nr_sendmsg() nr_output() nr_kick() nr_send_iframe() nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_process_rx_frame(sk, skb); // sk : socket_1's sk nr_state3_machine() nr_queue_rx_frame() sock_queue_rcv_skb() sock_queue_rcv_skb_reason() __sock_queue_rcv_skb() __skb_queue_tail(list, skb); // list : socket_1's sk->sk_receive_queue 4. listen(socket_1) nr_listen() uaf_socket = accept(socket_1) nr_accept() skb_dequeue(&sk->sk_receive_queue); 5. close(accepted_socket) nr_release() nr_write_internal(sk, NR_DISCREQ) nr_transmit_buffer() // NR_DISCREQ nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() // sk : socket_1's sk nr_process_rx_frame() // NR_STATE_3 nr_state3_machine() // NR_DISCREQ nr_disconnect() nr_sk(sk)->state = NR_STATE_0; 6. close(socket_1) // sk refcount : 3 nr_release() // NR_STATE_0 sock_put(sk); // sk refcount : 0 sk_free(sk); close(uaf_socket) nr_release() sock_hold(sk); // UAF```
Anything wrong?
Quoted 153 lines
Quoted 153 lines
nr_release()nr_write_internal(sk, NR_DISCREQ)
nr_transmit_buffer()//NR_DISCREQ
nr_route_frame()nr_loopback_queue()nr_loopback_timer()
nr_rx_frame()// sk : socket_1's sk
nr_process_rx_frame()//NR_STATE_3
nr_state3_machine()//NR_DISCREQ
nr_disconnect()nr_sk(sk)->state =NR_STATE_0;
5.close(socket_1)// sk refcount : 3
nr_release()//NR_STATE_0
sock_put(sk); // sk refcount : 0
sk_free(sk);
close(uaf_socket)
nr_release()
sock_hold(sk); // UAF``` KASAN report by syzbot: ``` BUG: KASAN: use-after-free in nr_release+0x66/0x460 net/netrom/af_netrom.c:520 Write of size 4 at addr ffff8880235d8080 by task syz-executor564/5128 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:306 [inline] print_report+0x15e/0x461 mm/kasan/report.c:417 kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 check_region_inline mm/kasan/generic.c:183 [inline] kasan_check_range+0x141/0x190 mm/kasan/generic.c:189 instrument_atomic_read_write include/linux/instrumented.h:102 [inline] atomic_fetch_add_relaxed include/linux/atomic/atomic-instrumented.h:116 [inline] __refcount_add include/linux/refcount.h:193 [inline] __refcount_inc include/linux/refcount.h:250 [inline] refcount_inc include/linux/refcount.h:267 [inline] sock_hold include/net/sock.h:775 [inline] nr_release+0x66/0x460 net/netrom/af_netrom.c:520 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f6c19e3c9b9 Code: Unable to access opcode bytes at 0x7f6c19e3c98f. RSP: 002b:00007fffd4ba2ce8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: 0000000000000116 RBX: 0000000000000003 RCX: 00007f6c19e3c9b9 RDX: 0000000000000318 RSI: 00000000200bd000 RDI: 0000000000000006 RBP: 0000000000000003 R08: 000000000000000d R09: 000000000000000d R10: 0000000000000000 R11: 0000000000000246 R12: 000055555566a2c0 R13: 0000000000000011 R14: 0000000000000000 R15: 0000000000000000 </TASK> Allocated by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:371 [inline] ____kasan_kmalloc mm/kasan/common.c:330 [inline] __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380 kasan_kmalloc include/linux/kasan.h:211 [inline] __do_kmalloc_node mm/slab_common.c:968 [inline] __kmalloc+0x5a/0xd0 mm/slab_common.c:981 kmalloc include/linux/slab.h:584 [inline] sk_prot_alloc+0x140/0x290 net/core/sock.c:2038 sk_alloc+0x3a/0x7a0 net/core/sock.c:2091 nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433 __sock_create+0x359/0x790 net/socket.c:1515 sock_create net/socket.c:1566 [inline] __sys_socket_create net/socket.c:1603 [inline] __sys_socket_create net/socket.c:1588 [inline] __sys_socket+0x133/0x250 net/socket.c:1636 __do_sys_socket net/socket.c:1649 [inline] __se_sys_socket net/socket.c:1647 [inline] __x64_sys_socket+0x73/0xb0 net/socket.c:1647 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Freed by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] __cache_free mm/slab.c:3394 [inline] __do_kmem_cache_free mm/slab.c:3580 [inline] __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_release+0x39e/0x460 net/netrom/af_netrom.c:554 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd```
To fix this problem,
nr_listen()returns-EINVALfor sockets that successfullynr_connect().Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")Reported-by [email protected]Signed-off-by Hyunwoo Kim <[email protected]>--- net/netrom/af_netrom.c | 5 +++++ 1 file changed, 5 insertions(+)net/netrom/af_netrom.c +5
-0@@ -400,6 +400,11 @@ static int nr_listen(struct socket *sock, int backlog)struct sock *sk = sock->sk;lock_sock (sk); +if (sock->state !=SS_UNCONNECTED ) { +release_sock (sk); +return -EINVAL ; + } +if (sk->sk_state !=TCP_LISTEN ) {memset (&nr_sk (sk)->user_addr,0 ,AX25_ADDR_LEN ); sk->sk_max_ack_backlog = backlog;Signature · 1 line
2.25.1
From: Hyunwoo Kim <[email protected]> Date: Wed, 25 Jan 2023 20:16:36 -0800
Quoted 104 lines · Kuniyuki Iwashima
Quoted 103 lines
From: Hyunwoo Kim <[email protected]> Date: Wed, 25 Jan 2023 01:17:10 -0800Quoted 91 lines · Kuniyuki Iwashima
Quoted 22 lines
Hi,
I think the diff looks good but changelog is not correct.
From: Hyunwoo Kim <[email protected]> Date: Mon, 23 Jan 2023 09:22:33 -0800Quoted 4 lines
If
listen()andaccept()are called on anAF_NETROMsocket that has already been connect()ed,accept()succeeds in connecting. This is becausenr_accept()dequeues the skb queued insk->sk_receive_queueinnr_connect().This sentence is misleading. The skb sent by
nr_connect()is queued up for the peer'ssk_receive_queue(socket_2below), and also the reply is not queued for connect()er (socket_1) because it isNR_CONNACKand just consumed bynr_state1_machine()to transition toNR_STATE_3andTCP_ESTABLISHED.Quoted 3 lines
This causes
nr_accept()to allocate and return a sock with the sk of the parentAF_NETROMsocket.Quoted 7 lines
This happens because the peer (
socket_2) sends some data bynr_sendmsg(), whose type isNR_INFOand the data is queued up for the connect()er's (socket_1)sk_receive_queueby-
nr_state3_machine
-nr_queue_rx_frame
-sock_queue_rcv_skbyou're right.
I misanalyzednr_rx_frame(). sorry.Quoted 53 lines
Quoted 15 lines
And here's where use-after-free
can happen through complex race conditions:
```
cpu0 cpu1
1.socket_2=socket(AF_NETROM)listen(socket_2)
accepted_socket=accept(socket_2)// loopback connection withsocket_1
2.socket_1=socket(AF_NETROM)
nr_create()// sk refcount : 1
connect(socket_1)// loopback connection withsocket_2
nr_connect()
nr_establish_data_link()
nr_write_internal()This is
NR_CONNREQforsocket_2.Quoted 6 lines
nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() nr_process_rx_frame()So,
nr_process_rx_frame()is not called fromnr_rx_frame()because the kernel findssocket_2bynr_find_listener(), and createsaccepted_socket, and then responds withNR_CONNACKtosocket_1.And
accepted_socketsends some data withNR_INFO, then,nr_state3_machine()is called forsocket_1and the skb with sk pointingsocket_1is queued for socket_1'ssk_receive_queue.I think this part is lacking in this UAF scenario.
What do you think ?
Quoted 5 lines
nr_state3_machine() nr_queue_rx_frame() sock_queue_rcv_skb() sock_queue_rcv_skb_reason() __sock_queue_rcv_skb()Quoted 8 lines
__skb_queue_tail(list, skb); // list : sk->sk_receive_queue 3. listen(socket_1) nr_listen() uaf_socket = accept(socket_1) nr_accept() skb_dequeue(&sk->sk_receive_queue); 4. close(accepted_socket)Quoted 3 lines
And I guess this
close()is not so important in this case. Even if we don't close the socket cleanly, the UAF will happen, right ? (it might be caused in a different place like timer though)Quoted 5 lines
IMHO, I think this
close(accepted_socket)is a necessary procedure.
This is becausecase NR_STATE_3:innr_release()is executed here,
andnr_write_internal(sk, NR_DISCREQ)~nr_disconnect()sets socket_1's sk toNR_STATE_0. If sk ofsocket_1is not set toNR_STATE_0,case NR_STATE_3:is executed instead ofcase NR_STATE_0:inclose(socket_1)and sk is not released.No, it's released by the heartbeat timer. The heartbeat timer finally calls
nr_destroy_socket()asSOCK_DESTROYis flagged to the sk.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
This means you will not be able to trigger UAF on
close(uaf_socket).I didn't say
close(uaf_socket)is not needed, I mean we can trigger UAF withoutclose(__accepted_socket__).ok. understand. The reason why I put
close(accepted_socket)is because Freed by task in the KASAN log I attached to the patch description is as follows:
Ah, right.
Sorry, I was confused with 3 close()s :/
Quoted 147 lines
``` Freed by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] __cache_free mm/slab.c:3394 [inline] __do_kmem_cache_free mm/slab.c:3580 [inline] __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_release+0x39e/0x460 net/netrom/af_netrom.c:554 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd ```If, as you say, heartbeat is running and UAF is triggered, the KASAN Freed log will look like this:
``` Freed by task 14094: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2e/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x160/0x1c0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] slab_free_hook mm/slub.c:1781 [inline] slab_free_freelist_hook+0x8b/0x1c0 mm/slub.c:1807 slab_free mm/slub.c:3787 [inline] __kmem_cache_free+0xaf/0x3b0 mm/slub.c:3800 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_heartbeat_expiry+0x1d7/0x460 net/netrom/nr_timer.c:148 call_timer_fn+0x1da/0x7c0 kernel/time/timer.c:1700 expire_timers+0x2c6/0x5c0 kernel/time/timer.c:1751 __run_timers kernel/time/timer.c:2022 [inline] __run_timers kernel/time/timer.c:1995 [inline] run_timer_softirq+0x326/0x910 kernel/time/timer.c:2035 __do_softirq+0x1fb/0xadc kernel/softirq.c:571 ```Anyway, I'm trying to keep
close(accepted_socket)in the flow chart because the KASAN log I added to the first patch description is the first one.Quoted 28 lines
Quoted 19 lines
What do you think?
So the modified flow chart looks like this:
```cpu0 cpu1 1. socket_2 = socket(AF_NETROM) . . listen(socket_2) accepted_socket = accept(socket_2) 2. socket_1 = socket(AF_NETROM) nr_create() // sk refcount : 1 connect(socket_1) nr_connect() nr_establish_data_link() nr_write_internal()Quoted 8 lines
nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() nr_process_rx_frame() nr_state1_machine() nr->state = NR_STATE_3;Quoted 6 lines
If you write the connect()'s stack trace, you should note the state change at the
socket_1side byNR_CONNACK. TheNR_STATE_3here is forsocket_2byNR_CONNREQ. We don't need the details ofsocket_2.Otherwise, you should just write
connect(socket_1)only like the step 1 (socket(),listen()etc).So, the modified flow chart is:
``` cpu0 cpu1 1. socket_2 = socket(AF_NETROM) . . listen(socket_2) accepted_socket = accept(socket_2) 2. socket_1 = socket(AF_NETROM) nr_create() // sk refcount : 1 connect(socket_1) 3. write(accepted_socket) nr_sendmsg() nr_output() nr_kick() nr_send_iframe() nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() nr_process_rx_frame(sk, skb); // sk : socket_1's sk nr_state3_machine() nr_queue_rx_frame() sock_queue_rcv_skb() sock_queue_rcv_skb_reason() __sock_queue_rcv_skb() __skb_queue_tail(list, skb); // list : socket_1's sk->sk_receive_queue 4. listen(socket_1) nr_listen() uaf_socket = accept(socket_1) nr_accept() skb_dequeue(&sk->sk_receive_queue); 5. close(accepted_socket) nr_release() nr_write_internal(sk, NR_DISCREQ) nr_transmit_buffer() // NR_DISCREQ nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() // sk : socket_1's sk nr_process_rx_frame() // NR_STATE_3 nr_state3_machine() // NR_DISCREQ nr_disconnect() nr_sk(sk)->state = NR_STATE_0;
Quoted 8 lines
6. close(socket_1) // sk refcount : 3
nr_release() // NR_STATE_0
sock_put(sk); // sk refcount : 0
sk_free(sk);
close(uaf_socket)
nr_release()
sock_hold(sk); // UAF
```Ok, this looks good.
Please send v4 without my Reviewed-by tag.
Thank you.
Quoted 206 lines
And sorry for sending the v3 netrom patch first.
I received an email that the v2 x25 patch with the wrong patch description was applied to the tree,
so I made a v3 x25 patch in a hurry and sent the netrom as well.Quoted 200 lines
Quoted 200 lines
3. write(accepted_socket) nr_sendmsg() nr_output() nr_kick() nr_send_iframe() nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_process_rx_frame(sk, skb); // sk : socket_1's sk nr_state3_machine() nr_queue_rx_frame() sock_queue_rcv_skb() sock_queue_rcv_skb_reason() __sock_queue_rcv_skb() __skb_queue_tail(list, skb); // list : socket_1's sk->sk_receive_queue 4. listen(socket_1) nr_listen() uaf_socket = accept(socket_1) nr_accept() skb_dequeue(&sk->sk_receive_queue); 5. close(accepted_socket) nr_release() nr_write_internal(sk, NR_DISCREQ) nr_transmit_buffer() // NR_DISCREQ nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() // sk : socket_1's sk nr_process_rx_frame() // NR_STATE_3 nr_state3_machine() // NR_DISCREQ nr_disconnect() nr_sk(sk)->state = NR_STATE_0; 6. close(socket_1) // sk refcount : 3 nr_release() // NR_STATE_0 sock_put(sk); // sk refcount : 0 sk_free(sk); close(uaf_socket) nr_release() sock_hold(sk); // UAF```
Anything wrong?
Quoted 153 lines
Quoted 153 lines
nr_release()nr_write_internal(sk, NR_DISCREQ)
nr_transmit_buffer()//NR_DISCREQ
nr_route_frame()nr_loopback_queue()nr_loopback_timer()
nr_rx_frame()// sk : socket_1's sk
nr_process_rx_frame()//NR_STATE_3
nr_state3_machine()//NR_DISCREQ
nr_disconnect()nr_sk(sk)->state =NR_STATE_0;
5.close(socket_1)// sk refcount : 3
nr_release()//NR_STATE_0
sock_put(sk); // sk refcount : 0
sk_free(sk);
close(uaf_socket)
nr_release()
sock_hold(sk); // UAF``` KASAN report by syzbot: ``` BUG: KASAN: use-after-free in nr_release+0x66/0x460 net/netrom/af_netrom.c:520 Write of size 4 at addr ffff8880235d8080 by task syz-executor564/5128 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:306 [inline] print_report+0x15e/0x461 mm/kasan/report.c:417 kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 check_region_inline mm/kasan/generic.c:183 [inline] kasan_check_range+0x141/0x190 mm/kasan/generic.c:189 instrument_atomic_read_write include/linux/instrumented.h:102 [inline] atomic_fetch_add_relaxed include/linux/atomic/atomic-instrumented.h:116 [inline] __refcount_add include/linux/refcount.h:193 [inline] __refcount_inc include/linux/refcount.h:250 [inline] refcount_inc include/linux/refcount.h:267 [inline] sock_hold include/net/sock.h:775 [inline] nr_release+0x66/0x460 net/netrom/af_netrom.c:520 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f6c19e3c9b9 Code: Unable to access opcode bytes at 0x7f6c19e3c98f. RSP: 002b:00007fffd4ba2ce8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: 0000000000000116 RBX: 0000000000000003 RCX: 00007f6c19e3c9b9 RDX: 0000000000000318 RSI: 00000000200bd000 RDI: 0000000000000006 RBP: 0000000000000003 R08: 000000000000000d R09: 000000000000000d R10: 0000000000000000 R11: 0000000000000246 R12: 000055555566a2c0 R13: 0000000000000011 R14: 0000000000000000 R15: 0000000000000000 </TASK> Allocated by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:371 [inline] ____kasan_kmalloc mm/kasan/common.c:330 [inline] __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380 kasan_kmalloc include/linux/kasan.h:211 [inline] __do_kmalloc_node mm/slab_common.c:968 [inline] __kmalloc+0x5a/0xd0 mm/slab_common.c:981 kmalloc include/linux/slab.h:584 [inline] sk_prot_alloc+0x140/0x290 net/core/sock.c:2038 sk_alloc+0x3a/0x7a0 net/core/sock.c:2091 nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433 __sock_create+0x359/0x790 net/socket.c:1515 sock_create net/socket.c:1566 [inline] __sys_socket_create net/socket.c:1603 [inline] __sys_socket_create net/socket.c:1588 [inline] __sys_socket+0x133/0x250 net/socket.c:1636 __do_sys_socket net/socket.c:1649 [inline] __se_sys_socket net/socket.c:1647 [inline] __x64_sys_socket+0x73/0xb0 net/socket.c:1647 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Freed by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] __cache_free mm/slab.c:3394 [inline] __do_kmem_cache_free mm/slab.c:3580 [inline] __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_release+0x39e/0x460 net/netrom/af_netrom.c:554 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd```
To fix this problem,
nr_listen()returns-EINVALfor sockets that successfullynr_connect().Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")Reported-by [email protected]Signed-off-by Hyunwoo Kim <[email protected]>--- net/netrom/af_netrom.c | 5 +++++ 1 file changed, 5 insertions(+)net/netrom/af_netrom.c +5
-0@@ -400,6 +400,11 @@ static int nr_listen(struct socket *sock, int backlog)struct sock *sk = sock->sk;lock_sock (sk); +if (sock->state !=SS_UNCONNECTED ) { +release_sock (sk); +return -EINVAL ; + } +if (sk->sk_state !=TCP_LISTEN ) {memset (&nr_sk (sk)->user_addr,0 ,AX25_ADDR_LEN ); sk->sk_max_ack_backlog = backlog;Signature · 1 line
2.25.1
KERNEL BUG LIKELY: Kernel Panic! MKISS related
I noticed this on two systems except I did not get the kernel dump
readout as X was running. I thought it may have had to do with
VirtualBox, but then I am getting similar behavior on a real install. I was lucky that I did not have X running and have nice output that I OCR'd from a photo of the screen.
How to reproduce this:
Setup 3 pseudo tty's for loopback to FBB BBS kissnetd -p 3 &
kissattach /dev/pts/1
kissparms -c 1 -p lb0
kissattach /dev/pts/2
kissparms -c 1 -p lb1
fbb configured with a real radio on /dev/ttyS0 for port 1 and the lb0 AX.25 kernel interface for port 2.
I leave the third pseudo tty for connecting JNOS to FBB over this "loopback" net.
If I try to pass bulls (or if I remember correctly even connect from JNOS) it locks cold.
Last night (where this screen shot kernel panic came from) was an actual radio port where I was pushing bulls to a newly installed instance of FBB on Arch Linux with the latest kernel 6.2.5. I have not had issues in slackware (and I was also running the latest stable kernel as I am too lazy to keep patching the LTS kernel, but I have not played as much there. I think I may install slack on this box too and see if I can get it to dump like this. If you want the photo, just email me directly as it looks like the OCR is not that good, but I do not know how photos will go over here.
Here is the screen dump:
11 fm KOolIP: 1 to NoTJ-1 ctI DISC: 1100216.0098271 BUG: kernel MULL
[106216.0109741 #PF supervisor read access in kernel mode
1106216.0121001 APE: error codetox0000)
not present page
[106216.0132301 PCD 0 P4D 0
[106216.0143551 Dops: 0000 [#11 PREEMPT SMP PTI
[106216.0151781 CPU: 0 PID: 39178 Comm: xibbd Tainted: G
DE
6.2.5-arch1-1 #1 Fel?0e9497e04500
[106216.0166331 Hardware name: Dell Inc. Optifiex 790/ONKUGV, BIOS A17 03/14/2013
[106216.0177931 RIP: 0010 :ax25_addr_ax25dev+0x44/0xb0 [ax251
[106216.0189621 Code: c1 53 ed 9 b3 61 P9 48 86 14 40 16 01 00 48 85 db 74 41 41 bc 01 00 00 00 eb 08 48 Bb 16
0 03 00 00 eB do fb M Tr 85 co 75 e1 48 Ba bb 90 00 00°
[106216.0214491 RSP: 0018: Frffa52b0107bdeB EFLAGS: 00010286
[106216.022714] RAX: 0000000000000000 RBX: FIff9457c84126c0 RCX:
0000000000000000
[106216.023976] RDX: 0000000000000001 RSI: ffffffffc1541100 RDI:
ffffa5260107be68
[106216.025229] RBP: ffFfa52b0107be68 ROB: 0000000000000009 R09:
0000000000000000
[106216.0264951 R10: 0000000000000000 R11: 0000000000000000 R12:
0000000000000001
[106216.0277661 R13: 0000000000000000 R14: 0000000000000000 R15:
0000000000000000
[106216.029015] FS:
00007/7421a26740 (0000) GS:ffff9458a9c00000 (0000) knIGS: 0000000000000000
[106216.0302591 CS:
0010 DS: 0000 ES: 0000 CRO: 0000000080050033
[106216.031589] CR2: 0000000000000340 CR3: 000000008c804005 CR4:
0000000000060650
[106216.0330441 Call Trace:
[106216.0337581 <TASK>
[106216.0344601 ax25_bind+0x1e2/0x210 [ax250149579197c9004716ce47844d0cb0c56b9a4c841
[106216.0351811
_sys_bind+Oxe8/OxfO
[106216.0358931
_x64_sus_bind+0x18/0×20
[106216.0365951
[106216.037296]
do_suscal1_64+0x5f/0×90
? syscall_exit_to_user_mode+0x1b/0×40
[106216.038000]
? do_syscal1_64+0x6b/0x90 [106216.0386931 entry_SYSCALL_64_after_huframe+0x72/0xdc
[106216.039390] RIP: 0033:0x717421b3791b
[106216.0400931 Code: c3 66 0f 1 44 00 00 48 86 15 51 e4 0c 00 f7 d8 64 89 02 b8 ff fr if ff eb be of 11 44 00 00. 13 of 1e fa b8 31 00 00 00 of 05 <48> 34 01 1
0 ff ff 73 01 c3 48 86 0d 25 e4 0c 00 f7 d8 64 89 01 48
[106216.041578] RSP: 0026:00007ffd15dab688 EFLAGS: 00000206 ORIG RAX:
0000000000000031
[106216.0423321 RAX: fffffffffffffrda RBX: 00007ffd15dabac2 RCX: 000077421b37916
[106216.043092] RDX: 0000000000000048 RSI: 00007ffd15dab700 RDI:
0000000000000009
[106216.043853] RBP: 0000563ef2403900 ROB: 0000000000000004 R09:
00000000ffffffff
[106216.0446231 R10: 00007rd15dab6c0 R11: 0000000000000206 R12: 0000000000000009
[106216.045395] R13: 0000000000000048 R14: 0000563ef2403c00 R15:
0000000000000010
[106216.0461671
</TASK>
[106216.0469201 Modules linked in: mkiss ax25 crc16 cp210x tun rperdma rdma_cm iw_cm ib_cm ib_core ufat fat intel_rap _msr intel_rapl common ×86_pkg_temp_therma I intel powerc lamp coretemp kum_ intel kum (rqbupass cret10dif pcimul cre32 pcimul polyual cimulni poluual generic grizimul ghash cimulni intel crypta sha512 53s e3 snd Ida _codec_hdmi snd hda_codec_-realtek snd _hda_codec generic rapl ledtrig _audio mousedev snd hda_intel intel _cstate at24 snd_intel_dspefg snd_intel_sdu acp i snd_hda_codec snd_hda_core snd_hudep snd_pem mei_pxp 12c_1801 intel_uncore mei_hdep snd_timer iTCO_wt snd dedbas intel_pc_bxt iTCO_uendor_support mei wat cf gBO211 rikill soundcore pespr 12c _smblis mei me mel lpe_ich mac hid e1000e nfsd auth epcyss nfs acl lockd grace sunrpe uboxnetfit (OF) Uboxmetadp(OF) uboxdru(OF» dm _mod loop fuse bpf_preload ip_tables x tables btrfs blakeZb _generic xor raid_pq liberc32c usbhid cre32c _generic 1915 drm_buddy intel_gtt crc32c_intel drm_di splay_helper sr_mod cdrom cec ttm video uni
[106216.0526781 CRZ: 0000000000000340
[106216.053515] ---[ end trace 0000000000000000 1-
[106216.0543461 RIP: 0010 :ax25_ addr_ax25deu+0x44/Oxb0 Lax25]
[106216.055173] Code: c1 53 8 9 63 61 9 48 86 1d 40 16 01 00 48 85 ab
74 4f 41 bc 01 00 00 00 eb 0B 48 8b 16 48 85 b 74 31 48 86 43 08 48. 89 ef <48> 86 60
0 03 00 00 e8 do fb fr ff 85 cO 75 e1 48 8d bb 90 00 00
[106216.056921] RSP: 0018:ffffa52b0107bded EFLAGS: 00010286
1106216.0578041 RAX: 0000000000000000 RBX: fFff9457c84126c0 RCX:
0000000000000000
[106216.058688] RDX: 0000000000000001 RSI: ffffffffc1541100 RDI: ffffa520107be68
[106216.059577] RBP: ffffa52b0107be68 ROB: 0000000000000009 R09:
0000000000000000
[106216.060473] R10: 0000000000000000 R11: 0000000000000000 R12:
0000000000000001
[106216.0613741 R13: 0000000000000000 R14: 0000000000000000 R15:
0000000000000000
[106216.0622811 FS*
0000757421a26740 (0000) GS:ffFf9458a9c00000(0000) knIGS:0000000000000000
[106216.063200] C8:
0010 DS: 0000 ES: 0000 CRO: 0000000080050033
[106216.0641291 CR2: 0000000000000340 CR3: 000000008c804005 CR4: 000000000006060
[106216.0650721 Kernel panic - not syncing: Fatal exception in interrupt
[106216.0662201 Kernel Offset: 0x38e00000 from Oxffffffff81000000 (relocation range: Oxfffffff80000000-oxfrrrrrrrrrrrrr)
[106216.0672191
---[ end Kernel panic
- not syncing: Fatal exception in interrupt ]-.
Regards,
Chris KQ6UP
Re: KERNEL BUG LIKELY: Kernel Panic! MKISS related
Hi,
From: Chris Maness <[email protected]> Date: Wed, 15 Mar 2023 09:54:03 -0700
Quoted 89 lines
I noticed this on two systems except I did not get the kernel dump
readout as X was running. I thought it may have had to do with
VirtualBox, but then I am getting similar behavior on a real install. I was lucky that I did not have X running and have nice output that I OCR'd from a photo of the screen.How to reproduce this:
Setup 3 pseudo tty's for loopback to FBB BBS kissnetd -p 3 &
kissattach/dev/pts/1
kissparms -c 1 -p lb0
kissattach/dev/pts/2
kissparms -c 1 -p lb1
fbb configured with a real radio on/dev/ttyS0for port 1 and the lb0 AX.25 kernel interface for port 2.I leave the third pseudo tty for connecting JNOS to FBB over this "loopback" net.
If I try to pass bulls (or if I remember correctly even connect from JNOS) it locks cold.
Last night (where this screen shot kernel panic came from) was an actual radio port where I was pushing bulls to a newly installed instance of FBB on Arch Linux with the latest kernel 6.2.5. I have not had issues in slackware (and I was also running the latest stable kernel as I am too lazy to keep patching the LTS kernel, but I have not played as much there. I think I may install slack on this box too and see if I can get it to dump like this. If you want the photo, just email me directly as it looks like the OCR is not that good, but I do not know how photos will go over here.
Here is the screen dump:
11 fm KOolIP: 1 to NoTJ-1 ctI DISC: 1100216.0098271 BUG: kernel MULL
[106216.0109741 #PF supervisor read access in kernel mode
1106216.0121001 APE: error codetox0000)
not present page
[106216.0132301 PCD 0 P4D 0
[106216.0143551 Dops: 0000 [#11 PREEMPT SMP PTI
[106216.0151781 CPU: 0 PID: 39178 Comm: xibbd Tainted: G
DE
6.2.5-arch1-1 #1 Fel?0e9497e04500
[106216.0166331 Hardware name: Dell Inc. Optifiex 790/ONKUGV, BIOS A17 03/14/2013
[106216.0177931 RIP: 0010 :ax25_addr_ax25dev+0x44/0xb0 [ax251
[106216.0189621 Code: c1 53 ed 9 b3 61 P9 48 86 14 40 16 01 00 48 85 db 74 41 41 bc 01 00 00 00 eb 08 48 Bb 16
0 03 00 00 eB do fb M Tr 85 co 75 e1 48 Ba bb 90 00 00=C2=B0
[106216.0214491 RSP: 0018: Frffa52b0107bdeB EFLAGS: 00010286
[106216.022714] RAX: 0000000000000000 RBX: FIff9457c84126c0 RCX:0000000000000000
[106216.023976] RDX: 0000000000000001 RSI: ffffffffc1541100 RDI:
ffffa5260107be68[106216.025229] RBP: ffFfa52b0107be68 ROB: 0000000000000009 R09:0000000000000000
[106216.0264951 R10: 0000000000000000 R11: 0000000000000000 R12:
0000000000000001[106216.0277661 R13: 0000000000000000 R14: 0000000000000000 R15:
0000000000000000[106216.029015] FS:00007/7421a26740 (0000) GS:ffff9458a9c00000 (0000) knIGS: 0000000000000000
[106216.0302591 CS:
0010 DS: 0000 ES: 0000 CRO: 0000000080050033
[106216.031589] CR2: 0000000000000340 CR3: 000000008c804005 CR4:
Quoted 8 lines
0000000000060650
[106216.0330441 Call Trace:
[106216.0337581 <TASK>
[106216.0344601
ax25_bind+0x1e2/0x210[ax250149579197c9004716ce47844d0cb0c56b9a4c841
It seems to be a new null-deref ?
I think at least this patch is not related to the issue and same for other patches from Hyunwoom. All of these commits did not touch ax25.
611792920925 ("netrom: Fix use-after-free caused by accept on already connected socket") f2b0b5210f67 ("net/x25: Fix to not accept on connected socket") 14caefcf9837 ("net/rose: Fix to not accept on connected socket")
Thanks,
Kuniyuki
Quoted 122 lines
[106216.0351811
_sys_bind+Oxe8/OxfO
[106216.0358931
_x64_sus_bind+0x18/0=C3=9720
[106216.0365951
[106216.037296]do_suscal1_64+0x5f/0=C3=9790
? syscall_exit_to_user_mode+0x1b/0=C3=9740
[106216.038000]? do_syscal1_64+0x6b/0x90 [106216.0386931 entry_SYSCALL_64_after_huframe+0x72/0xdc[106216.039390] RIP: 0033:0x717421b3791b[106216.0400931 Code: c3 66 0f 1 44 00 00 48 86 15 51 e4 0c 00 f7 d8 64 89 02 b8 ff fr if ff eb be of 11 44 00 00. 13 of 1e fa b8 31 00 00 00 of 05 <48> 34 01 1
0 ff ff 73 01 c3 48 86 0d 25 e4 0c 00 f7 d8 64 89 01 48
[106216.041578] RSP: 0026:00007ffd15dab688 EFLAGS: 00000206 ORIG RAX:0000000000000031
[106216.0423321 RAX: fffffffffffffrda RBX:
00007ffd15dabac2RCX: 000077421b= 37916[106216.043092] RDX: 0000000000000048 RSI: 00007ffd15dab700 RDI:0000000000000009
[106216.043853] RBP: 0000563ef2403900 ROB: 0000000000000004 R09:
00000000ffffffff[106216.0446231 R10: 00007rd15dab6c0 R11: 0000000000000206 R12: 00000000000= 00009
[106216.045395] R13: 0000000000000048 R14: 0000563ef2403c00 R15:0000000000000010
[106216.0461671
</TASK>[106216.0469201 Modules linked in: mkiss ax25 crc16 cp210x tun rperdma
rdma_cmiw_cmib_cmib_coreufat fatintel_rap_msrintel_raplcommon =C3=9786_pkg_temp_therma I intel powerc lamp coretempkum_intel kum (rqbupass cret10dif pcimul cre32 pcimul polyual cimulni poluual generic grizimul ghash cimulni intel crypta sha512 53s e3 snd Ida_codec_hdmisnd hda_codec_-realtek snd_hda_codecgeneric rapl ledtrig_audiomousedev sndhda_intelintel_cstateat24snd_intel_dspefgsnd_intel_sduacp isnd_hda_codecsnd_hda_coresnd_hudepsnd_pemmei_pxp12c_1801intel_uncoremei_hdepsnd_timeriTCO_wtsnd dedbasintel_pc_bxtiTCO_uendor_supportmei wat cf gBO211 rikill soundcore pespr 12c_smblismei me mellpe_ichmac hid e1000e nfsd auth epcyss nfs acl lockd grace sunrpe uboxnetfit (OF) Uboxmetadp(OF) uboxdru(OF=C2=BB dm_modloop fusebpf_preloadip_tablesx tables btrfs blakeZb_genericxorraid_pqliberc32c usbhid cre32c_generic1915drm_buddyintel_gttcrc32c_inteldrm_display_helpersr_modcdrom cec ttm video uni[106216.0526781 CRZ: 0000000000000340
[106216.053515] ---[ end trace 0000000000000000 1-[106216.0543461 RIP: 0010 :ax25_ addr_ax25deu+0x44/Oxb0 Lax25]
[106216.055173] Code: c1 53 8 9 63 61 9 48 86 1d 40 16 01 00 48 85 ab74 4f 41 bc 01 00 00 00 eb 0B 48 8b 16 48 85 b 74 31 48 86 43 08 48. 89 ef <48> 86 60
0 03 00 00 e8 do fb fr ff 85 cO 75 e1 48 8d bb 90 00 00
[106216.056921] RSP: 0018:ffffa52b0107bded EFLAGS: 000102861106216.0578041 RAX: 0000000000000000 RBX: fFff9457c84126c0 RCX:
0000000000000000[106216.058688] RDX: 0000000000000001 RSI: ffffffffc1541100 RDI: ffffa52010=7be68
[106216.059577] RBP: ffffa52b0107be68 ROB: 0000000000000009 R09:0000000000000000
[106216.060473] R10: 0000000000000000 R11: 0000000000000000 R12:0000000000000001
[106216.0613741 R13: 0000000000000000 R14: 0000000000000000 R15:
0000000000000000[106216.0622811 FS*
0000757421a26740(0000) GS:ffFf9458a9c00000(0000) knIGS:0000000000000000[106216.063200] C8:0010 DS: 0000 ES: 0000 CRO: 0000000080050033
[106216.0641291 CR2: 0000000000000340 CR3:
000000008c804005CR4: 0000000000= 06060[106216.0650721 Kernel panic - not syncing: Fatal exception in interrupt
[106216.0662201 Kernel Offset:
0x38e00000from Oxffffffff81000000 (relocation range: Oxfffffff80000000-oxfrrrrrrrrrrrrr)[106216.0672191
---[ end Kernel panic- not syncing: Fatal exception in interrupt ]-.
Regards,
Chris KQ6UP