netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 net 0/3] ipv6: fix possible UAF in output paths
@ 2024-08-20 16:08 Eric Dumazet
  2024-08-20 16:08 ` [PATCH v2 net 1/3] ipv6: prevent UAF in ip6_send_skb() Eric Dumazet
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Eric Dumazet @ 2024-08-20 16:08 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: David Ahern, netdev, eric.dumazet, Eric Dumazet

First patch fixes an issue spotted by syzbot, and the two
other patches fix error paths after skb_expand_head()
adoption.

v2: addressed David Ahern feedback on the third patch.

Eric Dumazet (3):
  ipv6: prevent UAF in ip6_send_skb()
  ipv6: fix possible UAF in ip6_finish_output2()
  ipv6: prevent possible UAF in ip6_xmit()

 net/ipv6/ip6_output.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

-- 
2.46.0.184.g6999bdac58-goog


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 net 1/3] ipv6: prevent UAF in ip6_send_skb()
  2024-08-20 16:08 [PATCH v2 net 0/3] ipv6: fix possible UAF in output paths Eric Dumazet
@ 2024-08-20 16:08 ` Eric Dumazet
  2024-08-20 18:58   ` David Ahern
  2024-08-20 16:08 ` [PATCH v2 net 2/3] ipv6: fix possible UAF in ip6_finish_output2() Eric Dumazet
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Eric Dumazet @ 2024-08-20 16:08 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: David Ahern, netdev, eric.dumazet, Eric Dumazet, syzbot

syzbot reported an UAF in ip6_send_skb() [1]

After ip6_local_out() has returned, we no longer can safely
dereference rt, unless we hold rcu_read_lock().

A similar issue has been fixed in commit
a688caa34beb ("ipv6: take rcu lock in rawv6_send_hdrinc()")

Another potential issue in ip6_finish_output2() is handled in a
separate patch.

[1]
 BUG: KASAN: slab-use-after-free in ip6_send_skb+0x18d/0x230 net/ipv6/ip6_output.c:1964
Read of size 8 at addr ffff88806dde4858 by task syz.1.380/6530

CPU: 1 UID: 0 PID: 6530 Comm: syz.1.380 Not tainted 6.11.0-rc3-syzkaller-00306-gdf6cbc62cc9b #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024
Call Trace:
 <TASK>
  __dump_stack lib/dump_stack.c:93 [inline]
  dump_stack_lvl+0x241/0x360 lib/dump_stack.c:119
  print_address_description mm/kasan/report.c:377 [inline]
  print_report+0x169/0x550 mm/kasan/report.c:488
  kasan_report+0x143/0x180 mm/kasan/report.c:601
  ip6_send_skb+0x18d/0x230 net/ipv6/ip6_output.c:1964
  rawv6_push_pending_frames+0x75c/0x9e0 net/ipv6/raw.c:588
  rawv6_sendmsg+0x19c7/0x23c0 net/ipv6/raw.c:926
  sock_sendmsg_nosec net/socket.c:730 [inline]
  __sock_sendmsg+0x1a6/0x270 net/socket.c:745
  sock_write_iter+0x2dd/0x400 net/socket.c:1160
 do_iter_readv_writev+0x60a/0x890
  vfs_writev+0x37c/0xbb0 fs/read_write.c:971
  do_writev+0x1b1/0x350 fs/read_write.c:1018
  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
  do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f936bf79e79
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f936cd7f038 EFLAGS: 00000246 ORIG_RAX: 0000000000000014
RAX: ffffffffffffffda RBX: 00007f936c115f80 RCX: 00007f936bf79e79
RDX: 0000000000000001 RSI: 0000000020000040 RDI: 0000000000000004
RBP: 00007f936bfe7916 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000000000 R14: 00007f936c115f80 R15: 00007fff2860a7a8
 </TASK>

Allocated by task 6530:
  kasan_save_stack mm/kasan/common.c:47 [inline]
  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
  unpoison_slab_object mm/kasan/common.c:312 [inline]
  __kasan_slab_alloc+0x66/0x80 mm/kasan/common.c:338
  kasan_slab_alloc include/linux/kasan.h:201 [inline]
  slab_post_alloc_hook mm/slub.c:3988 [inline]
  slab_alloc_node mm/slub.c:4037 [inline]
  kmem_cache_alloc_noprof+0x135/0x2a0 mm/slub.c:4044
  dst_alloc+0x12b/0x190 net/core/dst.c:89
  ip6_blackhole_route+0x59/0x340 net/ipv6/route.c:2670
  make_blackhole net/xfrm/xfrm_policy.c:3120 [inline]
  xfrm_lookup_route+0xd1/0x1c0 net/xfrm/xfrm_policy.c:3313
  ip6_dst_lookup_flow+0x13e/0x180 net/ipv6/ip6_output.c:1257
  rawv6_sendmsg+0x1283/0x23c0 net/ipv6/raw.c:898
  sock_sendmsg_nosec net/socket.c:730 [inline]
  __sock_sendmsg+0x1a6/0x270 net/socket.c:745
  ____sys_sendmsg+0x525/0x7d0 net/socket.c:2597
  ___sys_sendmsg net/socket.c:2651 [inline]
  __sys_sendmsg+0x2b0/0x3a0 net/socket.c:2680
  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
  do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

