* Re: [PATCH] net: rxrpc: mark expected switch fall-throughs
From: Gustavo A. R. Silva @ 2017-10-19 21:50 UTC (permalink / raw)
To: David Howells; +Cc: David S. Miller, linux-afs, netdev, linux-kernel
In-Reply-To: <3101.1508449499@warthog.procyon.org.uk>
Quoting David Howells <dhowells@redhat.com>:
>> What is the reason?
>
> Visual separation.
>
Thanks for clarifying.
--
Gustavo A. R. Silva
^ permalink raw reply
* Re: [PATCH 32/58] isdn/gigaset: Convert timers to use timer_setup()
From: Paul Bolle @ 2017-10-19 21:51 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Kees Cook, David S. Miller, Karsten Keil, Johan Hovold,
gigaset307x-common, netdev, linux-kernel
In-Reply-To: <alpine.DEB.2.20.1710192328110.2054@nanos>
On Thu, 2017-10-19 at 23:31 +0200, Thomas Gleixner wrote:
> bas_gigaset_exit()
> {
> for (i = 0; i < driver->minors; i++) {
> if (gigaset_shutdown(driver->cs + i) < 0)
>
> gigaset_shutdown(cs)
> {
> mutex_lock(&cs->mutex); <-------- Explodes here
>
> So driver->cs + i is invalid. No idea how that might be related to that
> timer conversion patch, but ....
Thanks for peeking into this!
Please note that driver->minors is one of the more embarrassing warts of the
gigaset code. It's basically hardcoded to 1 for all three drivers (including
bas_gigaset). So driver->cs itself is invalid here.
And since the patch uses
struct cardstate *cs = urb->context;
in a few places my guess is that it's really the patch that triggers this.
Thanks,
Paul Bolle
^ permalink raw reply
* [PATCH v2] net: rxrpc: mark expected switch fall-throughs
From: Gustavo A. R. Silva @ 2017-10-19 21:54 UTC (permalink / raw)
To: David Howells, David S. Miller
Cc: linux-afs, netdev, linux-kernel, Gustavo A. R. Silva
In-Reply-To: <20171019165015.Horde.gFbCP0wQxOy_VCfPCdilo2m@gator4166.hostgator.com>
In preparation to enabling -Wimplicit-fallthrough, mark switch cases
where we are expecting to fall through.
Signed-off-by: Gustavo A. R. Silva <garsilva@embeddedor.com>
---
This code was tested by compilation only (GCC 7.2.0 was used).
Please, verify if the actual intention of the code is to fall through.
Changes in v2:
Start every "Fall through" comment with capital 'F'.
Put back blank lines.
net/rxrpc/af_rxrpc.c | 2 ++
net/rxrpc/input.c | 1 +
net/rxrpc/sendmsg.c | 1 +
3 files changed, 4 insertions(+)
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index fb17552..73d5665 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -246,6 +246,7 @@ static int rxrpc_listen(struct socket *sock, int backlog)
ret = 0;
break;
}
+ /* Fall through */
default:
ret = -EBUSY;
break;
@@ -537,6 +538,7 @@ static int rxrpc_sendmsg(struct socket *sock, struct msghdr *m, size_t len)
m->msg_name = &rx->connect_srx;
m->msg_namelen = sizeof(rx->connect_srx);
}
+ /* Fall through */
case RXRPC_SERVER_BOUND:
case RXRPC_SERVER_LISTENING:
ret = rxrpc_do_sendmsg(rx, m, len);
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index e56e23e..1e37eb1 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -1125,6 +1125,7 @@ void rxrpc_data_ready(struct sock *udp_sk)
case RXRPC_PACKET_TYPE_BUSY:
if (sp->hdr.flags & RXRPC_CLIENT_INITIATED)
goto discard;
+ /* Fall through */
case RXRPC_PACKET_TYPE_DATA:
if (sp->hdr.callNumber == 0)
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
index 9ea6f97..dbe0c4d 100644
--- a/net/rxrpc/sendmsg.c
+++ b/net/rxrpc/sendmsg.c
@@ -166,6 +166,7 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
ktime_get_real());
if (!last)
break;
+ /* Fall through */
case RXRPC_CALL_SERVER_SEND_REPLY:
call->state = RXRPC_CALL_SERVER_AWAIT_ACK;
rxrpc_notify_end_tx(rx, call, notify_end_tx);
--
2.7.4
^ permalink raw reply related
* [PATCH] net: smc_close: mark expected switch fall-throughs
From: Gustavo A. R. Silva @ 2017-10-19 22:02 UTC (permalink / raw)
To: Ursula Braun, David S. Miller
Cc: linux-s390, netdev, linux-kernel, Gustavo A. R. Silva
In preparation to enabling -Wimplicit-fallthrough, mark switch cases
where we are expecting to fall through.
Notice that in this particular case I placed a "fall through" comment on
its own line, which is what GCC is expecting to find.
Signed-off-by: Gustavo A. R. Silva <garsilva@embeddedor.com>
---
net/smc/smc_close.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index f0d16fb..9b16f40 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -360,7 +360,8 @@ static void smc_close_passive_work(struct work_struct *work)
case SMC_PEERCLOSEWAIT1:
if (rxflags->peer_done_writing)
sk->sk_state = SMC_PEERCLOSEWAIT2;
- /* fall through to check for closing */
+ /* to check for closing */
+ /* fall through */
case SMC_PEERCLOSEWAIT2:
case SMC_PEERFINCLOSEWAIT:
if (!smc_cdc_rxed_any_close(&smc->conn))
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net] dccp/tcp: fix ireq->opt races
From: David Miller @ 2017-10-19 22:07 UTC (permalink / raw)
To: edumazet; +Cc: eric.dumazet, netdev
In-Reply-To: <CANn89i+=3B-i1Fo=8PWwzXJ-Tn7x8uOL7oQ02Bvx0e-KrdUQFw@mail.gmail.com>
[-- Attachment #1: Type: Text/Plain, Size: 959 bytes --]
From: Eric Dumazet <edumazet@google.com>
Date: Thu, 19 Oct 2017 07:45:09 -0700
> Can you send me this v2-net-dccp-tcp-fix-ireq--opt-races.patch file ?
>
> Here the patch applies fine.
Sure, attached.
I even just tried it again, same result:
[davem@kkuri net]$ git am --signoff v2-net-dccp-tcp-fix-ireq--opt-races.patch
Applying: dccp/tcp: fix ireq->opt races
error: patch failed: include/net/inet_sock.h:96
error: include/net/inet_sock.h: patch does not apply
error: patch failed: net/dccp/ipv4.c:414
error: net/dccp/ipv4.c: patch does not apply
error: patch failed: net/ipv4/inet_connection_sock.c:540
error: net/ipv4/inet_connection_sock.c: patch does not apply
error: patch failed: net/ipv4/syncookies.c:355
error: net/ipv4/syncookies.c: patch does not apply
error: patch failed: net/ipv4/tcp_input.c:6196
error: net/ipv4/tcp_input.c: patch does not apply
error: patch failed: net/ipv4/tcp_ipv4.c:877
error: net/ipv4/tcp_ipv4.c: patch does not apply
[-- Attachment #2: v2-net-dccp-tcp-fix-ireq--opt-races.patch --]
[-- Type: Text/X-Patch, Size: 16549 bytes --]
>From patchwork Tue Oct 17 19:55:01 2017
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v2,net] dccp/tcp: fix ireq->opt races
X-Patchwork-Submitter: Eric Dumazet <eric.dumazet@gmail.com>
X-Patchwork-Id: 827264
X-Patchwork-Delegate: davem@davemloft.net
Message-Id: <1508270101.31614.117.camel@edumazet-glaptop3.roam.corp.google.com>
To: David Miller <davem@davemloft.net>
Cc: netdev <netdev@vger.kernel.org>, edumazet@google.com
Date: Tue, 17 Oct 2017 12:55:01 -0700
From: Eric Dumazet <eric.dumazet@gmail.com>
List-Id: <netdev.vger.kernel.org>
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>
---
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
* Re: [PATCH net-next v12] openvswitch: enable NSH support
From: Yang, Yi @ 2017-10-19 21:53 UTC (permalink / raw)
To: Jiri Benc
Cc: netdev@vger.kernel.org, dev@openvswitch.org, e@erig.me,
pshelar@ovn.org, davem@davemloft.net
In-Reply-To: <20171019154118.16d906e0@griffin>
On Thu, Oct 19, 2017 at 03:41:18PM +0200, Jiri Benc wrote:
> On Thu, 19 Oct 2017 21:12:15 +0800, Yang, Yi wrote:
> > flow_key in set_nsh is got from netlink message which is set by
> > commit_nsh in user space, here is code.
>
> Isn't this the 'key' local variable that you're talking about, while I'm
> referring to the 'flow_key' parameter?
Oh, my mistake, but it is possible not to polulate nsh key in flow_key
for push_nsh then set, as Jan and I explained before, we don't
recirculate the packet after push_nsh for performance, so parse function
isn't called for NSH header, mdtype can't be gotten from flow_key yet.
Only one case is true, i.e. an ingress NSH packet is parsed then set by
changing si and ttl.
For push_nsh, my typical use scinario is push_nsh then set then output
to vxlangpe port.
>
> Jiri
^ permalink raw reply
* Re: [net PATCH] bpf: devmap fix arithmetic overflow in bitmap_size calculation
From: Alexei Starovoitov @ 2017-10-19 22:12 UTC (permalink / raw)
To: John Fastabend; +Cc: richard, davem, netdev, borkmann
In-Reply-To: <150842903200.12537.10765604428561566031.stgit@john-XPS-13-9360>
On Thu, Oct 19, 2017 at 09:03:52AM -0700, John Fastabend wrote:
> An integer overflow is possible in dev_map_bitmap_size() when
> calculating the BITS_TO_LONG logic which becomes, after macro
> replacement,
>
> (((n) + (d) - 1)/ (d))
>
> where 'n' is a __u32 and 'd' is (8 * sizeof(long)). To avoid
> overflow cast to u64 before arithmetic.
>
> Reported-by: Richard Weinberger <richard@nod.at>
> Acked-by: Daniel Borkmann <daniel@iogearbox.net>
> Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
^ permalink raw reply
* Re: [PATCH 32/58] isdn/gigaset: Convert timers to use timer_setup()
From: Paul Bolle @ 2017-10-19 22:16 UTC (permalink / raw)
To: Kees Cook
Cc: David S. Miller, Karsten Keil, Johan Hovold, gigaset307x-common,
Network Development, Thomas Gleixner, LKML
In-Reply-To: <CAGXu5j+TLfGAaHb8QLD0faaq6njuPUxStorxFSG7t_8gY-Jymw@mail.gmail.com>
On Thu, 2017-10-19 at 14:31 -0700, Kees Cook wrote:
> What I did in many other non-trivial conversions was just add an
> explicit pointer back, since that's operationally identical to what
> struct timer_list was storing in its .data field.
>
> i.e.
>
> add:
>
> struct cardstate *cs;
>
> to struct bas_cardstate, and then use this on timer entry:
>
> struct bas_cardstate *ucs = from_timer(ucs, t, $timer...);
> struct cardstate *cs = ucs->cs;
That crossed my mind too. (Honestly!) It _feels_ a bit dirty, as I have this
idea that structures having references to each other is some sort of an anti-
pattern. On the other hand: the various structures used here are, well, not
that clean already so I might as well ignore my feelings.
> and this at init:
>
> spin_lock_init(&ucs->lock);
> + ucs->cs = cs;
> - setup_timer(&ucs->timer_ctrl, req_timeout, (unsigned long) cs);
> - setup_timer(&ucs->timer_atrdy, atrdy_timeout, (unsigned long) cs);
> - setup_timer(&ucs->timer_cmd_in, cmd_in_timeout, (unsigned long) cs);
> - setup_timer(&ucs->timer_int_in, int_in_resubmit, (unsigned long) cs);
> + timer_setup(&ucs->timer_ctrl, req_timeout, 0);
> + timer_setup(&ucs->timer_atrdy, atrdy_timeout, 0);
> + timer_setup(&ucs->timer_cmd_in, cmd_in_timeout, 0);
> + timer_setup(&ucs->timer_int_in, int_in_resubmit, 0);
>
> which will avoid the urb entirely.
>
> Do you want me to send an alternative patch?
That would be nice! Please allow a few days for testing.
That testing is beyond silly, though. It requires me getting a laptop very
close to the awkward place where my ISDN setup lives. I'll spare you the
details. But that silliness again shows, I'd say, that the gigaset code mainly
exists to see if there's still a pulse in mainline ISDN. Is that enough to
bother? Or should mainline ISDN go the way of, say, IRDA?
But I digress. An alternative patch would be much appreciated.
Thanks,
Paul Bolle
^ permalink raw reply
* Re: [PATCH 18/27] bpf: Restrict kernel image access functions when the kernel is locked down
From: Alexei Starovoitov @ 2017-10-19 22:18 UTC (permalink / raw)
To: David Howells
Cc: linux-security-module, gnomes, linux-efi, matthew.garrett, gregkh,
linux-kernel, jforbes, Daniel Borkmann, David S. Miller, netdev
In-Reply-To: <150842476953.7923.18174368926573855810.stgit@warthog.procyon.org.uk>
On Thu, Oct 19, 2017 at 03:52:49PM +0100, David Howells wrote:
> From: Chun-Yi Lee <jlee@suse.com>
>
> There are some bpf functions can be used to read kernel memory:
> bpf_probe_read, bpf_probe_write_user and bpf_trace_printk. These allow
> private keys in kernel memory (e.g. the hibernation image signing key) to
> be read by an eBPF program. Prohibit those functions when the kernel is
> locked down.
>
> Signed-off-by: Chun-Yi Lee <jlee@suse.com>
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: netdev@vger.kernel.org
> ---
>
> kernel/trace/bpf_trace.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index dc498b605d5d..35e85a3fdb37 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -65,6 +65,11 @@ BPF_CALL_3(bpf_probe_read, void *, dst, u32, size, const void *, unsafe_ptr)
> {
> int ret;
>
> + if (kernel_is_locked_down("BPF")) {
> + memset(dst, 0, size);
> + return -EPERM;
> + }
That doesn't help the lockdown purpose.
If you don't trust the root the only way to prevent bpf read
memory is to disable the whole thing.
Have a single check in sys_bpf() to disallow everything if kernel_is_locked_down()
and don't add overhead to critical path like bpf_probe_read().
^ permalink raw reply
* Re: [PATCH net] dccp/tcp: fix ireq->opt races
From: Eric Dumazet @ 2017-10-19 22:21 UTC (permalink / raw)
To: David Miller; +Cc: Eric Dumazet, netdev
In-Reply-To: <20171019.230753.319918311561874519.davem@davemloft.net>
On Thu, Oct 19, 2017 at 3:07 PM, David Miller <davem@davemloft.net> wrote:
> From: Eric Dumazet <edumazet@google.com>
> Date: Thu, 19 Oct 2017 07:45:09 -0700
>
>> Can you send me this v2-net-dccp-tcp-fix-ireq--opt-races.patch file ?
>>
>> Here the patch applies fine.
>
> Sure, attached.
>
> I even just tried it again, same result:
>
Thanks David.
It is completely white space mangled (tabulations replaced by spaces.)
I have no idea how it happened, but it definitely happened on my side.
I will resend, sorry for this mess.
^ permalink raw reply
* Re: [PATCH net] net: bridge: fix returning of vlan range op errors
From: Roopa Prabhu @ 2017-10-19 22:22 UTC (permalink / raw)
To: Nikolay Aleksandrov
Cc: netdev@vger.kernel.org, bridge, stephen@networkplumber.org
In-Reply-To: <1508433452-23812-1-git-send-email-nikolay@cumulusnetworks.com>
On Thu, Oct 19, 2017 at 10:17 AM, Nikolay Aleksandrov
<nikolay@cumulusnetworks.com> wrote:
> When vlan tunnels were introduced, vlan range errors got silently
> dropped and instead 0 was returned always. Restore the previous
> behaviour and return errors to user-space.
>
> Fixes: efa5356b0d97 ("bridge: per vlan dst_metadata netlink support")
> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
> ---
Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
thanks
^ permalink raw reply
* [PATCH v3 net] dccp/tcp: fix ireq->opt races
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
* Re: Problems with mvneta
From: Sven Müller @ 2017-10-19 22:25 UTC (permalink / raw)
To: Thomas Petazzoni
Cc: Grégory Clement, Antoine Ténart, netdev, Marcin Wojtas
In-Reply-To: <20171018225557.43837338@windsurf.home>
Hi all.
First of all I'm not familiar with kernel programming at all, so please excuse me, if I don't understand everything at the first glance.
I did as you told me, and moved the mvneta folder from 4.10.10 to 4.13.7:
rm -rf linux-4.13.7-gentoo/drivers/net/ethernet/marvell
mv linux-4.10.10-gentoo/drivers/net/ethernet/marvell linux-4.13.7-gentoo/drivers/net/ethernet/marvell
This approach didn't compile. So I had to change a view lines:
--- linux-4.10.10-gentoo/drivers/net/ethernet/marvell/mvneta.c 2017-04-17 01:55:25.126007316 +0200
+++ linux-4.13.7-gentoo/drivers/net/ethernet/marvell/mvneta.c 2017-10-19 22:27:02.685114689 +0200
@@ -28,6 +28,7 @@
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/phy.h>
+#include <linux/phy_fixed.h>
#include <linux/platform_device.h>
#include <linux/skbuff.h>
#include <net/hwbm.h>
@@ -652,7 +653,8 @@
}
/* Get System Network Statistics */
-static struct rtnl_link_stats64 *
+//static struct rtnl_link_stats64 *
+static void
mvneta_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *stats)
{
@@ -687,7 +689,7 @@
stats->tx_dropped = dev->stats.tx_dropped;
- return stats;
+// return stats;
}
/* Rx descriptors helper methods */
It compiles and runs fine. After a couple of hours and testing no issues were found.
The changes with a lot of noise:
diff -ur linux-4.13.7-gentoo.orig/drivers/net/ethernet/marvell/ linux-4.13.7-gentoo/drivers/net/ethernet/marvell/
https://paste.pound-python.org/show/GoVNQqxqr2AK6abriwFH/
diff -ur linux-4.10.10-gentoo/drivers/net/ethernet/marvell/ linux-4.13.7-gentoo/drivers/net/ethernet/marvell/
https://paste.pound-python.org/show/LFkv81qeIGQTOvFDQfTZ/
Thanks a lot
Sven
Am Wed, 18 Oct 2017 22:55:57 +0200
schrieb Thomas Petazzoni <thomas.petazzoni@free-electrons.com>:
> Hello,
>
> I'm adding my colleagues Grégory Clement and Antoine Ténart in Cc, as
> well as Marcin Wojtas, who also worked on mvneta, and the netdev
> mailing list. I'm keeping your full message below so that others can
> read the context.
>
> On Wed, 18 Oct 2017 22:34:25 +0200, Sven Müller wrote:
>
> > I've found your email address in the kernel sources of the mvneta
> > driver. I didn't find a bug system on free-electrons.com. And on
> > kernel.org searching for mvneta wasn't really helpful.
>
> There is a bug tracker for the Linux kernel at
> https://bugzilla.kernel.org/. However, I indeed wouldn't be notified
> of bug reports against mvneta.
>
> > Some people including me hacked the Zyxel NSA-326 some time ago.
> > The whole thread you can find here:
> >
> > https://forum.doozan.com/read.php?2,27108
> >
> > Until kernel 4.10.10 everything worked great. I didn't test 4.11.
> > But any higher kernel version (tested 4.12., 4.13) causes network
> > problems with nfs. I described it here:
> >
> > https://forum.doozan.com/read.php?2,27108,37699#msg-37699
> >
> > Transfering files not with full speed but over a longer period of
> > time, e.g. playing music files over nfs or reading a lot of smaller
> > files causes the error:
> >
> > Sep 27 17:35:37 nas kernel: rpc-srv/tcp: nfsd: sent only 36488 when
> > sending 65644 bytes - shutting down socket
> >
> > After that message the network is down. I have to reboot the device
> > in order to get any network connectivity again. And how I wrote:
> > 4.10.10 works perfectly. 4.12 produced a lot of this errors, 4.13
> > seems to be a little bit better.
> >
> > Unfortunately I didn't find a way to reproduce this problem
> > directly. It occurs after 5 minutes up to one hour of transferring
> > files via nfs.
> >
> > If you are interested in fixing this bug, I would like to support
> > you with providing you any information I can find on my system and
> > testing.
> >
> > My kernel config, which is working in 4.10.10 and producing the nfs
> > problem in 4.12 and 4.13:
> >
> > https://paste.pound-python.org/show/RCaG9J4yBy79K3NL5F1
> >
> > and the device tree:
> >
> > https://paste.pound-python.org/show/UiLpMgUERuCddHOn6Vsp/
>
> There have been a few changes in the mvneta code between 4.10 and
> 4.12, but not many of them look potentially problematic.
>
> f95936cca6a8410ebdaf164bc5d3ade9e1de5bdb net: mvneta: Adjust six
> checks for null pointers d441b688a1bce8e2e1b43d8090738c306dd09131
> net: mvneta: Use kmalloc_array() in mvneta_txq_init()
> 5d6312ed57a909c86bb9472b2bbc012539392e7d net: mvneta: Improve two
> size determinations in mvneta_init()
> 2911063011fc7adcb43c93e9c3e9dc7798f459f5 net: mvneta: Use
> devm_kmalloc_array() in mvneta_init()
> 82960fff09bc394e2a33d5369969410699c04861 net: mvneta: fix failed to
> suspend if WOL is enabled d6956ac87b5ff6841b09c273a70de86200d82019
> net: mvneta: set rx mode during resume if interface is running
> a38d20d791fdcd79ebccda15a8308a6d8ada6e1c net: mvneta: add RGMII_RXID
> and RGMII_TXID support 9768b45ceb0bc7bdee61837afad331dd6bf7977f net:
> mvneta: support suspend and resume
> 4581be42fce5e1d208cbeb8e78df3f1b4673eff7 net: mvneta: make
> mvneta_eth_tool_ops static 9303ab2b3402b60f6c39abfdbfa4ce00fce8bee4
> net: mvneta: fix build errors when linux/phy*.h is removed from
> net/dsa.h b60a00f9c5f14695991cb77dce7e926623269d88 net: mvneta:
> implement .set_wol and .get_wol
> 6ad20165d376fa07919a70e4f43dfae564601829 drivers: net: generalize
> napi_complete_done() a29b6235560a1ed10c8e1a73bfc616a66b802b90 net:
> mvneta: add BQL support 2a90f7e1d5d04e4f1060268e0b55a2c702bbd67a net:
> mvneta: add xmit_more support
> bc1f44709cf27fb2a5766cadafe7e2ad5e9cb221 net: make ndo_get_stats64 a
> void function
>
> The only ones that really could have an impact are:
>
> 6ad20165d376fa07919a70e4f43dfae564601829 drivers: net: generalize
> napi_complete_done() a29b6235560a1ed10c8e1a73bfc616a66b802b90 net:
> mvneta: add BQL support 2a90f7e1d5d04e4f1060268e0b55a2c702bbd67a net:
> mvneta: add xmit_more support
>
> Could you try to take mvneta* from Linux 4.10, put that in Linux 4.12,
> and see if you can still produce the problem? I'd like to first make
> sure the problem really is inside mvneta, and not in some other place.
>
> Thanks!
>
> Thomas
^ permalink raw reply
* Re: [PATCH 32/58] isdn/gigaset: Convert timers to use timer_setup()
From: Thomas Gleixner @ 2017-10-19 22:28 UTC (permalink / raw)
To: Paul Bolle
Cc: Kees Cook, David S. Miller, Karsten Keil, Johan Hovold,
gigaset307x-common, netdev, linux-kernel
In-Reply-To: <1508449907.2274.28.camel@tiscali.nl>
On Thu, 19 Oct 2017, Paul Bolle wrote:
> On Thu, 2017-10-19 at 23:31 +0200, Thomas Gleixner wrote:
> > bas_gigaset_exit()
> > {
> > for (i = 0; i < driver->minors; i++) {
> > if (gigaset_shutdown(driver->cs + i) < 0)
> >
> > gigaset_shutdown(cs)
> > {
> > mutex_lock(&cs->mutex); <-------- Explodes here
> >
> > So driver->cs + i is invalid. No idea how that might be related to that
> > timer conversion patch, but ....
>
> Thanks for peeking into this!
>
> Please note that driver->minors is one of the more embarrassing warts of the
> gigaset code. It's basically hardcoded to 1 for all three drivers (including
> bas_gigaset). So driver->cs itself is invalid here.
>
> And since the patch uses
> struct cardstate *cs = urb->context;
>
> in a few places my guess is that it's really the patch that triggers this.
Well, that does not explain why
drivers->cs + i
would be corrupted. That would require that this cs -> urb link points at
driver magically and then wreckages that driver data structure. Might be
the case, but if so then there are dragons burried somehwere
Thanks,
tglx
^ permalink raw reply
* [PATCH net-next 0/8] tools: bpftool: add a "version" command, and fix several items
From: Jakub Kicinski @ 2017-10-19 22:46 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
Quentin says:
The first seven patches of this series bring several minor fixes to
bpftool. Please see individual commit logs for details.
Last patch adds a "version" commands to bpftool, which is in fact the
version of the kernel from which it was compiled.
Quentin Monnet (8):
tools: bpftool: add pointer to file argument to print_hex()
tools: bpftool: fix return value when all eBPF programs have been
shown
tools: bpftool: use err() instead of info() if there are too many
insns
tools: bpftool: add `bpftool prog help` as real command i.r.t exit
code
tools: bpftool: print only one error message on byte parsing failure
tools: bpftool: print all relevant byte opcodes for "load double word"
tools: bpftool: show that `opcodes` or `file FILE` should be exclusive
tools: bpftool: add a command to display bpftool version
tools/bpf/bpftool/Documentation/bpftool-prog.rst | 8 +++----
tools/bpf/bpftool/Documentation/bpftool.rst | 2 ++
tools/bpf/bpftool/main.c | 22 +++++++++++++----
tools/bpf/bpftool/main.h | 2 +-
tools/bpf/bpftool/map.c | 22 ++++++++---------
tools/bpf/bpftool/prog.c | 30 +++++++++++++++++-------
6 files changed, 56 insertions(+), 30 deletions(-)
--
2.14.1
^ permalink raw reply
* [PATCH net-next 1/8] tools: bpftool: add pointer to file argument to print_hex()
From: Jakub Kicinski @ 2017-10-19 22:46 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Quentin Monnet, Jakub Kicinski
In-Reply-To: <20171019224626.31608-1-jakub.kicinski@netronome.com>
From: Quentin Monnet <quentin.monnet@netronome.com>
Make print_hex() able to print to any file instead of standard output
only, and rename it to fprint_hex(). The function can now be called with
the info() macro, for example, without splitting the output between
standard and error outputs.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
tools/bpf/bpftool/main.c | 8 ++++----
tools/bpf/bpftool/main.h | 2 +-
tools/bpf/bpftool/map.c | 20 ++++++++++----------
tools/bpf/bpftool/prog.c | 4 ++--
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
index e02d00d6e00b..8662199ee050 100644
--- a/tools/bpf/bpftool/main.c
+++ b/tools/bpf/bpftool/main.c
@@ -100,7 +100,7 @@ bool is_prefix(const char *pfx, const char *str)
return !memcmp(str, pfx, strlen(pfx));
}
-void print_hex(void *arg, unsigned int n, const char *sep)
+void fprint_hex(FILE *f, void *arg, unsigned int n, const char *sep)
{
unsigned char *data = arg;
unsigned int i;
@@ -111,13 +111,13 @@ void print_hex(void *arg, unsigned int n, const char *sep)
if (!i)
/* nothing */;
else if (!(i % 16))
- printf("\n");
+ fprintf(f, "\n");
else if (!(i % 8))
- printf(" ");
+ fprintf(f, " ");
else
pfx = sep;
- printf("%s%02hhx", i ? pfx : "", data[i]);
+ fprintf(f, "%s%02hhx", i ? pfx : "", data[i]);
}
}
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index 844e4ef6db56..41e6c7d3fcad 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -67,7 +67,7 @@ enum bpf_obj_type {
extern const char *bin_name;
bool is_prefix(const char *pfx, const char *str);
-void print_hex(void *arg, unsigned int n, const char *sep);
+void fprint_hex(FILE *f, void *arg, unsigned int n, const char *sep);
void usage(void) __attribute__((noreturn));
struct cmd {
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index 0528a5379e6c..b1dad76215ed 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -216,12 +216,12 @@ static void print_entry(struct bpf_map_info *info, unsigned char *key,
!break_names;
printf("key:%c", break_names ? '\n' : ' ');
- print_hex(key, info->key_size, " ");
+ fprint_hex(stdout, key, info->key_size, " ");
printf(single_line ? " " : "\n");
printf("value:%c", break_names ? '\n' : ' ');
- print_hex(value, info->value_size, " ");
+ fprint_hex(stdout, value, info->value_size, " ");
printf("\n");
} else {
@@ -230,13 +230,13 @@ static void print_entry(struct bpf_map_info *info, unsigned char *key,
n = get_possible_cpus();
printf("key:\n");
- print_hex(key, info->key_size, " ");
+ fprint_hex(stdout, key, info->key_size, " ");
printf("\n");
for (i = 0; i < n; i++) {
printf("value (CPU %02d):%c",
i, info->value_size > 16 ? '\n' : ' ');
- print_hex(value + i * info->value_size,
- info->value_size, " ");
+ fprint_hex(stdout, value + i * info->value_size,
+ info->value_size, " ");
printf("\n");
}
}
@@ -492,8 +492,8 @@ static int do_dump(int argc, char **argv)
print_entry(&info, key, value);
} else {
info("can't lookup element with key: ");
- print_hex(key, info.key_size, " ");
- printf("\n");
+ fprint_hex(stderr, key, info.key_size, " ");
+ fprintf(stderr, "\n");
}
prev_key = key;
@@ -587,7 +587,7 @@ static int do_lookup(int argc, char **argv)
print_entry(&info, key, value);
} else if (errno == ENOENT) {
printf("key:\n");
- print_hex(key, info.key_size, " ");
+ fprint_hex(stdout, key, info.key_size, " ");
printf("\n\nNot found\n");
} else {
err("lookup failed: %s\n", strerror(errno));
@@ -642,14 +642,14 @@ static int do_getnext(int argc, char **argv)
if (key) {
printf("key:\n");
- print_hex(key, info.key_size, " ");
+ fprint_hex(stdout, key, info.key_size, " ");
printf("\n");
} else {
printf("key: None\n");
}
printf("next key:\n");
- print_hex(nextkey, info.key_size, " ");
+ fprint_hex(stdout, nextkey, info.key_size, " ");
printf("\n");
exit_free:
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index d60f5307b6e2..aa6d72ea3807 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -224,7 +224,7 @@ static int show_prog(int fd)
printf("name %s ", info.name);
printf("tag ");
- print_hex(info.tag, BPF_TAG_SIZE, "");
+ fprint_hex(stdout, info.tag, BPF_TAG_SIZE, "");
printf("\n");
if (info.load_time) {
@@ -319,7 +319,7 @@ static void dump_xlated(void *buf, unsigned int len, bool opcodes)
if (opcodes) {
printf(" ");
- print_hex(insn + i, 8, " ");
+ fprint_hex(stdout, insn + i, 8, " ");
printf("\n");
}
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 2/8] tools: bpftool: fix return value when all eBPF programs have been shown
From: Jakub Kicinski @ 2017-10-19 22:46 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Quentin Monnet, Jakub Kicinski
In-Reply-To: <20171019224626.31608-1-jakub.kicinski@netronome.com>
From: Quentin Monnet <quentin.monnet@netronome.com>
Change the program to have a more consistent return code. Specifically,
do not make bpftool return an error code simply because it reaches the
end of the list of the eBPF programs to show.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
tools/bpf/bpftool/prog.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index aa6d72ea3807..ede7957adcd9 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -275,8 +275,10 @@ static int do_show(int argc, char **argv)
while (true) {
err = bpf_prog_get_next_id(id, &id);
if (err) {
- if (errno == ENOENT)
+ if (errno == ENOENT) {
+ err = 0;
break;
+ }
err("can't get next program: %s\n", strerror(errno));
if (errno == EINVAL)
err("kernel too old?\n");
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 3/8] tools: bpftool: use err() instead of info() if there are too many insns
From: Jakub Kicinski @ 2017-10-19 22:46 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Quentin Monnet, Jakub Kicinski
In-Reply-To: <20171019224626.31608-1-jakub.kicinski@netronome.com>
From: Quentin Monnet <quentin.monnet@netronome.com>
Make error messages and return codes more consistent. Specifically,
replace the use of info() macro with err() when too many eBPF
instructions are received to be dumped, given that bpftool returns with
a non-null exit value in that case.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
tools/bpf/bpftool/prog.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index ede7957adcd9..6c03d2ea3f79 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -416,7 +416,7 @@ static int do_dump(int argc, char **argv)
}
if (*member_len > buf_size) {
- info("too many instructions returned\n");
+ err("too many instructions returned\n");
goto err_free;
}
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 4/8] tools: bpftool: add `bpftool prog help` as real command i.r.t exit code
From: Jakub Kicinski @ 2017-10-19 22:46 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Quentin Monnet, Jakub Kicinski
In-Reply-To: <20171019224626.31608-1-jakub.kicinski@netronome.com>
From: Quentin Monnet <quentin.monnet@netronome.com>
Make error messages and return codes more consistent. Specifically, make
`bpftool prog help` a real command, instead of printing usage by default
for a non-recognized "help" command. Output is the same, but this makes
bpftool return with a success value instead of an error.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
tools/bpf/bpftool/prog.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 6c03d2ea3f79..355c14325622 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -475,6 +475,7 @@ static int do_help(int argc, char **argv)
static const struct cmd cmds[] = {
{ "show", do_show },
+ { "help", do_help },
{ "dump", do_dump },
{ "pin", do_pin },
{ 0 }
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 5/8] tools: bpftool: print only one error message on byte parsing failure
From: Jakub Kicinski @ 2017-10-19 22:46 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Quentin Monnet, Jakub Kicinski
In-Reply-To: <20171019224626.31608-1-jakub.kicinski@netronome.com>
From: Quentin Monnet <quentin.monnet@netronome.com>
Make error messages more consistent. Specifically, when bpftool fails at
parsing map key bytes, make it print a single error message to stderr
and return from the function, instead of (always) printing a second
error message afterwards.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
tools/bpf/bpftool/map.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index b1dad76215ed..e1004d825392 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -252,7 +252,7 @@ static char **parse_bytes(char **argv, const char *name, unsigned char *val,
val[i] = strtoul(argv[i], &endptr, 0);
if (*endptr) {
err("error parsing byte: %s\n", argv[i]);
- break;
+ return NULL;
}
i++;
}
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 6/8] tools: bpftool: print all relevant byte opcodes for "load double word"
From: Jakub Kicinski @ 2017-10-19 22:46 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Quentin Monnet, Jakub Kicinski
In-Reply-To: <20171019224626.31608-1-jakub.kicinski@netronome.com>
From: Quentin Monnet <quentin.monnet@netronome.com>
The eBPF instruction permitting to load double words (8 bytes) into a
register need 8-byte long "immediate" field, and thus occupy twice the
space of other instructions. bpftool was aware of this and would
increment the instruction counter only once on meeting such instruction,
but it would only print the first four bytes of the immediate value to
load. Make it able to dump the whole 16 byte-long double instruction
instead (as would `llvm-objdump -d <program>`).
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
tools/bpf/bpftool/prog.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 355c14325622..57edbea2fbe8 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -313,20 +313,29 @@ static void print_insn(struct bpf_verifier_env *env, const char *fmt, ...)
static void dump_xlated(void *buf, unsigned int len, bool opcodes)
{
struct bpf_insn *insn = buf;
+ bool double_insn = false;
unsigned int i;
for (i = 0; i < len / sizeof(*insn); i++) {
+ if (double_insn) {
+ double_insn = false;
+ continue;
+ }
+
+ double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW);
+
printf("% 4d: ", i);
print_bpf_insn(print_insn, NULL, insn + i, true);
if (opcodes) {
printf(" ");
fprint_hex(stdout, insn + i, 8, " ");
+ if (double_insn && i < len - 1) {
+ printf(" ");
+ fprint_hex(stdout, insn + i + 1, 8, " ");
+ }
printf("\n");
}
-
- if (insn[i].code == (BPF_LD | BPF_IMM | BPF_DW))
- i++;
}
}
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 7/8] tools: bpftool: show that `opcodes` or `file FILE` should be exclusive
From: Jakub Kicinski @ 2017-10-19 22:46 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Quentin Monnet, Jakub Kicinski
In-Reply-To: <20171019224626.31608-1-jakub.kicinski@netronome.com>
From: Quentin Monnet <quentin.monnet@netronome.com>
For the `bpftool prog dump { jited | xlated } ...` command, adding
`opcodes` keyword (to request opcodes to be printed) will have no effect
if `file FILE` (to write binary output to FILE) is provided.
The manual page and the help message to be displayed in the terminal
should reflect that, and indicate that these options should be mutually
exclusive.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
tools/bpf/bpftool/Documentation/bpftool-prog.rst | 8 ++++----
tools/bpf/bpftool/prog.c | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
index 3968f0bd37db..69b3770370c8 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
@@ -11,8 +11,8 @@ SYNOPSIS
========
| **bpftool** prog show [*PROG*]
-| **bpftool** prog dump xlated *PROG* [file *FILE*] [opcodes]
-| **bpftool** prog dump jited *PROG* [file *FILE*] [opcodes]
+| **bpftool** prog dump xlated *PROG* [{file *FILE* | opcodes }]
+| **bpftool** prog dump jited *PROG* [{file *FILE* | opcodes }]
| **bpftool** prog pin *PROG* *FILE*
| **bpftool** prog help
|
@@ -28,14 +28,14 @@ DESCRIPTION
Output will start with program ID followed by program type and
zero or more named attributes (depending on kernel version).
- **bpftool prog dump xlated** *PROG* [**file** *FILE*] [**opcodes**]
+ **bpftool prog dump xlated** *PROG* [{ **file** *FILE* | **opcodes** }]
Dump eBPF instructions of the program from the kernel.
If *FILE* is specified image will be written to a file,
otherwise it will be disassembled and printed to stdout.
**opcodes** controls if raw opcodes will be printed.
- **bpftool prog dump jited** *PROG* [**file** *FILE*] [**opcodes**]
+ **bpftool prog dump jited** *PROG* [{ **file** *FILE* | **opcodes** }]
Dump jited image (host machine code) of the program.
If *FILE* is specified image will be written to a file,
otherwise it will be disassembled and printed to stdout.
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 57edbea2fbe8..7838206a455b 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -469,8 +469,8 @@ static int do_help(int argc, char **argv)
{
fprintf(stderr,
"Usage: %s %s show [PROG]\n"
- " %s %s dump xlated PROG [file FILE] [opcodes]\n"
- " %s %s dump jited PROG [file FILE] [opcodes]\n"
+ " %s %s dump xlated PROG [{ file FILE | opcodes }]\n"
+ " %s %s dump jited PROG [{ file FILE | opcodes }]\n"
" %s %s pin PROG FILE\n"
" %s %s help\n"
"\n"
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 8/8] tools: bpftool: add a command to display bpftool version
From: Jakub Kicinski @ 2017-10-19 22:46 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Quentin Monnet, Jakub Kicinski
In-Reply-To: <20171019224626.31608-1-jakub.kicinski@netronome.com>
From: Quentin Monnet <quentin.monnet@netronome.com>
This command can be used to print the version of the tool, which is in
fact the version from Linux taken from usr/include/linux/version.h.
Example usage:
$ bpftool version
bpftool v4.14.0
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
tools/bpf/bpftool/Documentation/bpftool.rst | 2 ++
tools/bpf/bpftool/main.c | 14 +++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/tools/bpf/bpftool/Documentation/bpftool.rst b/tools/bpf/bpftool/Documentation/bpftool.rst
index f1df1893fb54..45ad8baf1915 100644
--- a/tools/bpf/bpftool/Documentation/bpftool.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool.rst
@@ -14,6 +14,8 @@ SYNOPSIS
**bpftool** batch file *FILE*
+ **bpftool** version
+
*OBJECT* := { **map** | **program** }
*MAP-COMMANDS* :=
diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
index 8662199ee050..814d19e1b53f 100644
--- a/tools/bpf/bpftool/main.c
+++ b/tools/bpf/bpftool/main.c
@@ -37,6 +37,7 @@
#include <ctype.h>
#include <errno.h>
#include <linux/bpf.h>
+#include <linux/version.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -62,13 +63,23 @@ static int do_help(int argc, char **argv)
fprintf(stderr,
"Usage: %s OBJECT { COMMAND | help }\n"
" %s batch file FILE\n"
+ " %s version\n"
"\n"
" OBJECT := { prog | map }\n",
- bin_name, bin_name);
+ bin_name, bin_name, bin_name);
return 0;
}
+static int do_version(int argc, char **argv)
+{
+ printf("%s v%d.%d.%d\n", bin_name,
+ LINUX_VERSION_CODE >> 16,
+ LINUX_VERSION_CODE >> 8 & 0xf,
+ LINUX_VERSION_CODE & 0xf);
+ return 0;
+}
+
int cmd_select(const struct cmd *cmds, int argc, char **argv,
int (*help)(int argc, char **argv))
{
@@ -128,6 +139,7 @@ static const struct cmd cmds[] = {
{ "batch", do_batch },
{ "prog", do_prog },
{ "map", do_map },
+ { "version", do_version },
{ 0 }
};
--
2.14.1
^ permalink raw reply related
* Re: [PATCH 18/27] bpf: Restrict kernel image access functions when the kernel is locked down
From: David Howells @ 2017-10-19 22:48 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: jlee, dhowells, linux-security-module, gnomes, linux-efi, gregkh,
linux-kernel, jforbes, Daniel Borkmann, David S. Miller, netdev
In-Reply-To: <20171019221829.7m5nczg3ltqmhzom@ast-mbp>
Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> > @@ -65,6 +65,11 @@ BPF_CALL_3(bpf_probe_read, void *, dst, u32, size, const void *, unsafe_ptr)
> > {
> > int ret;
> >
> > + if (kernel_is_locked_down("BPF")) {
> > + memset(dst, 0, size);
> > + return -EPERM;
> > + }
>
> That doesn't help the lockdown purpose.
> If you don't trust the root the only way to prevent bpf read
> memory is to disable the whole thing.
> Have a single check in sys_bpf() to disallow everything if kernel_is_locked_down()
> and don't add overhead to critical path like bpf_probe_read().
TBH, I've no idea how bpf does anything, so I can't say whether this is
better, overkill or insufficient.
David
^ permalink raw reply
* Instability of i40e driver on 4.9 kernel
From: Pavlos Parissis @ 2017-10-19 23:02 UTC (permalink / raw)
To: netdev@vger.kernel.org, intel-wired-lan@lists.osuosl.org; +Cc: Alexander Duyck
[-- Attachment #1.1: Type: text/plain, Size: 1573 bytes --]
Hi all,
We have been running 4.9 kernels for several months on CentOS 7.3 and for few weeks on CentOS 7.4,
and, after we replaced 10GbE cobber cards(X540-AT2 with ixgbe driver) with X710 10GbE SFP cards
using i40e driver, we noticed sever instabilities on our servers.
On several servers the links were marked down and up again, without any obvious reasons expect a lot
of errors on kernel.log. We run Bird Internet daemon on our servers in order to establish BGP
peerings with routers and we have observed flapping on BGP peerings. At the same time we had BGP
peering stabilities issues we had kernel errors. We decided to go back to 3.10 kernel from CentOS,
but that process wasn't smooth as latest firmware gave us problems with speed detection. We rolled
back to two version old and speed detection issue was resolved. We have been running 3.10 several
weeks without any problems. Even we want certain functionality from kernel 4.9, we decided to switch
back to 3.10 as stability of our systems has higher priority.
I need to mention that in all occurrences of the issue we didn't see any anomalies, such DDOS
attacks and etc.
I have opened https://communities.intel.com/message/501682#501682 and there you can find all the
error messages and other information.
Since we noticed the issues, I have been following netdev ML and I know that there are a lot of
improvements/patched queued up for 4.14 and I am hoping those patches fix our issue and most
importantly are sent to linux-stable for inclusion in 4.9 kernel.
Cheers,
Pavlos
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox