2024-01-17 07:38:24

by Ubisectech Sirius

[permalink] [raw]
Subject: BUG: unable to handle kernel paging request in __skb_flow_dissect

Hello.
We are Ubisectech Sirius Team, the vulnerability lab of China ValiantSec. Recently, our team has discovered a issue in Linux kernel 6.7.0-g052d534373b7. Attached to the email were a POC file of the issue.
Stack dump:
[ 185.664167][ T8332] BUG: unable to handle page fault for address: ffffed1029c40001
[ 185.665134][ T8332] #PF: supervisor read access in kernel mode
[ 185.665877][ T8332] #PF: error_code(0x0000) - not-present page
[ 185.666481][ T8332] PGD 7ffd0067 P4D 7ffd0067 PUD 3fff5067 PMD 0
[ 185.667129][ T8332] Oops: 0000 [#1] PREEMPT SMP KASAN
[ 185.667719][ T8332] CPU: 1 PID: 8332 Comm: poc Not tainted 6.7.0-g052d534373b7 #19
[ 185.668641][ T8332] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
[ 185.669639][ T8332] RIP: 0010:__skb_flow_dissect (net/core/flow_dissector.c:1170 (discriminator 1))
[ 185.682210][ T8332] Call Trace:
[ 185.682595][ T8332] <TASK>
[ 185.717256][ T8332] __skb_get_hash (net/core/flow_dissector.c:1737 net/core/flow_dissector.c:1770 net/core/flow_dissector.c:1794 net/core/flow_dissector.c:1856)
[ 185.721978][ T8332] ip_tunnel_xmit (./include/linux/skbuff.h:1566 net/ipv4/ip_tunnel.c:748)
[ 185.727788][ T8332] ipip_tunnel_xmit (net/ipv4/ipip.c:308)
[ 185.728396][ T8332] dev_hard_start_xmit (./include/linux/netdevice.h:5004 net/core/dev.c:3547 net/core/dev.c:3563)
[ 185.729082][ T8332] __dev_queue_xmit (./include/linux/netdevice.h:3367 net/core/dev.c:4352)
[ 185.736814][ T8332] neigh_connected_output (./include/linux/netdevice.h:3171 net/core/neighbour.c:1592)
[ 185.737536][ T8332] ip_finish_output2 (./include/net/neighbour.h:542 net/ipv4/ip_output.c:235)
[ 185.742239][ T8332] __ip_finish_output (net/ipv4/ip_output.c:313 net/ipv4/ip_output.c:295)
[ 185.742943][ T8332] ip_finish_output (net/ipv4/ip_output.c:323)
[ 185.743556][ T8332] ip_mc_output (./include/linux/netfilter.h:303 net/ipv4/ip_output.c:420)
[ 185.744137][ T8332] ip_local_out (./include/net/dst.h:451 net/ipv4/ip_output.c:129)
[ 185.744746][ T8332] iptunnel_xmit (net/ipv4/ip_tunnel_core.c:84 (discriminator 4))
[ 185.745390][ T8332] ip_tunnel_xmit (net/ipv4/ip_tunnel.c:833)
[ 185.750430][ T8332] dev_hard_start_xmit (./include/linux/netdevice.h:5004 net/core/dev.c:3547 net/core/dev.c:3563)
[ 185.751114][ T8332] __dev_queue_xmit (./include/linux/netdevice.h:3367 net/core/dev.c:4352)
[ 185.759138][ T8332] __bpf_redirect (./include/linux/netdevice.h:3367 net/core/filter.c:2136 net/core/filter.c:2165 net/core/filter.c:2188)
[ 185.759757][ T8332] bpf_clone_redirect (net/core/filter.c:2459 net/core/filter.c:2431)
[ 185.761088][ T8332] ___bpf_prog_run (kernel/bpf/core.c:1986)
[ 185.762499][ T8332] __bpf_prog_run512 (kernel/bpf/core.c:2227)
[ 185.778478][ T8332] bpf_test_run (./include/linux/bpf.h:1231 ./include/linux/filter.h:651 ./include/linux/filter.h:658 net/bpf/test_run.c:423)
[ 185.783715][ T8332] bpf_prog_test_run_skb (net/bpf/test_run.c:1057)
[ 185.786538][ T8332] __sys_bpf (kernel/bpf/syscall.c:4107 kernel/bpf/syscall.c:5475)
[ 185.793454][ T8332] __x64_sys_bpf (kernel/bpf/syscall.c:5559)
[ 185.794810][ T8332] do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
[ 185.795399][ T8332] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129)
[ 185.796182][ T8332] RIP: 0033:0x7f4f8955df29
Analyze of the issue:
The issue code in the __skb_flow_dissect function(net/core/flow_dissector.c:1170). The code are blow:
iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
if (!iph || iph->ihl < 5) {
fdret = FLOW_DISSECT_RET_OUT_BAD;
break;
}
It looks like the function __skb_header_pointer will return a invalid address, and iph->ihl will read the invalid address to get value. So, I think the issue is lack of check the iph is valid or no.
Thank you for taking the time to read this email and we look forward to working with you further.
Ubisectech Sirius Team
Web: http://www.ubisectech.com
Email: [email protected]


Attachments:
poc.c (43.98 kB)

2024-01-19 13:03:38

by Hillf Danton

[permalink] [raw]
Subject: Re: BUG: unable to handle kernel paging request in __skb_flow_dissect

On Wed, 17 Jan 2024 15:32:28 +0800 Ubisectech Sirius <[email protected]>
> Hello.
> We are Ubisectech Sirius Team, the vulnerability lab of China ValiantSec.
> Recently, our team has discovered a issue in Linux kernel 6.7.0-g052d534373b7.
> Attached to the email were a POC file of the issue.
> Stack dump:
> [ 185.664167][ T8332] BUG: unable to handle page fault for address: ffffed1029c40001
> [ 185.665134][ T8332] #PF: supervisor read access in kernel mode
> [ 185.665877][ T8332] #PF: error_code(0x0000) - not-present page
> [ 185.666481][ T8332] PGD 7ffd0067 P4D 7ffd0067 PUD 3fff5067 PMD 0
> [ 185.667129][ T8332] Oops: 0000 [#1] PREEMPT SMP KASAN
> [ 185.667719][ T8332] CPU: 1 PID: 8332 Comm: poc Not tainted 6.7.0-g052d534373b7 #19
> [ 185.668641][ T8332] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
> [ 185.669639][ T8332] RIP: 0010:__skb_flow_dissect (net/core/flow_dissector.c:1170 (discriminator 1))

Looks like the syzbot report [1] on 01 Jan 2024, and decoding the test
result of a debug patch [2] is welcome.

Hillf

[1] https://lore.kernel.org/lkml/[email protected]/
[2] https://lore.kernel.org/lkml/[email protected]/