Freed by task 45:
  kasan_save_stack mm/kasan/common.c:47 [inline]
  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
  kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579
  poison_slab_object+0xe0/0x150 mm/kasan/common.c:240
  __kasan_slab_free+0x37/0x60 mm/kasan/common.c:256
  kasan_slab_free include/linux/kasan.h:184 [inline]
  slab_free_hook mm/slub.c:2252 [inline]
  slab_free mm/slub.c:4473 [inline]
  kmem_cache_free+0x145/0x350 mm/slub.c:4548
  dst_destroy+0x2ac/0x460 net/core/dst.c:124
  rcu_do_batch kernel/rcu/tree.c:2569 [inline]
  rcu_core+0xafd/0x1830 kernel/rcu/tree.c:2843
  handle_softirqs+0x2c4/0x970 kernel/softirq.c:554
  __do_softirq kernel/softirq.c:588 [inline]
  invoke_softirq kernel/softirq.c:428 [inline]
  __irq_exit_rcu+0xf4/0x1c0 kernel/softirq.c:637
  irq_exit_rcu+0x9/0x30 kernel/softirq.c:649
  instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1043 [inline]
  sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1043
  asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:702

Last potentially related work creation:
  kasan_save_stack+0x3f/0x60 mm/kasan/common.c:47
  __kasan_record_aux_stack+0xac/0xc0 mm/kasan/generic.c:541
  __call_rcu_common kernel/rcu/tree.c:3106 [inline]
  call_rcu+0x167/0xa70 kernel/rcu/tree.c:3210
  refdst_drop include/net/dst.h:263 [inline]
  skb_dst_drop include/net/dst.h:275 [inline]
  nf_ct_frag6_queue net/ipv6/netfilter/nf_conntrack_reasm.c:306 [inline]
  nf_ct_frag6_gather+0xb9a/0x2080 net/ipv6/netfilter/nf_conntrack_reasm.c:485
  ipv6_defrag+0x2c8/0x3c0 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c:67
  nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
  nf_hook_slow+0xc3/0x220 net/netfilter/core.c:626
  nf_hook include/linux/netfilter.h:269 [inline]
  __ip6_local_out+0x6fa/0x800 net/ipv6/output_core.c:143
  ip6_local_out+0x26/0x70 net/ipv6/output_core.c:153
  ip6_send_skb+0x112/0x230 net/ipv6/ip6_output.c:1959
  rawv6_push_pending_frames+0x75c/0x9e0 net/ipv6/raw.c:588
  rawv6_sendmsg+0x19c7/0x23c0 net/ipv6/raw.c:926
  sock_sendmsg_nosec net/socket.c:730 [inline]
  __sock_sendmsg+0x1a6/0x270 net/socket.c:745
  sock_write_iter+0x2dd/0x400 net/socket.c:1160
 do_iter_readv_writev+0x60a/0x890

Fixes: 0625491493d9 ("ipv6: ip6_push_pending_frames() should increment IPSTATS_MIB_OUTDISCARDS")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
---
 net/ipv6/ip6_output.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index ab504d31f0cdd8dec9ab01bf9d6e6517307609cd..f7b53effc80f8b3b7a839f58097d021a11f9eb37 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1956,6 +1956,7 @@ int ip6_send_skb(struct sk_buff *skb)
 	struct rt6_info *rt = dst_rt6_info(skb_dst(skb));
 	int err;
 
+	rcu_read_lock();
 	err = ip6_local_out(net, skb->sk, skb);
 	if (err) {
 		if (err > 0)
@@ -1965,6 +1966,7 @@ int ip6_send_skb(struct sk_buff *skb)
 				      IPSTATS_MIB_OUTDISCARDS);
 	}
 
+	rcu_read_unlock();
 	return err;
 }
 
