netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] ipv6: orphan skbs in reassembly unit
@ 2017-03-01 22:45 Eric Dumazet
  2017-03-01 23:34 ` Joe Stringer
  2017-03-02  4:58 ` David Miller
  0 siblings, 2 replies; 3+ messages in thread
From: Eric Dumazet @ 2017-03-01 22:45 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Andrey Konovalov

From: Eric Dumazet <edumazet@google.com>

Andrey reported a use-after-free in IPv6 stack.

Issue here is that we free the socket while it still has skb
in TX path and in some queues.

It happens here because IPv6 reassembly unit messes skb->truesize,
breaking skb_set_owner_w() badly.

We fixed a similar issue for IPV4 in commit 8282f27449bf ("inet: frag:
Always orphan skbs inside ip_defrag()")

================================================================== 
BUG: KASAN: use-after-free in sock_wfree+0x118/0x120 
Read of size 8 at addr ffff880062da0060 by task a.out/4140 

page:ffffea00018b6800 count:1 mapcount:0 mapping:          (null) 
index:0x0 compound_mapcount: 0 
flags: 0x100000000008100(slab|head) 
raw: 0100000000008100 0000000000000000 0000000000000000 0000000180130013 
raw: dead000000000100 dead000000000200 ffff88006741f140 0000000000000000 
page dumped because: kasan: bad access detected 

CPU: 0 PID: 4140 Comm: a.out Not tainted 4.10.0-rc3+ #59 
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 
Call Trace: 
 __dump_stack lib/dump_stack.c:15 
 dump_stack+0x292/0x398 lib/dump_stack.c:51 
 describe_address mm/kasan/report.c:262 
 kasan_report_error+0x121/0x560 mm/kasan/report.c:370 
 kasan_report mm/kasan/report.c:392 
 __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:413 
 sock_flag ./arch/x86/include/asm/bitops.h:324 
 sock_wfree+0x118/0x120 net/core/sock.c:1631 
 skb_release_head_state+0xfc/0x250 net/core/skbuff.c:655 
 skb_release_all+0x15/0x60 net/core/skbuff.c:668 
 __kfree_skb+0x15/0x20 net/core/skbuff.c:684 
 kfree_skb+0x16e/0x4e0 net/core/skbuff.c:705 
 inet_frag_destroy+0x121/0x290 net/ipv4/inet_fragment.c:304 
 inet_frag_put ./include/net/inet_frag.h:133 
 nf_ct_frag6_gather+0x1125/0x38b0 net/ipv6/netfilter/nf_conntrack_reasm.c:617 
 ipv6_defrag+0x21b/0x350 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c:68 
 nf_hook_entry_hookfn ./include/linux/netfilter.h:102 
 nf_hook_slow+0xc3/0x290 net/netfilter/core.c:310 
 nf_hook ./include/linux/netfilter.h:212 
 __ip6_local_out+0x52c/0xaf0 net/ipv6/output_core.c:160 
 ip6_local_out+0x2d/0x170 net/ipv6/output_core.c:170 
 ip6_send_skb+0xa1/0x340 net/ipv6/ip6_output.c:1722 
 ip6_push_pending_frames+0xb3/0xe0 net/ipv6/ip6_output.c:1742 
 rawv6_push_pending_frames net/ipv6/raw.c:613 
 rawv6_sendmsg+0x2cff/0x4130 net/ipv6/raw.c:927 
 inet_sendmsg+0x164/0x5b0 net/ipv4/af_inet.c:744 
 sock_sendmsg_nosec net/socket.c:635 
 sock_sendmsg+0xca/0x110 net/socket.c:645 
 sock_write_iter+0x326/0x620 net/socket.c:848 
 new_sync_write fs/read_write.c:499 
 __vfs_write+0x483/0x760 fs/read_write.c:512 
 vfs_write+0x187/0x530 fs/read_write.c:560 
 SYSC_write fs/read_write.c:607 
 SyS_write+0xfb/0x230 fs/read_write.c:599 
 entry_SYSCALL_64_fastpath+0x1f/0xc2 arch/x86/entry/entry_64.S:203 
RIP: 0033:0x7ff26e6f5b79 
RSP: 002b:00007ff268e0ed98 EFLAGS: 00000206 ORIG_RAX: 0000000000000001 
RAX: ffffffffffffffda RBX: 00007ff268e0f9c0 RCX: 00007ff26e6f5b79 
RDX: 0000000000000010 RSI: 0000000020f50fe1 RDI: 0000000000000003 
RBP: 00007ff26ebc1220 R08: 0000000000000000 R09: 0000000000000000 
R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000000 
R13: 00007ff268e0f9c0 R14: 00007ff26efec040 R15: 0000000000000003 

The buggy address belongs to the object at ffff880062da0000 
 which belongs to the cache RAWv6 of size 1504 
The buggy address ffff880062da0060 is located 96 bytes inside 
 of 1504-byte region [ffff880062da0000, ffff880062da05e0) 

Freed by task 4113: 
 save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57 
 save_stack+0x43/0xd0 mm/kasan/kasan.c:502 
 set_track mm/kasan/kasan.c:514 
 kasan_slab_free+0x73/0xc0 mm/kasan/kasan.c:578 
 slab_free_hook mm/slub.c:1352 
 slab_free_freelist_hook mm/slub.c:1374 
 slab_free mm/slub.c:2951 
 kmem_cache_free+0xb2/0x2c0 mm/slub.c:2973 
 sk_prot_free net/core/sock.c:1377 
 __sk_destruct+0x49c/0x6e0 net/core/sock.c:1452 
 sk_destruct+0x47/0x80 net/core/sock.c:1460 
 __sk_free+0x57/0x230 net/core/sock.c:1468 
 sk_free+0x23/0x30 net/core/sock.c:1479 
 sock_put ./include/net/sock.h:1638 
 sk_common_release+0x31e/0x4e0 net/core/sock.c:2782 
 rawv6_close+0x54/0x80 net/ipv6/raw.c:1214 
 inet_release+0xed/0x1c0 net/ipv4/af_inet.c:425 
 inet6_release+0x50/0x70 net/ipv6/af_inet6.c:431 
 sock_release+0x8d/0x1e0 net/socket.c:599 
 sock_close+0x16/0x20 net/socket.c:1063 
 __fput+0x332/0x7f0 fs/file_table.c:208 
 ____fput+0x15/0x20 fs/file_table.c:244 
 task_work_run+0x19b/0x270 kernel/task_work.c:116 
 exit_task_work ./include/linux/task_work.h:21 
 do_exit+0x186b/0x2800 kernel/exit.c:839 
 do_group_exit+0x149/0x420 kernel/exit.c:943 
 SYSC_exit_group kernel/exit.c:954 
 SyS_exit_group+0x1d/0x20 kernel/exit.c:952 
 entry_SYSCALL_64_fastpath+0x1f/0xc2 arch/x86/entry/entry_64.S:203 

Allocated by task 4115: 
 save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57 
 save_stack+0x43/0xd0 mm/kasan/kasan.c:502 
 set_track mm/kasan/kasan.c:514 
 kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:605 
 kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:544 
 slab_post_alloc_hook mm/slab.h:432 
 slab_alloc_node mm/slub.c:2708 
 slab_alloc mm/slub.c:2716 
 kmem_cache_alloc+0x1af/0x250 mm/slub.c:2721 
 sk_prot_alloc+0x65/0x2a0 net/core/sock.c:1334 
 sk_alloc+0x105/0x1010 net/core/sock.c:1396 
 inet6_create+0x44d/0x1150 net/ipv6/af_inet6.c:183 
 __sock_create+0x4f6/0x880 net/socket.c:1199 
 sock_create net/socket.c:1239 
 SYSC_socket net/socket.c:1269 
 SyS_socket+0xf9/0x230 net/socket.c:1249 
 entry_SYSCALL_64_fastpath+0x1f/0xc2 arch/x86/entry/entry_64.S:203 

Memory state around the buggy address: 
 ffff880062d9ff00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc 
 ffff880062d9ff80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc 
>ffff880062da0000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 
                                                       ^ 
 ffff880062da0080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 
 ffff880062da0100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 
================================================================== 

Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv6/netfilter/nf_conntrack_reasm.c |    1 +
 net/openvswitch/conntrack.c             |    1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 9948b5ce52dad3a823edede517f17069bd7226dc..986d4ca38832b17703b09e50209ec133885c7276 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -589,6 +589,7 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
 	hdr = ipv6_hdr(skb);
 	fhdr = (struct frag_hdr *)skb_transport_header(skb);
 
+	skb_orphan(skb);
 	fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr,
 		     skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
 	if (fq == NULL) {
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index 85cd59526670681d9aa996b09597c1ac2e0405b7..e0a87776a010a3be352c0b2b71859e56c75a6b6f 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -485,7 +485,6 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key,
 	} else if (key->eth.type == htons(ETH_P_IPV6)) {
 		enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone;
 
-		skb_orphan(skb);
 		memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
 		err = nf_ct_frag6_gather(net, skb, user);
 		if (err) {

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

* Re: [PATCH net] ipv6: orphan skbs in reassembly unit
  2017-03-01 22:45 [PATCH net] ipv6: orphan skbs in reassembly unit Eric Dumazet
@ 2017-03-01 23:34 ` Joe Stringer
  2017-03-02  4:58 ` David Miller
  1 sibling, 0 replies; 3+ messages in thread
From: Joe Stringer @ 2017-03-01 23:34 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, Andrey Konovalov

On 1 March 2017 at 14:45, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> Andrey reported a use-after-free in IPv6 stack.
>
> Issue here is that we free the socket while it still has skb
> in TX path and in some queues.
>
> It happens here because IPv6 reassembly unit messes skb->truesize,
> breaking skb_set_owner_w() badly.
>
> We fixed a similar issue for IPV4 in commit 8282f27449bf ("inet: frag:
> Always orphan skbs inside ip_defrag()")
>
> ==================================================================
> BUG: KASAN: use-after-free in sock_wfree+0x118/0x120
> Read of size 8 at addr ffff880062da0060 by task a.out/4140
>
> page:ffffea00018b6800 count:1 mapcount:0 mapping:          (null)
> index:0x0 compound_mapcount: 0
> flags: 0x100000000008100(slab|head)
> raw: 0100000000008100 0000000000000000 0000000000000000 0000000180130013
> raw: dead000000000100 dead000000000200 ffff88006741f140 0000000000000000
> page dumped because: kasan: bad access detected
>
> CPU: 0 PID: 4140 Comm: a.out Not tainted 4.10.0-rc3+ #59
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> Call Trace:
>  __dump_stack lib/dump_stack.c:15
>  dump_stack+0x292/0x398 lib/dump_stack.c:51
>  describe_address mm/kasan/report.c:262
>  kasan_report_error+0x121/0x560 mm/kasan/report.c:370
>  kasan_report mm/kasan/report.c:392
>  __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:413
>  sock_flag ./arch/x86/include/asm/bitops.h:324
>  sock_wfree+0x118/0x120 net/core/sock.c:1631
>  skb_release_head_state+0xfc/0x250 net/core/skbuff.c:655
>  skb_release_all+0x15/0x60 net/core/skbuff.c:668
>  __kfree_skb+0x15/0x20 net/core/skbuff.c:684
>  kfree_skb+0x16e/0x4e0 net/core/skbuff.c:705
>  inet_frag_destroy+0x121/0x290 net/ipv4/inet_fragment.c:304
>  inet_frag_put ./include/net/inet_frag.h:133
>  nf_ct_frag6_gather+0x1125/0x38b0 net/ipv6/netfilter/nf_conntrack_reasm.c:617
>  ipv6_defrag+0x21b/0x350 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c:68
>  nf_hook_entry_hookfn ./include/linux/netfilter.h:102
>  nf_hook_slow+0xc3/0x290 net/netfilter/core.c:310
>  nf_hook ./include/linux/netfilter.h:212
>  __ip6_local_out+0x52c/0xaf0 net/ipv6/output_core.c:160
>  ip6_local_out+0x2d/0x170 net/ipv6/output_core.c:170
>  ip6_send_skb+0xa1/0x340 net/ipv6/ip6_output.c:1722
>  ip6_push_pending_frames+0xb3/0xe0 net/ipv6/ip6_output.c:1742
>  rawv6_push_pending_frames net/ipv6/raw.c:613
>  rawv6_sendmsg+0x2cff/0x4130 net/ipv6/raw.c:927
>  inet_sendmsg+0x164/0x5b0 net/ipv4/af_inet.c:744
>  sock_sendmsg_nosec net/socket.c:635
>  sock_sendmsg+0xca/0x110 net/socket.c:645
>  sock_write_iter+0x326/0x620 net/socket.c:848
>  new_sync_write fs/read_write.c:499
>  __vfs_write+0x483/0x760 fs/read_write.c:512
>  vfs_write+0x187/0x530 fs/read_write.c:560
>  SYSC_write fs/read_write.c:607
>  SyS_write+0xfb/0x230 fs/read_write.c:599
>  entry_SYSCALL_64_fastpath+0x1f/0xc2 arch/x86/entry/entry_64.S:203
> RIP: 0033:0x7ff26e6f5b79
> RSP: 002b:00007ff268e0ed98 EFLAGS: 00000206 ORIG_RAX: 0000000000000001
> RAX: ffffffffffffffda RBX: 00007ff268e0f9c0 RCX: 00007ff26e6f5b79
> RDX: 0000000000000010 RSI: 0000000020f50fe1 RDI: 0000000000000003
> RBP: 00007ff26ebc1220 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000000
> R13: 00007ff268e0f9c0 R14: 00007ff26efec040 R15: 0000000000000003
>
> The buggy address belongs to the object at ffff880062da0000
>  which belongs to the cache RAWv6 of size 1504
> The buggy address ffff880062da0060 is located 96 bytes inside
>  of 1504-byte region [ffff880062da0000, ffff880062da05e0)
>
> Freed by task 4113:
>  save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
>  save_stack+0x43/0xd0 mm/kasan/kasan.c:502
>  set_track mm/kasan/kasan.c:514
>  kasan_slab_free+0x73/0xc0 mm/kasan/kasan.c:578
>  slab_free_hook mm/slub.c:1352
>  slab_free_freelist_hook mm/slub.c:1374
>  slab_free mm/slub.c:2951
>  kmem_cache_free+0xb2/0x2c0 mm/slub.c:2973
>  sk_prot_free net/core/sock.c:1377
>  __sk_destruct+0x49c/0x6e0 net/core/sock.c:1452
>  sk_destruct+0x47/0x80 net/core/sock.c:1460
>  __sk_free+0x57/0x230 net/core/sock.c:1468
>  sk_free+0x23/0x30 net/core/sock.c:1479
>  sock_put ./include/net/sock.h:1638
>  sk_common_release+0x31e/0x4e0 net/core/sock.c:2782
>  rawv6_close+0x54/0x80 net/ipv6/raw.c:1214
>  inet_release+0xed/0x1c0 net/ipv4/af_inet.c:425
>  inet6_release+0x50/0x70 net/ipv6/af_inet6.c:431
>  sock_release+0x8d/0x1e0 net/socket.c:599
>  sock_close+0x16/0x20 net/socket.c:1063
>  __fput+0x332/0x7f0 fs/file_table.c:208
>  ____fput+0x15/0x20 fs/file_table.c:244
>  task_work_run+0x19b/0x270 kernel/task_work.c:116
>  exit_task_work ./include/linux/task_work.h:21
>  do_exit+0x186b/0x2800 kernel/exit.c:839
>  do_group_exit+0x149/0x420 kernel/exit.c:943
>  SYSC_exit_group kernel/exit.c:954
>  SyS_exit_group+0x1d/0x20 kernel/exit.c:952
>  entry_SYSCALL_64_fastpath+0x1f/0xc2 arch/x86/entry/entry_64.S:203
>
> Allocated by task 4115:
>  save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
>  save_stack+0x43/0xd0 mm/kasan/kasan.c:502
>  set_track mm/kasan/kasan.c:514
>  kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:605
>  kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:544
>  slab_post_alloc_hook mm/slab.h:432
>  slab_alloc_node mm/slub.c:2708
>  slab_alloc mm/slub.c:2716
>  kmem_cache_alloc+0x1af/0x250 mm/slub.c:2721
>  sk_prot_alloc+0x65/0x2a0 net/core/sock.c:1334
>  sk_alloc+0x105/0x1010 net/core/sock.c:1396
>  inet6_create+0x44d/0x1150 net/ipv6/af_inet6.c:183
>  __sock_create+0x4f6/0x880 net/socket.c:1199
>  sock_create net/socket.c:1239
>  SYSC_socket net/socket.c:1269
>  SyS_socket+0xf9/0x230 net/socket.c:1249
>  entry_SYSCALL_64_fastpath+0x1f/0xc2 arch/x86/entry/entry_64.S:203
>
> Memory state around the buggy address:
>  ffff880062d9ff00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>  ffff880062d9ff80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>ffff880062da0000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>                                                        ^
>  ffff880062da0080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>  ffff880062da0100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ==================================================================
>
> Reported-by: Andrey Konovalov <andreyknvl@google.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>

For reference, I suggested a very similar change last year:
https://patchwork.ozlabs.org/patch/610116/

At that time, I linked it to this commit:
Fixes: 029f7f3b8701 ("netfilter: ipv6: nf_defrag: avoid/free clone operations")

I'm happy with the change from OVS side.

Acked-by: Joe Stringer <joe@ovn.org>

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

* Re: [PATCH net] ipv6: orphan skbs in reassembly unit
  2017-03-01 22:45 [PATCH net] ipv6: orphan skbs in reassembly unit Eric Dumazet
  2017-03-01 23:34 ` Joe Stringer
@ 2017-03-02  4:58 ` David Miller
  1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2017-03-02  4:58 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, andreyknvl

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 01 Mar 2017 14:45:06 -0800

> From: Eric Dumazet <edumazet@google.com>
> 
> Andrey reported a use-after-free in IPv6 stack.
> 
> Issue here is that we free the socket while it still has skb
> in TX path and in some queues.
> 
> It happens here because IPv6 reassembly unit messes skb->truesize,
> breaking skb_set_owner_w() badly.
> 
> We fixed a similar issue for IPV4 in commit 8282f27449bf ("inet: frag:
> Always orphan skbs inside ip_defrag()")
 ...
> Reported-by: Andrey Konovalov <andreyknvl@google.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied and queued up for -stable.

Thanks.

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

end of thread, other threads:[~2017-03-02 10:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-01 22:45 [PATCH net] ipv6: orphan skbs in reassembly unit Eric Dumazet
2017-03-01 23:34 ` Joe Stringer
2017-03-02  4:58 ` David Miller

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).