* [PATCH v3 net] dccp/tcp: fix ireq->opt races
@ 2017-10-19 22:24 Eric Dumazet
2017-10-20 6:04 ` David Miller
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Eric Dumazet @ 2017-10-19 22:24 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
syzkaller found another bug in DCCP/TCP stacks [1]
For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix
ireq->pktopts race"), we need to make sure we do not access
ireq->opt unless we own the request sock.
[1]
BUG: KASAN: use-after-free in ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474
Read of size 1 at addr ffff8801c951039c by task syz-executor5/3295
CPU: 1 PID: 3295 Comm: syz-executor5 Not tainted 4.14.0-rc4+ #80
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:16 [inline]
dump_stack+0x194/0x257 lib/dump_stack.c:52
print_address_description+0x73/0x250 mm/kasan/report.c:252
kasan_report_error mm/kasan/report.c:351 [inline]
kasan_report+0x25b/0x340 mm/kasan/report.c:409
__asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:427
ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474
tcp_transmit_skb+0x1ab7/0x3840 net/ipv4/tcp_output.c:1135
tcp_send_ack.part.37+0x3bb/0x650 net/ipv4/tcp_output.c:3587
tcp_send_ack+0x49/0x60 net/ipv4/tcp_output.c:3557
__tcp_ack_snd_check+0x2c6/0x4b0 net/ipv4/tcp_input.c:5072
tcp_ack_snd_check net/ipv4/tcp_input.c:5085 [inline]
tcp_rcv_state_process+0x2eff/0x4850 net/ipv4/tcp_input.c:6071
tcp_child_process+0x342/0x990 net/ipv4/tcp_minisocks.c:816
tcp_v4_rcv+0x1827/0x2f80 net/ipv4/tcp_ipv4.c:1682
ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257
dst_input include/net/dst.h:464 [inline]
ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493
__netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476
__netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514
netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587
netif_receive_skb+0xae/0x390 net/core/dev.c:4611
tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372
tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766
tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792
call_write_iter include/linux/fs.h:1770 [inline]
new_sync_write fs/read_write.c:468 [inline]
__vfs_write+0x68a/0x970 fs/read_write.c:481
vfs_write+0x18f/0x510 fs/read_write.c:543
SYSC_write fs/read_write.c:588 [inline]
SyS_write+0xef/0x220 fs/read_write.c:580
entry_SYSCALL_64_fastpath+0x1f/0xbe
RIP: 0033:0x40c341
RSP: 002b:00007f469523ec10 EFLAGS: 00000293 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000000000718000 RCX: 000000000040c341
RDX: 0000000000000037 RSI: 0000000020004000 RDI: 0000000000000015
RBP: 0000000000000086 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000000f4240 R11: 0000000000000293 R12: 00000000004b7fd1
R13: 00000000ffffffff R14: 0000000020000000 R15: 0000000000025000
Allocated by task 3295:
save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459 [inline]
kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
__do_kmalloc mm/slab.c:3725 [inline]
__kmalloc+0x162/0x760 mm/slab.c:3734
kmalloc include/linux/slab.h:498 [inline]
tcp_v4_save_options include/net/tcp.h:1962 [inline]
tcp_v4_init_req+0x2d3/0x3e0 net/ipv4/tcp_ipv4.c:1271
tcp_conn_request+0xf6d/0x3410 net/ipv4/tcp_input.c:6283
tcp_v4_conn_request+0x157/0x210 net/ipv4/tcp_ipv4.c:1313
tcp_rcv_state_process+0x8ea/0x4850 net/ipv4/tcp_input.c:5857
tcp_v4_do_rcv+0x55c/0x7d0 net/ipv4/tcp_ipv4.c:1482
tcp_v4_rcv+0x2d10/0x2f80 net/ipv4/tcp_ipv4.c:1711
ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257
dst_input include/net/dst.h:464 [inline]
ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493
__netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476
__netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514
netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587
netif_receive_skb+0xae/0x390 net/core/dev.c:4611
tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372
tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766
tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792
call_write_iter include/linux/fs.h:1770 [inline]
new_sync_write fs/read_write.c:468 [inline]
__vfs_write+0x68a/0x970 fs/read_write.c:481
vfs_write+0x18f/0x510 fs/read_write.c:543
SYSC_write fs/read_write.c:588 [inline]
SyS_write+0xef/0x220 fs/read_write.c:580
entry_SYSCALL_64_fastpath+0x1f/0xbe
Freed by task 3306:
save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459 [inline]
kasan_slab_free+0x71/0xc0 mm/kasan/kasan.c:524
__cache_free mm/slab.c:3503 [inline]
kfree+0xca/0x250 mm/slab.c:3820
inet_sock_destruct+0x59d/0x950 net/ipv4/af_inet.c:157
__sk_destruct+0xfd/0x910 net/core/sock.c:1560
sk_destruct+0x47/0x80 net/core/sock.c:1595
__sk_free+0x57/0x230 net/core/sock.c:1603
sk_free+0x2a/0x40 net/core/sock.c:1614
sock_put include/net/sock.h:1652 [inline]
inet_csk_complete_hashdance+0xd5/0xf0 net/ipv4/inet_connection_sock.c:959
tcp_check_req+0xf4d/0x1620 net/ipv4/tcp_minisocks.c:765
tcp_v4_rcv+0x17f6/0x2f80 net/ipv4/tcp_ipv4.c:1675
ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257
dst_input include/net/dst.h:464 [inline]
ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493
__netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476
__netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514
netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587
netif_receive_skb+0xae/0x390 net/core/dev.c:4611
tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372
tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766
tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792
call_write_iter include/linux/fs.h:1770 [inline]
new_sync_write fs/read_write.c:468 [inline]
__vfs_write+0x68a/0x970 fs/read_write.c:481
vfs_write+0x18f/0x510 fs/read_write.c:543
SYSC_write fs/read_write.c:588 [inline]
SyS_write+0xef/0x220 fs/read_write.c:580
entry_SYSCALL_64_fastpath+0x1f/0xbe
Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets")
Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table")
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
v3: fixed the whit space mangling
v2: removed some lines from KASAN report that confuse patchwork.
include/net/inet_sock.h | 2 +-
net/dccp/ipv4.c | 13 ++++++++-----
net/ipv4/inet_connection_sock.c | 8 +++-----
net/ipv4/syncookies.c | 2 +-
net/ipv4/tcp_input.c | 2 +-
net/ipv4/tcp_ipv4.c | 22 +++++++++++++---------
6 files changed, 27 insertions(+), 22 deletions(-)
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index aa95053dfc78d35d04aef276e2a5dce7343f72a0..425752f768d2f1a0efb13964204e07f27609e9db 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -96,7 +96,7 @@ struct inet_request_sock {
kmemcheck_bitfield_end(flags);
u32 ir_mark;
union {
- struct ip_options_rcu *opt;
+ struct ip_options_rcu __rcu *ireq_opt;
#if IS_ENABLED(CONFIG_IPV6)
struct {
struct ipv6_txoptions *ipv6_opt;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 001c08696334bba0ceb896c116e595b814af0667..0490916864f93d5466e87f5b97dc524b3ee57a2e 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -414,8 +414,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
sk_daddr_set(newsk, ireq->ir_rmt_addr);
sk_rcv_saddr_set(newsk, ireq->ir_loc_addr);
newinet->inet_saddr = ireq->ir_loc_addr;
- newinet->inet_opt = ireq->opt;
- ireq->opt = NULL;
+ RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt));
newinet->mc_index = inet_iif(skb);
newinet->mc_ttl = ip_hdr(skb)->ttl;
newinet->inet_id = jiffies;
@@ -430,7 +429,10 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
if (__inet_inherit_port(sk, newsk) < 0)
goto put_and_exit;
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
-
+ if (*own_req)
+ ireq->ireq_opt = NULL;
+ else
+ newinet->inet_opt = NULL;
return newsk;
exit_overflow:
@@ -441,6 +443,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
__NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS);
return NULL;
put_and_exit:
+ newinet->inet_opt = NULL;
inet_csk_prepare_forced_close(newsk);
dccp_done(newsk);
goto exit;
@@ -492,7 +495,7 @@ static int dccp_v4_send_response(const struct sock *sk, struct request_sock *req
ireq->ir_rmt_addr);
err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr,
ireq->ir_rmt_addr,
- ireq->opt);
+ rcu_dereference(ireq->ireq_opt));
err = net_xmit_eval(err);
}
@@ -548,7 +551,7 @@ static void dccp_v4_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb)
static void dccp_v4_reqsk_destructor(struct request_sock *req)
{
dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg);
- kfree(inet_rsk(req)->opt);
+ kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1));
}
void dccp_syn_ack_timeout(const struct request_sock *req)
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 67aec7a106860b26c929fea1624d652c87972f04..5ec9136a7c36933cb36e5cd50058eb6cf189a7c3 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -540,9 +540,10 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk,
{
const struct inet_request_sock *ireq = inet_rsk(req);
struct net *net = read_pnet(&ireq->ireq_net);
- struct ip_options_rcu *opt = ireq->opt;
+ struct ip_options_rcu *opt;
struct rtable *rt;
+ opt = rcu_dereference(ireq->ireq_opt);
flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
sk->sk_protocol, inet_sk_flowi_flags(sk),
@@ -576,10 +577,9 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
struct flowi4 *fl4;
struct rtable *rt;
+ opt = rcu_dereference(ireq->ireq_opt);
fl4 = &newinet->cork.fl.u.ip4;
- rcu_read_lock();
- opt = rcu_dereference(newinet->inet_opt);
flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
sk->sk_protocol, inet_sk_flowi_flags(sk),
@@ -592,13 +592,11 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
goto no_route;
if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
goto route_err;
- rcu_read_unlock();
return &rt->dst;
route_err:
ip_rt_put(rt);
no_route:
- rcu_read_unlock();
__IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
return NULL;
}
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index b1bb1b3a108232d56aa82383422d68b5ff9da3ed..77cf32a80952fcf3ceff4ada946cc2d0df2411d9 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
/* We throwed the options of the initial SYN away, so we hope
* the ACK carries the same options again (see RFC1122 4.2.3.8)
*/
- ireq->opt = tcp_v4_save_options(sock_net(sk), skb);
+ RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(sock_net(sk), skb));
if (security_inet_conn_request(sk, skb, req)) {
reqsk_free(req);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c5d7656beeee29b3c92e1c8824dbf00d3fa32d28..7eec3383702bbab497a12095b55d255532ad5f60 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -6196,7 +6196,7 @@ struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops,
struct inet_request_sock *ireq = inet_rsk(req);
kmemcheck_annotate_bitfield(ireq, flags);
- ireq->opt = NULL;
+ ireq->ireq_opt = NULL;
#if IS_ENABLED(CONFIG_IPV6)
ireq->pktopts = NULL;
#endif
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 85164d4d3e537537c87d74c00172592c860d4dfb..4c43365c374c8bf868fc0b862333244ca26d5016 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -877,7 +877,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr,
ireq->ir_rmt_addr,
- ireq->opt);
+ rcu_dereference(ireq->ireq_opt));
err = net_xmit_eval(err);
}
@@ -889,7 +889,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
*/
static void tcp_v4_reqsk_destructor(struct request_sock *req)
{
- kfree(inet_rsk(req)->opt);
+ kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1));
}
#ifdef CONFIG_TCP_MD5SIG
@@ -1265,10 +1265,11 @@ static void tcp_v4_init_req(struct request_sock *req,
struct sk_buff *skb)
{
struct inet_request_sock *ireq = inet_rsk(req);
+ struct net *net = sock_net(sk_listener);
sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);
sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr);
- ireq->opt = tcp_v4_save_options(sock_net(sk_listener), skb);
+ RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb));
}
static struct dst_entry *tcp_v4_route_req(const struct sock *sk,
@@ -1355,10 +1356,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
sk_daddr_set(newsk, ireq->ir_rmt_addr);
sk_rcv_saddr_set(newsk, ireq->ir_loc_addr);
newsk->sk_bound_dev_if = ireq->ir_iif;
- newinet->inet_saddr = ireq->ir_loc_addr;
- inet_opt = ireq->opt;
- rcu_assign_pointer(newinet->inet_opt, inet_opt);
- ireq->opt = NULL;
+ newinet->inet_saddr = ireq->ir_loc_addr;
+ inet_opt = rcu_dereference(ireq->ireq_opt);
+ RCU_INIT_POINTER(newinet->inet_opt, inet_opt);
newinet->mc_index = inet_iif(skb);
newinet->mc_ttl = ip_hdr(skb)->ttl;
newinet->rcv_tos = ip_hdr(skb)->tos;
@@ -1403,9 +1403,12 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
if (__inet_inherit_port(sk, newsk) < 0)
goto put_and_exit;
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
- if (*own_req)
+ if (likely(*own_req)) {
tcp_move_syn(newtp, req);
-
+ ireq->ireq_opt = NULL;
+ } else {
+ newinet->inet_opt = NULL;
+ }
return newsk;
exit_overflow:
@@ -1416,6 +1419,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
tcp_listendrop(sk);
return NULL;
put_and_exit:
+ newinet->inet_opt = NULL;
inet_csk_prepare_forced_close(newsk);
tcp_done(newsk);
goto exit;
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3 net] dccp/tcp: fix ireq->opt races
2017-10-19 22:24 [PATCH v3 net] dccp/tcp: fix ireq->opt races Eric Dumazet
@ 2017-10-20 6:04 ` David Miller
2017-10-20 6:18 ` David Miller
2017-10-20 16:04 ` [PATCH v4 net] tcp/dccp: " Eric Dumazet
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: David Miller @ 2017-10-20 6:04 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 19 Oct 2017 15:24:49 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> syzkaller found another bug in DCCP/TCP stacks [1]
>
> For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix
> ireq->pktopts race"), we need to make sure we do not access
> ireq->opt unless we own the request sock.
...
> Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets")
> Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> v3: fixed the whit space mangling
> v2: removed some lines from KASAN report that confuse patchwork.
Much better, applied and queued up for -stable.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 net] dccp/tcp: fix ireq->opt races
2017-10-20 6:04 ` David Miller
@ 2017-10-20 6:18 ` David Miller
2017-10-20 15:58 ` Eric Dumazet
0 siblings, 1 reply; 9+ messages in thread
From: David Miller @ 2017-10-20 6:18 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
From: David Miller <davem@davemloft.net>
Date: Fri, 20 Oct 2017 07:04:58 +0100 (WEST)
> Much better, applied and queued up for -stable.
I take that back.
Please build test your changes more thoroughly.
In file included from ./arch/x86/include/asm/atomic.h:7:0,
from ./include/linux/atomic.h:4,
from ./include/linux/rcupdate.h:38,
from net/ipv4/cipso_ipv4.c:40:
net/ipv4/cipso_ipv4.c: In function ‘cipso_v4_req_setattr’:
net/ipv4/cipso_ipv4.c:1954:22: error: ‘struct inet_request_sock’ has no member named ‘opt’
opt = xchg(&req_inet->opt, opt);
^
./arch/x86/include/asm/cmpxchg.h:43:24: note: in definition of macro ‘__xchg_op’
__typeof__ (*(ptr)) __ret = (arg); \
^~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro ‘xchg’
opt = xchg(&req_inet->opt, opt);
^~~~
./arch/x86/include/asm/cmpxchg.h:43:38: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
__typeof__ (*(ptr)) __ret = (arg); \
^
./arch/x86/include/asm/cmpxchg.h:77:22: note: in expansion of macro ‘__xchg_op’
#define xchg(ptr, v) __xchg_op((ptr), (v), xchg, "")
^~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro ‘xchg’
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: ‘struct inet_request_sock’ has no member named ‘opt’
opt = xchg(&req_inet->opt, opt);
^
./arch/x86/include/asm/cmpxchg.h:44:20: note: in definition of macro ‘__xchg_op’
switch (sizeof(*(ptr))) { \
^~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro ‘xchg’
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: ‘struct inet_request_sock’ has no member named ‘opt’
opt = xchg(&req_inet->opt, opt);
^
./arch/x86/include/asm/cmpxchg.h:47:35: note: in definition of macro ‘__xchg_op’
: "+q" (__ret), "+m" (*(ptr)) \
^~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro ‘xchg’
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: ‘struct inet_request_sock’ has no member named ‘opt’
opt = xchg(&req_inet->opt, opt);
^
./arch/x86/include/asm/cmpxchg.h:52:35: note: in definition of macro ‘__xchg_op’
: "+r" (__ret), "+m" (*(ptr)) \
^~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro ‘xchg’
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: ‘struct inet_request_sock’ has no member named ‘opt’
opt = xchg(&req_inet->opt, opt);
^
./arch/x86/include/asm/cmpxchg.h:57:35: note: in definition of macro ‘__xchg_op’
: "+r" (__ret), "+m" (*(ptr)) \
^~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro ‘xchg’
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: ‘struct inet_request_sock’ has no member named ‘opt’
opt = xchg(&req_inet->opt, opt);
^
./arch/x86/include/asm/cmpxchg.h:62:35: note: in definition of macro ‘__xchg_op’
: "+r" (__ret), "+m" (*(ptr)) \
^~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro ‘xchg’
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
opt = xchg(&req_inet->opt, opt);
^
net/ipv4/cipso_ipv4.c: In function ‘cipso_v4_req_delattr’:
net/ipv4/cipso_ipv4.c:2073:16: error: ‘struct inet_request_sock’ has no member named ‘opt’
opt = req_inet->opt;
^~
net/ipv4/cipso_ipv4.c:2077:27: error: ‘struct inet_request_sock’ has no member named ‘opt’
cipso_v4_delopt(&req_inet->opt);
^~
scripts/Makefile.build:313: recipe for target 'net/ipv4/cipso_ipv4.o' failed
make[2]: *** [net/ipv4/cipso_ipv4.o] Error 1
make[2]: *** Waiting for unfinished jobs....
scripts/Makefile.build:572: recipe for target 'net/ipv4' failed
make[1]: *** [net/ipv4] Error 2
Makefile:1019: recipe for target 'net' failed
make: *** [net] Error 2
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 net] dccp/tcp: fix ireq->opt races
2017-10-20 6:18 ` David Miller
@ 2017-10-20 15:58 ` Eric Dumazet
0 siblings, 0 replies; 9+ messages in thread
From: Eric Dumazet @ 2017-10-20 15:58 UTC (permalink / raw)
To: David Miller; +Cc: netdev
On Fri, 2017-10-20 at 07:18 +0100, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Fri, 20 Oct 2017 07:04:58 +0100 (WEST)
>
> > Much better, applied and queued up for -stable.
>
> I take that back.
>
> Please build test your changes more thoroughly.
Arg, sorry for wasting your time, I will send a v4.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v4 net] tcp/dccp: fix ireq->opt races
2017-10-19 22:24 [PATCH v3 net] dccp/tcp: fix ireq->opt races Eric Dumazet
2017-10-20 6:04 ` David Miller
@ 2017-10-20 16:04 ` Eric Dumazet
2017-10-21 1:18 ` David Miller
2017-10-20 21:26 ` [PATCH v3 net] dccp/tcp: " kbuild test robot
2017-10-21 0:36 ` kbuild test robot
3 siblings, 1 reply; 9+ messages in thread
From: Eric Dumazet @ 2017-10-20 16:04 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
syzkaller found another bug in DCCP/TCP stacks [1]
For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix
ireq->pktopts race"), we need to make sure we do not access
ireq->opt unless we own the request sock.
Note the opt field is renamed to ireq_opt to ease grep games.
[1]
BUG: KASAN: use-after-free in ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474
Read of size 1 at addr ffff8801c951039c by task syz-executor5/3295
CPU: 1 PID: 3295 Comm: syz-executor5 Not tainted 4.14.0-rc4+ #80
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:16 [inline]
dump_stack+0x194/0x257 lib/dump_stack.c:52
print_address_description+0x73/0x250 mm/kasan/report.c:252
kasan_report_error mm/kasan/report.c:351 [inline]
kasan_report+0x25b/0x340 mm/kasan/report.c:409
__asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:427
ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474
tcp_transmit_skb+0x1ab7/0x3840 net/ipv4/tcp_output.c:1135
tcp_send_ack.part.37+0x3bb/0x650 net/ipv4/tcp_output.c:3587
tcp_send_ack+0x49/0x60 net/ipv4/tcp_output.c:3557
__tcp_ack_snd_check+0x2c6/0x4b0 net/ipv4/tcp_input.c:5072
tcp_ack_snd_check net/ipv4/tcp_input.c:5085 [inline]
tcp_rcv_state_process+0x2eff/0x4850 net/ipv4/tcp_input.c:6071
tcp_child_process+0x342/0x990 net/ipv4/tcp_minisocks.c:816
tcp_v4_rcv+0x1827/0x2f80 net/ipv4/tcp_ipv4.c:1682
ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257
dst_input include/net/dst.h:464 [inline]
ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493
__netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476
__netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514
netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587
netif_receive_skb+0xae/0x390 net/core/dev.c:4611
tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372
tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766
tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792
call_write_iter include/linux/fs.h:1770 [inline]
new_sync_write fs/read_write.c:468 [inline]
__vfs_write+0x68a/0x970 fs/read_write.c:481
vfs_write+0x18f/0x510 fs/read_write.c:543
SYSC_write fs/read_write.c:588 [inline]
SyS_write+0xef/0x220 fs/read_write.c:580
entry_SYSCALL_64_fastpath+0x1f/0xbe
RIP: 0033:0x40c341
RSP: 002b:00007f469523ec10 EFLAGS: 00000293 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000000000718000 RCX: 000000000040c341
RDX: 0000000000000037 RSI: 0000000020004000 RDI: 0000000000000015
RBP: 0000000000000086 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000000f4240 R11: 0000000000000293 R12: 00000000004b7fd1
R13: 00000000ffffffff R14: 0000000020000000 R15: 0000000000025000
Allocated by task 3295:
save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459 [inline]
kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
__do_kmalloc mm/slab.c:3725 [inline]
__kmalloc+0x162/0x760 mm/slab.c:3734
kmalloc include/linux/slab.h:498 [inline]
tcp_v4_save_options include/net/tcp.h:1962 [inline]
tcp_v4_init_req+0x2d3/0x3e0 net/ipv4/tcp_ipv4.c:1271
tcp_conn_request+0xf6d/0x3410 net/ipv4/tcp_input.c:6283
tcp_v4_conn_request+0x157/0x210 net/ipv4/tcp_ipv4.c:1313
tcp_rcv_state_process+0x8ea/0x4850 net/ipv4/tcp_input.c:5857
tcp_v4_do_rcv+0x55c/0x7d0 net/ipv4/tcp_ipv4.c:1482
tcp_v4_rcv+0x2d10/0x2f80 net/ipv4/tcp_ipv4.c:1711
ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257
dst_input include/net/dst.h:464 [inline]
ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493
__netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476
__netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514
netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587
netif_receive_skb+0xae/0x390 net/core/dev.c:4611
tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372
tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766
tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792
call_write_iter include/linux/fs.h:1770 [inline]
new_sync_write fs/read_write.c:468 [inline]
__vfs_write+0x68a/0x970 fs/read_write.c:481
vfs_write+0x18f/0x510 fs/read_write.c:543
SYSC_write fs/read_write.c:588 [inline]
SyS_write+0xef/0x220 fs/read_write.c:580
entry_SYSCALL_64_fastpath+0x1f/0xbe
Freed by task 3306:
save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459 [inline]
kasan_slab_free+0x71/0xc0 mm/kasan/kasan.c:524
__cache_free mm/slab.c:3503 [inline]
kfree+0xca/0x250 mm/slab.c:3820
inet_sock_destruct+0x59d/0x950 net/ipv4/af_inet.c:157
__sk_destruct+0xfd/0x910 net/core/sock.c:1560
sk_destruct+0x47/0x80 net/core/sock.c:1595
__sk_free+0x57/0x230 net/core/sock.c:1603
sk_free+0x2a/0x40 net/core/sock.c:1614
sock_put include/net/sock.h:1652 [inline]
inet_csk_complete_hashdance+0xd5/0xf0 net/ipv4/inet_connection_sock.c:959
tcp_check_req+0xf4d/0x1620 net/ipv4/tcp_minisocks.c:765
tcp_v4_rcv+0x17f6/0x2f80 net/ipv4/tcp_ipv4.c:1675
ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257
dst_input include/net/dst.h:464 [inline]
ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493
__netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476
__netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514
netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587
netif_receive_skb+0xae/0x390 net/core/dev.c:4611
tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372
tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766
tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792
call_write_iter include/linux/fs.h:1770 [inline]
new_sync_write fs/read_write.c:468 [inline]
__vfs_write+0x68a/0x970 fs/read_write.c:481
vfs_write+0x18f/0x510 fs/read_write.c:543
SYSC_write fs/read_write.c:588 [inline]
SyS_write+0xef/0x220 fs/read_write.c:580
entry_SYSCALL_64_fastpath+0x1f/0xbe
Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets")
Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table")
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
v4: Added the needed changes in net/ipv4/cipso_ipv4.c (and full build)
v3: fixed the white space mangling
v2: removed some lines from KASAN report that confuse patchwork.
include/net/inet_sock.h | 2 +-
net/dccp/ipv4.c | 13 ++++++++-----
net/ipv4/cipso_ipv4.c | 24 +++++++-----------------
net/ipv4/inet_connection_sock.c | 8 +++-----
net/ipv4/syncookies.c | 2 +-
net/ipv4/tcp_input.c | 2 +-
net/ipv4/tcp_ipv4.c | 22 +++++++++++++---------
7 files changed, 34 insertions(+), 39 deletions(-)
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index aa95053dfc78d35d04aef276e2a5dce7343f72a0..425752f768d2f1a0efb13964204e07f27609e9db 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -96,7 +96,7 @@ struct inet_request_sock {
kmemcheck_bitfield_end(flags);
u32 ir_mark;
union {
- struct ip_options_rcu *opt;
+ struct ip_options_rcu __rcu *ireq_opt;
#if IS_ENABLED(CONFIG_IPV6)
struct {
struct ipv6_txoptions *ipv6_opt;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 001c08696334bba0ceb896c116e595b814af0667..0490916864f93d5466e87f5b97dc524b3ee57a2e 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -414,8 +414,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
sk_daddr_set(newsk, ireq->ir_rmt_addr);
sk_rcv_saddr_set(newsk, ireq->ir_loc_addr);
newinet->inet_saddr = ireq->ir_loc_addr;
- newinet->inet_opt = ireq->opt;
- ireq->opt = NULL;
+ RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt));
newinet->mc_index = inet_iif(skb);
newinet->mc_ttl = ip_hdr(skb)->ttl;
newinet->inet_id = jiffies;
@@ -430,7 +429,10 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
if (__inet_inherit_port(sk, newsk) < 0)
goto put_and_exit;
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
-
+ if (*own_req)
+ ireq->ireq_opt = NULL;
+ else
+ newinet->inet_opt = NULL;
return newsk;
exit_overflow:
@@ -441,6 +443,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
__NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS);
return NULL;
put_and_exit:
+ newinet->inet_opt = NULL;
inet_csk_prepare_forced_close(newsk);
dccp_done(newsk);
goto exit;
@@ -492,7 +495,7 @@ static int dccp_v4_send_response(const struct sock *sk, struct request_sock *req
ireq->ir_rmt_addr);
err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr,
ireq->ir_rmt_addr,
- ireq->opt);
+ rcu_dereference(ireq->ireq_opt));
err = net_xmit_eval(err);
}
@@ -548,7 +551,7 @@ static void dccp_v4_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb)
static void dccp_v4_reqsk_destructor(struct request_sock *req)
{
dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg);
- kfree(inet_rsk(req)->opt);
+ kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1));
}
void dccp_syn_ack_timeout(const struct request_sock *req)
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 2ae8f54cb32148f2499f78ecbf29259db36bd207..82178cc69c9618bae69c096290a7a96a8b8bade0 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1951,7 +1951,7 @@ int cipso_v4_req_setattr(struct request_sock *req,
buf = NULL;
req_inet = inet_rsk(req);
- opt = xchg(&req_inet->opt, opt);
+ opt = xchg((__force struct ip_options_rcu **)&req_inet->ireq_opt, opt);
if (opt)
kfree_rcu(opt, rcu);
@@ -1973,11 +1973,13 @@ int cipso_v4_req_setattr(struct request_sock *req,
* values on failure.
*
*/
-static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr)
+static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr)
{
+ struct ip_options_rcu *opt = rcu_dereference_protected(*opt_ptr, 1);
int hdr_delta = 0;
- struct ip_options_rcu *opt = *opt_ptr;
+ if (!opt || opt->opt.cipso == 0)
+ return 0;
if (opt->opt.srr || opt->opt.rr || opt->opt.ts || opt->opt.router_alert) {
u8 cipso_len;
u8 cipso_off;
@@ -2039,14 +2041,10 @@ static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr)
*/
void cipso_v4_sock_delattr(struct sock *sk)
{
- int hdr_delta;
- struct ip_options_rcu *opt;
struct inet_sock *sk_inet;
+ int hdr_delta;
sk_inet = inet_sk(sk);
- opt = rcu_dereference_protected(sk_inet->inet_opt, 1);
- if (!opt || opt->opt.cipso == 0)
- return;
hdr_delta = cipso_v4_delopt(&sk_inet->inet_opt);
if (sk_inet->is_icsk && hdr_delta > 0) {
@@ -2066,15 +2064,7 @@ void cipso_v4_sock_delattr(struct sock *sk)
*/
void cipso_v4_req_delattr(struct request_sock *req)
{
- struct ip_options_rcu *opt;
- struct inet_request_sock *req_inet;
-
- req_inet = inet_rsk(req);
- opt = req_inet->opt;
- if (!opt || opt->opt.cipso == 0)
- return;
-
- cipso_v4_delopt(&req_inet->opt);
+ cipso_v4_delopt(&inet_rsk(req)->ireq_opt);
}
/**
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 67aec7a106860b26c929fea1624d652c87972f04..5ec9136a7c36933cb36e5cd50058eb6cf189a7c3 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -540,9 +540,10 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk,
{
const struct inet_request_sock *ireq = inet_rsk(req);
struct net *net = read_pnet(&ireq->ireq_net);
- struct ip_options_rcu *opt = ireq->opt;
+ struct ip_options_rcu *opt;
struct rtable *rt;
+ opt = rcu_dereference(ireq->ireq_opt);
flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
sk->sk_protocol, inet_sk_flowi_flags(sk),
@@ -576,10 +577,9 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
struct flowi4 *fl4;
struct rtable *rt;
+ opt = rcu_dereference(ireq->ireq_opt);
fl4 = &newinet->cork.fl.u.ip4;
- rcu_read_lock();
- opt = rcu_dereference(newinet->inet_opt);
flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
sk->sk_protocol, inet_sk_flowi_flags(sk),
@@ -592,13 +592,11 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
goto no_route;
if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
goto route_err;
- rcu_read_unlock();
return &rt->dst;
route_err:
ip_rt_put(rt);
no_route:
- rcu_read_unlock();
__IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
return NULL;
}
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index b1bb1b3a108232d56aa82383422d68b5ff9da3ed..77cf32a80952fcf3ceff4ada946cc2d0df2411d9 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
/* We throwed the options of the initial SYN away, so we hope
* the ACK carries the same options again (see RFC1122 4.2.3.8)
*/
- ireq->opt = tcp_v4_save_options(sock_net(sk), skb);
+ RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(sock_net(sk), skb));
if (security_inet_conn_request(sk, skb, req)) {
reqsk_free(req);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c5d7656beeee29b3c92e1c8824dbf00d3fa32d28..7eec3383702bbab497a12095b55d255532ad5f60 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -6196,7 +6196,7 @@ struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops,
struct inet_request_sock *ireq = inet_rsk(req);
kmemcheck_annotate_bitfield(ireq, flags);
- ireq->opt = NULL;
+ ireq->ireq_opt = NULL;
#if IS_ENABLED(CONFIG_IPV6)
ireq->pktopts = NULL;
#endif
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 85164d4d3e537537c87d74c00172592c860d4dfb..4c43365c374c8bf868fc0b862333244ca26d5016 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -877,7 +877,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr,
ireq->ir_rmt_addr,
- ireq->opt);
+ rcu_dereference(ireq->ireq_opt));
err = net_xmit_eval(err);
}
@@ -889,7 +889,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
*/
static void tcp_v4_reqsk_destructor(struct request_sock *req)
{
- kfree(inet_rsk(req)->opt);
+ kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1));
}
#ifdef CONFIG_TCP_MD5SIG
@@ -1265,10 +1265,11 @@ static void tcp_v4_init_req(struct request_sock *req,
struct sk_buff *skb)
{
struct inet_request_sock *ireq = inet_rsk(req);
+ struct net *net = sock_net(sk_listener);
sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);
sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr);
- ireq->opt = tcp_v4_save_options(sock_net(sk_listener), skb);
+ RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb));
}
static struct dst_entry *tcp_v4_route_req(const struct sock *sk,
@@ -1355,10 +1356,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
sk_daddr_set(newsk, ireq->ir_rmt_addr);
sk_rcv_saddr_set(newsk, ireq->ir_loc_addr);
newsk->sk_bound_dev_if = ireq->ir_iif;
- newinet->inet_saddr = ireq->ir_loc_addr;
- inet_opt = ireq->opt;
- rcu_assign_pointer(newinet->inet_opt, inet_opt);
- ireq->opt = NULL;
+ newinet->inet_saddr = ireq->ir_loc_addr;
+ inet_opt = rcu_dereference(ireq->ireq_opt);
+ RCU_INIT_POINTER(newinet->inet_opt, inet_opt);
newinet->mc_index = inet_iif(skb);
newinet->mc_ttl = ip_hdr(skb)->ttl;
newinet->rcv_tos = ip_hdr(skb)->tos;
@@ -1403,9 +1403,12 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
if (__inet_inherit_port(sk, newsk) < 0)
goto put_and_exit;
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
- if (*own_req)
+ if (likely(*own_req)) {
tcp_move_syn(newtp, req);
-
+ ireq->ireq_opt = NULL;
+ } else {
+ newinet->inet_opt = NULL;
+ }
return newsk;
exit_overflow:
@@ -1416,6 +1419,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
tcp_listendrop(sk);
return NULL;
put_and_exit:
+ newinet->inet_opt = NULL;
inet_csk_prepare_forced_close(newsk);
tcp_done(newsk);
goto exit;
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3 net] dccp/tcp: fix ireq->opt races
2017-10-19 22:24 [PATCH v3 net] dccp/tcp: fix ireq->opt races Eric Dumazet
2017-10-20 6:04 ` David Miller
2017-10-20 16:04 ` [PATCH v4 net] tcp/dccp: " Eric Dumazet
@ 2017-10-20 21:26 ` kbuild test robot
2017-10-20 21:39 ` Eric Dumazet
2017-10-21 0:36 ` kbuild test robot
3 siblings, 1 reply; 9+ messages in thread
From: kbuild test robot @ 2017-10-20 21:26 UTC (permalink / raw)
To: Eric Dumazet; +Cc: kbuild-all, David Miller, netdev
[-- Attachment #1: Type: text/plain, Size: 5982 bytes --]
Hi Eric,
[auto build test WARNING on net/master]
url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/dccp-tcp-fix-ireq-opt-races/20171021-034024
config: alpha-allmodconfig (attached as .config)
compiler: alpha-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=alpha
All warnings (new ones prefixed by >>):
In file included from arch/alpha/include/asm/atomic.h:6:0,
from include/linux/atomic.h:4,
from include/linux/rcupdate.h:38,
from net/ipv4/cipso_ipv4.c:40:
net/ipv4/cipso_ipv4.c: In function 'cipso_v4_req_setattr':
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/alpha/include/asm/cmpxchg.h:47:15: note: in definition of macro 'xchg'
__typeof__(*(ptr)) _x_ = (x); \
^~~
>> arch/alpha/include/asm/cmpxchg.h:47:27: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
__typeof__(*(ptr)) _x_ = (x); \
^
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/alpha/include/asm/cmpxchg.h:48:16: note: in definition of macro 'xchg'
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \
^~~
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/alpha/include/asm/cmpxchg.h:48:31: note: in definition of macro 'xchg'
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \
^~~
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/alpha/include/asm/cmpxchg.h:49:15: note: in definition of macro 'xchg'
sizeof(*(ptr))); \
^~~
net/ipv4/cipso_ipv4.c: In function 'cipso_v4_req_delattr':
net/ipv4/cipso_ipv4.c:2073:16: error: 'struct inet_request_sock' has no member named 'opt'
opt = req_inet->opt;
^~
net/ipv4/cipso_ipv4.c:2077:27: error: 'struct inet_request_sock' has no member named 'opt'
cipso_v4_delopt(&req_inet->opt);
^~
--
In file included from arch/alpha/include/asm/atomic.h:6:0,
from include/linux/atomic.h:4,
from include/linux/rcupdate.h:38,
from net//ipv4/cipso_ipv4.c:40:
net//ipv4/cipso_ipv4.c: In function 'cipso_v4_req_setattr':
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/alpha/include/asm/cmpxchg.h:47:15: note: in definition of macro 'xchg'
__typeof__(*(ptr)) _x_ = (x); \
^~~
>> arch/alpha/include/asm/cmpxchg.h:47:27: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
__typeof__(*(ptr)) _x_ = (x); \
^
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/alpha/include/asm/cmpxchg.h:48:16: note: in definition of macro 'xchg'
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \
^~~
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/alpha/include/asm/cmpxchg.h:48:31: note: in definition of macro 'xchg'
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \
^~~
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/alpha/include/asm/cmpxchg.h:49:15: note: in definition of macro 'xchg'
sizeof(*(ptr))); \
^~~
net//ipv4/cipso_ipv4.c: In function 'cipso_v4_req_delattr':
net//ipv4/cipso_ipv4.c:2073:16: error: 'struct inet_request_sock' has no member named 'opt'
opt = req_inet->opt;
^~
net//ipv4/cipso_ipv4.c:2077:27: error: 'struct inet_request_sock' has no member named 'opt'
cipso_v4_delopt(&req_inet->opt);
^~
vim +47 arch/alpha/include/asm/cmpxchg.h
5ba840f9 Paul Gortmaker 2012-04-02 44
5ba840f9 Paul Gortmaker 2012-04-02 45 #define xchg(ptr, x) \
5ba840f9 Paul Gortmaker 2012-04-02 46 ({ \
5ba840f9 Paul Gortmaker 2012-04-02 @47 __typeof__(*(ptr)) _x_ = (x); \
5ba840f9 Paul Gortmaker 2012-04-02 48 (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \
5ba840f9 Paul Gortmaker 2012-04-02 49 sizeof(*(ptr))); \
5ba840f9 Paul Gortmaker 2012-04-02 50 })
5ba840f9 Paul Gortmaker 2012-04-02 51
:::::: The code at line 47 was first introduced by commit
:::::: 5ba840f9da1ff96e0c6e982608a9e80e35333cc5 alpha: fix build failures from system.h dismemberment
:::::: TO: Paul Gortmaker <paul.gortmaker@windriver.com>
:::::: CC: Paul Gortmaker <paul.gortmaker@windriver.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 51526 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 net] dccp/tcp: fix ireq->opt races
2017-10-20 21:26 ` [PATCH v3 net] dccp/tcp: " kbuild test robot
@ 2017-10-20 21:39 ` Eric Dumazet
0 siblings, 0 replies; 9+ messages in thread
From: Eric Dumazet @ 2017-10-20 21:39 UTC (permalink / raw)
To: kbuild test robot; +Cc: kbuild-all, David Miller, netdev
On Sat, 2017-10-21 at 05:26 +0800, kbuild test robot wrote:
> Hi Eric,
>
> [auto build test WARNING on net/master]
Obsolete report. v4 was sent few hours ago ;)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 net] dccp/tcp: fix ireq->opt races
2017-10-19 22:24 [PATCH v3 net] dccp/tcp: fix ireq->opt races Eric Dumazet
` (2 preceding siblings ...)
2017-10-20 21:26 ` [PATCH v3 net] dccp/tcp: " kbuild test robot
@ 2017-10-21 0:36 ` kbuild test robot
3 siblings, 0 replies; 9+ messages in thread
From: kbuild test robot @ 2017-10-21 0:36 UTC (permalink / raw)
To: Eric Dumazet; +Cc: kbuild-all, David Miller, netdev
[-- Attachment #1: Type: text/plain, Size: 17847 bytes --]
Hi Eric,
[auto build test WARNING on net/master]
url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/dccp-tcp-fix-ireq-opt-races/20171021-034024
config: powerpc-ppc6xx_defconfig (attached as .config)
compiler: powerpc-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=powerpc
All warnings (new ones prefixed by >>):
In file included from arch/powerpc/include/asm/atomic.h:10:0,
from include/linux/atomic.h:4,
from include/linux/rcupdate.h:38,
from net/ipv4/cipso_ipv4.c:40:
net/ipv4/cipso_ipv4.c: In function 'cipso_v4_req_setattr':
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:203:15: note: in definition of macro 'xchg_relaxed'
__typeof__(*(ptr)) _x_ = (x); \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
>> arch/powerpc/include/asm/cmpxchg.h:203:27: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
__typeof__(*(ptr)) _x_ = (x); \
^
>> include/linux/atomic.h:65:9: note: in expansion of macro 'xchg_relaxed'
typeof(op##_relaxed(args)) __ret; \
^~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:204:16: note: in definition of macro 'xchg_relaxed'
(__typeof__(*(ptr))) __xchg_relaxed((ptr), \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:204:39: note: in definition of macro 'xchg_relaxed'
(__typeof__(*(ptr))) __xchg_relaxed((ptr), \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:205:33: note: in definition of macro 'xchg_relaxed'
(unsigned long)_x_, sizeof(*(ptr))); \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:203:15: note: in definition of macro 'xchg_relaxed'
__typeof__(*(ptr)) _x_ = (x); \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
>> arch/powerpc/include/asm/cmpxchg.h:203:27: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
__typeof__(*(ptr)) _x_ = (x); \
^
include/linux/atomic.h:67:10: note: in expansion of macro 'xchg_relaxed'
__ret = op##_relaxed(args); \
^~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:204:16: note: in definition of macro 'xchg_relaxed'
(__typeof__(*(ptr))) __xchg_relaxed((ptr), \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:204:39: note: in definition of macro 'xchg_relaxed'
(__typeof__(*(ptr))) __xchg_relaxed((ptr), \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:205:33: note: in definition of macro 'xchg_relaxed'
(unsigned long)_x_, sizeof(*(ptr))); \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net/ipv4/cipso_ipv4.c:1954:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
opt = xchg(&req_inet->opt, opt);
^
net/ipv4/cipso_ipv4.c: In function 'cipso_v4_req_delattr':
net/ipv4/cipso_ipv4.c:2073:16: error: 'struct inet_request_sock' has no member named 'opt'
opt = req_inet->opt;
^~
net/ipv4/cipso_ipv4.c:2077:27: error: 'struct inet_request_sock' has no member named 'opt'
cipso_v4_delopt(&req_inet->opt);
^~
--
In file included from arch/powerpc/include/asm/atomic.h:10:0,
from include/linux/atomic.h:4,
from include/linux/rcupdate.h:38,
from net//ipv4/cipso_ipv4.c:40:
net//ipv4/cipso_ipv4.c: In function 'cipso_v4_req_setattr':
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:203:15: note: in definition of macro 'xchg_relaxed'
__typeof__(*(ptr)) _x_ = (x); \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
>> arch/powerpc/include/asm/cmpxchg.h:203:27: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
__typeof__(*(ptr)) _x_ = (x); \
^
>> include/linux/atomic.h:65:9: note: in expansion of macro 'xchg_relaxed'
typeof(op##_relaxed(args)) __ret; \
^~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:204:16: note: in definition of macro 'xchg_relaxed'
(__typeof__(*(ptr))) __xchg_relaxed((ptr), \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:204:39: note: in definition of macro 'xchg_relaxed'
(__typeof__(*(ptr))) __xchg_relaxed((ptr), \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:205:33: note: in definition of macro 'xchg_relaxed'
(unsigned long)_x_, sizeof(*(ptr))); \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:203:15: note: in definition of macro 'xchg_relaxed'
__typeof__(*(ptr)) _x_ = (x); \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
>> arch/powerpc/include/asm/cmpxchg.h:203:27: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
__typeof__(*(ptr)) _x_ = (x); \
^
include/linux/atomic.h:67:10: note: in expansion of macro 'xchg_relaxed'
__ret = op##_relaxed(args); \
^~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:204:16: note: in definition of macro 'xchg_relaxed'
(__typeof__(*(ptr))) __xchg_relaxed((ptr), \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:204:39: note: in definition of macro 'xchg_relaxed'
(__typeof__(*(ptr))) __xchg_relaxed((ptr), \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt'
opt = xchg(&req_inet->opt, opt);
^
arch/powerpc/include/asm/cmpxchg.h:205:33: note: in definition of macro 'xchg_relaxed'
(unsigned long)_x_, sizeof(*(ptr))); \
^~~
include/linux/atomic.h:517:22: note: in expansion of macro '__atomic_op_fence'
#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__)
^~~~~~~~~~~~~~~~~
net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg'
opt = xchg(&req_inet->opt, opt);
^~~~
net//ipv4/cipso_ipv4.c:1954:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
opt = xchg(&req_inet->opt, opt);
^
net//ipv4/cipso_ipv4.c: In function 'cipso_v4_req_delattr':
net//ipv4/cipso_ipv4.c:2073:16: error: 'struct inet_request_sock' has no member named 'opt'
opt = req_inet->opt;
^~
net//ipv4/cipso_ipv4.c:2077:27: error: 'struct inet_request_sock' has no member named 'opt'
cipso_v4_delopt(&req_inet->opt);
^~
vim +203 arch/powerpc/include/asm/cmpxchg.h
ae3a197e David Howells 2012-03-28 175
ae3a197e David Howells 2012-03-28 176 static __always_inline unsigned long
26760fc1 Boqun Feng 2015-12-15 177 __xchg_relaxed(void *ptr, unsigned long x, unsigned int size)
ae3a197e David Howells 2012-03-28 178 {
ae3a197e David Howells 2012-03-28 179 switch (size) {
d0563a12 Pan Xinhui 2016-04-27 180 case 1:
d0563a12 Pan Xinhui 2016-04-27 181 return __xchg_u8_relaxed(ptr, x);
d0563a12 Pan Xinhui 2016-04-27 182 case 2:
d0563a12 Pan Xinhui 2016-04-27 183 return __xchg_u16_relaxed(ptr, x);
ae3a197e David Howells 2012-03-28 184 case 4:
26760fc1 Boqun Feng 2015-12-15 185 return __xchg_u32_relaxed(ptr, x);
ae3a197e David Howells 2012-03-28 186 #ifdef CONFIG_PPC64
ae3a197e David Howells 2012-03-28 187 case 8:
26760fc1 Boqun Feng 2015-12-15 188 return __xchg_u64_relaxed(ptr, x);
ae3a197e David Howells 2012-03-28 189 #endif
ae3a197e David Howells 2012-03-28 190 }
10d8b148 pan xinhui 2016-02-23 191 BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg_local");
ae3a197e David Howells 2012-03-28 192 return x;
ae3a197e David Howells 2012-03-28 193 }
26760fc1 Boqun Feng 2015-12-15 194 #define xchg_local(ptr,x) \
ae3a197e David Howells 2012-03-28 195 ({ \
ae3a197e David Howells 2012-03-28 196 __typeof__(*(ptr)) _x_ = (x); \
26760fc1 Boqun Feng 2015-12-15 197 (__typeof__(*(ptr))) __xchg_local((ptr), \
26760fc1 Boqun Feng 2015-12-15 198 (unsigned long)_x_, sizeof(*(ptr))); \
ae3a197e David Howells 2012-03-28 199 })
ae3a197e David Howells 2012-03-28 200
26760fc1 Boqun Feng 2015-12-15 201 #define xchg_relaxed(ptr, x) \
ae3a197e David Howells 2012-03-28 202 ({ \
ae3a197e David Howells 2012-03-28 @203 __typeof__(*(ptr)) _x_ = (x); \
26760fc1 Boqun Feng 2015-12-15 204 (__typeof__(*(ptr))) __xchg_relaxed((ptr), \
ae3a197e David Howells 2012-03-28 205 (unsigned long)_x_, sizeof(*(ptr))); \
ae3a197e David Howells 2012-03-28 206 })
ae3a197e David Howells 2012-03-28 207 /*
ae3a197e David Howells 2012-03-28 208 * Compare and exchange - if *p == old, set it to new,
ae3a197e David Howells 2012-03-28 209 * and return the old value of *p.
ae3a197e David Howells 2012-03-28 210 */
ae3a197e David Howells 2012-03-28 211
:::::: The code at line 203 was first introduced by commit
:::::: ae3a197e3d0bfe3f4bf1693723e82dc018c096f3 Disintegrate asm/system.h for PowerPC
:::::: TO: David Howells <dhowells@redhat.com>
:::::: CC: David Howells <dhowells@redhat.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 29168 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 net] tcp/dccp: fix ireq->opt races
2017-10-20 16:04 ` [PATCH v4 net] tcp/dccp: " Eric Dumazet
@ 2017-10-21 1:18 ` David Miller
0 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2017-10-21 1:18 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 20 Oct 2017 09:04:13 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> syzkaller found another bug in DCCP/TCP stacks [1]
>
> For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix
> ireq->pktopts race"), we need to make sure we do not access
> ireq->opt unless we own the request sock.
>
> Note the opt field is renamed to ireq_opt to ease grep games.
>
...
> Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets")
> Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> v4: Added the needed changes in net/ipv4/cipso_ipv4.c (and full build)
> v3: fixed the white space mangling
> v2: removed some lines from KASAN report that confuse patchwork.
Hey it compiles! :-)
Applied and queued up for -stable.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2017-10-21 1:21 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-19 22:24 [PATCH v3 net] dccp/tcp: fix ireq->opt races Eric Dumazet
2017-10-20 6:04 ` David Miller
2017-10-20 6:18 ` David Miller
2017-10-20 15:58 ` Eric Dumazet
2017-10-20 16:04 ` [PATCH v4 net] tcp/dccp: " Eric Dumazet
2017-10-21 1:18 ` David Miller
2017-10-20 21:26 ` [PATCH v3 net] dccp/tcp: " kbuild test robot
2017-10-20 21:39 ` Eric Dumazet
2017-10-21 0:36 ` kbuild test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.