-- 
2.46.0.184.g6999bdac58-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 net 2/3] ipv6: fix possible UAF in ip6_finish_output2()
  2024-08-20 16:08 [PATCH v2 net 0/3] ipv6: fix possible UAF in output paths Eric Dumazet
  2024-08-20 16:08 ` [PATCH v2 net 1/3] ipv6: prevent UAF in ip6_send_skb() Eric Dumazet
@ 2024-08-20 16:08 ` Eric Dumazet
  2024-08-20 18:58   ` David Ahern
  2024-08-20 16:08 ` [PATCH v2 net 3/3] ipv6: prevent possible UAF in ip6_xmit() Eric Dumazet
  2024-08-22  0:40 ` [PATCH v2 net 0/3] ipv6: fix possible UAF in output paths patchwork-bot+netdevbpf
  3 siblings, 1 reply; 8+ messages in thread
From: Eric Dumazet @ 2024-08-20 16:08 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: David Ahern, netdev, eric.dumazet, Eric Dumazet, Vasily Averin

If skb_expand_head() returns NULL, skb has been freed
and associated dst/idev could also have been freed.

We need to hold rcu_read_lock() to make sure the dst and
associated idev are alive.

Fixes: 5796015fa968 ("ipv6: allocate enough headroom in ip6_finish_output2()")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Vasily Averin <vasily.averin@linux.dev>
---
 net/ipv6/ip6_output.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index f7b53effc80f8b3b7a839f58097d021a11f9eb37..1b9ebee7308f02a626c766de1794e6b114ae8554 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -70,11 +70,15 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
 
 	/* Be paranoid, rather than too clever. */
 	if (unlikely(hh_len > skb_headroom(skb)) && dev->header_ops) {
+		/* Make sure idev stays alive */
+		rcu_read_lock();
 		skb = skb_expand_head(skb, hh_len);
 		if (!skb) {
 			IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
+			rcu_read_unlock();
 			return -ENOMEM;
 		}
+		rcu_read_unlock();
 	}
 
 	hdr = ipv6_hdr(skb);
-- 
2.46.0.184.g6999bdac58-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 net 3/3] ipv6: prevent possible UAF in ip6_xmit()
  2024-08-20 16:08 [PATCH v2 net 0/3] ipv6: fix possible UAF in output paths Eric Dumazet
  2024-08-20 16:08 ` [PATCH v2 net 1/3] ipv6: prevent UAF in ip6_send_skb() Eric Dumazet
  2024-08-20 16:08 ` [PATCH v2 net 2/3] ipv6: fix possible UAF in ip6_finish_output2() Eric Dumazet
@ 2024-08-20 16:08 ` Eric Dumazet
  2024-08-20 18:58   ` David Ahern
  2024-08-22  0:40 ` [PATCH v2 net 0/3] ipv6: fix possible UAF in output paths patchwork-bot+netdevbpf
  3 siblings, 1 reply; 8+ messages in thread
From: Eric Dumazet @ 2024-08-20 16:08 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: David Ahern, netdev, eric.dumazet, Eric Dumazet, Vasily Averin

If skb_expand_head() returns NULL, skb has been freed
and the associated dst/idev could also have been freed.

We must use rcu_read_lock() to prevent a possible UAF.

Fixes: 0c9f227bee11 ("ipv6: use skb_expand_head in ip6_xmit")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Vasily Averin <vasily.averin@linux.dev>
---
 net/ipv6/ip6_output.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 1b9ebee7308f02a626c766de1794e6b114ae8554..f26841f1490f5c31e3b09bce5773391e779128e1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -287,11 +287,15 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
 		head_room += opt->opt_nflen + opt->opt_flen;
 
 	if (unlikely(head_room > skb_headroom(skb))) {
+		/* Make sure idev stays alive */
+		rcu_read_lock();
 		skb = skb_expand_head(skb, head_room);
 		if (!skb) {
 			IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
+			rcu_read_unlock();
 			return -ENOBUFS;
 		}
+		rcu_read_unlock();
 	}
 
 	if (opt) {
-- 
2.46.0.184.g6999bdac58-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net 1/3] ipv6: prevent UAF in ip6_send_skb()
  2024-08-20 16:08 ` [PATCH v2 net 1/3] ipv6: prevent UAF in ip6_send_skb() Eric Dumazet
@ 2024-08-20 18:58   ` David Ahern
  0 siblings, 0 replies; 8+ messages in thread
From: David Ahern @ 2024-08-20 18:58 UTC (permalink / raw)
  To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: netdev, eric.dumazet, syzbot

On 8/20/24 10:08 AM, Eric Dumazet wrote:
> syzbot reported an UAF in ip6_send_skb() [1]
> 
> After ip6_local_out() has returned, we no longer can safely
> dereference rt, unless we hold rcu_read_lock().
> 
> A similar issue has been fixed in commit
> a688caa34beb ("ipv6: take rcu lock in rawv6_send_hdrinc()")
> 
> Another potential issue in ip6_finish_output2() is handled in a
> separate patch.
> 

...

> 
> Fixes: 0625491493d9 ("ipv6: ip6_push_pending_frames() should increment IPSTATS_MIB_OUTDISCARDS")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: syzbot <syzkaller@googlegroups.com>
> ---
>  net/ipv6/ip6_output.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
Reviewed-by: David Ahern <dsahern@kernel.org>



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net 2/3] ipv6: fix possible UAF in ip6_finish_output2()
  2024-08-20 16:08 ` [PATCH v2 net 2/3] ipv6: fix possible UAF in ip6_finish_output2() Eric Dumazet
@ 2024-08-20 18:58   ` David Ahern
  0 siblings, 0 replies; 8+ messages in thread
From: David Ahern @ 2024-08-20 18:58 UTC (permalink / raw)
  To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: netdev, eric.dumazet, Vasily Averin

On 8/20/24 10:08 AM, Eric Dumazet wrote:
> If skb_expand_head() returns NULL, skb has been freed
> and associated dst/idev could also have been freed.
> 
> We need to hold rcu_read_lock() to make sure the dst and
> associated idev are alive.
> 
> Fixes: 5796015fa968 ("ipv6: allocate enough headroom in ip6_finish_output2()")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Vasily Averin <vasily.averin@linux.dev>
> ---
>  net/ipv6/ip6_output.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Reviewed-by: David Ahern <dsahern@kernel.org>



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net 3/3] ipv6: prevent possible UAF in ip6_xmit()
  2024-08-20 16:08 ` [PATCH v2 net 3/3] ipv6: prevent possible UAF in ip6_xmit() Eric Dumazet
@ 2024-08-20 18:58   ` David Ahern
  0 siblings, 0 replies; 8+ messages in thread
From: David Ahern @ 2024-08-20 18:58 UTC (permalink / raw)
  To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: netdev, eric.dumazet, Vasily Averin

On 8/20/24 10:08 AM, Eric Dumazet wrote:
> If skb_expand_head() returns NULL, skb has been freed
> and the associated dst/idev could also have been freed.
> 
> We must use rcu_read_lock() to prevent a possible UAF.
> 
> Fixes: 0c9f227bee11 ("ipv6: use skb_expand_head in ip6_xmit")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Vasily Averin <vasily.averin@linux.dev>
> ---
>  net/ipv6/ip6_output.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Reviewed-by: David Ahern <dsahern@kernel.org>



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net 0/3] ipv6: fix possible UAF in output paths
  2024-08-20 16:08 [PATCH v2 net 0/3] ipv6: fix possible UAF in output paths Eric Dumazet
                   ` (2 preceding siblings ...)
  2024-08-20 16:08 ` [PATCH v2 net 3/3] ipv6: prevent possible UAF in ip6_xmit() Eric Dumazet
@ 2024-08-22  0:40 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-08-22  0:40 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: davem, kuba, pabeni, dsahern, netdev, eric.dumazet

Hello:

This series was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Tue, 20 Aug 2024 16:08:56 +0000 you wrote:
> First patch fixes an issue spotted by syzbot, and the two
> other patches fix error paths after skb_expand_head()
> adoption.
> 
> v2: addressed David Ahern feedback on the third patch.
> 
> Eric Dumazet (3):
>   ipv6: prevent UAF in ip6_send_skb()
>   ipv6: fix possible UAF in ip6_finish_output2()
>   ipv6: prevent possible UAF in ip6_xmit()
> 
> [...]

Here is the summary with links:
  - [v2,net,1/3] ipv6: prevent UAF in ip6_send_skb()
    https://git.kernel.org/netdev/net/c/faa389b2fbaa
  - [v2,net,2/3] ipv6: fix possible UAF in ip6_finish_output2()
    https://git.kernel.org/netdev/net/c/da273b377ae0
  - [v2,net,3/3] ipv6: prevent possible UAF in ip6_xmit()
    https://git.kernel.org/netdev/net/c/2d5ff7e339d0

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-08-22  0:40 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-20 16:08 [PATCH v2 net 0/3] ipv6: fix possible UAF in output paths Eric Dumazet
2024-08-20 16:08 ` [PATCH v2 net 1/3] ipv6: prevent UAF in ip6_send_skb() Eric Dumazet
2024-08-20 18:58   ` David Ahern
2024-08-20 16:08 ` [PATCH v2 net 2/3] ipv6: fix possible UAF in ip6_finish_output2() Eric Dumazet
2024-08-20 18:58   ` David Ahern
2024-08-20 16:08 ` [PATCH v2 net 3/3] ipv6: prevent possible UAF in ip6_xmit() Eric Dumazet
2024-08-20 18:58   ` David Ahern
2024-08-22  0:40 ` [PATCH v2 net 0/3] ipv6: fix possible UAF in output paths patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).