linux/net/ipv4
Christoph Paasch dfea2aa654 tcp: Do not call tcp_fastopen_reset_cipher from interrupt context
tcp_fastopen_reset_cipher really cannot be called from interrupt
context. It allocates the tcp_fastopen_context with GFP_KERNEL and
calls crypto_alloc_cipher, which allocates all kind of stuff with
GFP_KERNEL.

Thus, we might sleep when the key-generation is triggered by an
incoming TFO cookie-request which would then happen in interrupt-
context, as shown by enabling CONFIG_DEBUG_ATOMIC_SLEEP:

[   36.001813] BUG: sleeping function called from invalid context at mm/slub.c:1266
[   36.003624] in_atomic(): 1, irqs_disabled(): 0, pid: 1016, name: packetdrill
[   36.004859] CPU: 1 PID: 1016 Comm: packetdrill Not tainted 4.1.0-rc7 #14
[   36.006085] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014
[   36.008250]  00000000000004f2 ffff88007f8838a8 ffffffff8171d53a ffff880075a084a8
[   36.009630]  ffff880075a08000 ffff88007f8838c8 ffffffff810967d3 ffff88007f883928
[   36.011076]  0000000000000000 ffff88007f8838f8 ffffffff81096892 ffff88007f89be00
[   36.012494] Call Trace:
[   36.012953]  <IRQ>  [<ffffffff8171d53a>] dump_stack+0x4f/0x6d
[   36.014085]  [<ffffffff810967d3>] ___might_sleep+0x103/0x170
[   36.015117]  [<ffffffff81096892>] __might_sleep+0x52/0x90
[   36.016117]  [<ffffffff8118e887>] kmem_cache_alloc_trace+0x47/0x190
[   36.017266]  [<ffffffff81680d82>] ? tcp_fastopen_reset_cipher+0x42/0x130
[   36.018485]  [<ffffffff81680d82>] tcp_fastopen_reset_cipher+0x42/0x130
[   36.019679]  [<ffffffff81680f01>] tcp_fastopen_init_key_once+0x61/0x70
[   36.020884]  [<ffffffff81680f2c>] __tcp_fastopen_cookie_gen+0x1c/0x60
[   36.022058]  [<ffffffff816814ff>] tcp_try_fastopen+0x58f/0x730
[   36.023118]  [<ffffffff81671788>] tcp_conn_request+0x3e8/0x7b0
[   36.024185]  [<ffffffff810e3872>] ? __module_text_address+0x12/0x60
[   36.025327]  [<ffffffff8167b2e1>] tcp_v4_conn_request+0x51/0x60
[   36.026410]  [<ffffffff816727e0>] tcp_rcv_state_process+0x190/0xda0
[   36.027556]  [<ffffffff81661f97>] ? __inet_lookup_established+0x47/0x170
[   36.028784]  [<ffffffff8167c2ad>] tcp_v4_do_rcv+0x16d/0x3d0
[   36.029832]  [<ffffffff812e6806>] ? security_sock_rcv_skb+0x16/0x20
[   36.030936]  [<ffffffff8167cc8a>] tcp_v4_rcv+0x77a/0x7b0
[   36.031875]  [<ffffffff816af8c3>] ? iptable_filter_hook+0x33/0x70
[   36.032953]  [<ffffffff81657d22>] ip_local_deliver_finish+0x92/0x1f0
[   36.034065]  [<ffffffff81657f1a>] ip_local_deliver+0x9a/0xb0
[   36.035069]  [<ffffffff81657c90>] ? ip_rcv+0x3d0/0x3d0
[   36.035963]  [<ffffffff81657569>] ip_rcv_finish+0x119/0x330
[   36.036950]  [<ffffffff81657ba7>] ip_rcv+0x2e7/0x3d0
[   36.037847]  [<ffffffff81610652>] __netif_receive_skb_core+0x552/0x930
[   36.038994]  [<ffffffff81610a57>] __netif_receive_skb+0x27/0x70
[   36.040033]  [<ffffffff81610b72>] process_backlog+0xd2/0x1f0
[   36.041025]  [<ffffffff81611482>] net_rx_action+0x122/0x310
[   36.042007]  [<ffffffff81076743>] __do_softirq+0x103/0x2f0
[   36.042978]  [<ffffffff81723e3c>] do_softirq_own_stack+0x1c/0x30

This patch moves the call to tcp_fastopen_init_key_once to the places
where a listener socket creates its TFO-state, which always happens in
user-context (either from the setsockopt, or implicitly during the
listen()-call)

Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
Fixes: 222e83d2e0 ("tcp: switch tcp_fastopen key generation to net_get_random_once")
Signed-off-by: Christoph Paasch <cpaasch@apple.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2015-06-23 02:38:10 -07:00
..
netfilter netfilter: ensure number of counters is >0 in do_replace() 2015-05-20 13:46:49 +02:00
af_inet.c tcp: Do not call tcp_fastopen_reset_cipher from interrupt context 2015-06-23 02:38:10 -07:00
ah4.c ipsec: Remove obsolete MAX_AH_AUTH_LEN 2014-09-18 10:54:36 +02:00
arp.c netfilter: Pass socket pointer down through okfn(). 2015-04-07 15:25:55 -04:00
cipso_ipv4.c ipv4: coding style: comparison for inequality with NULL 2015-04-03 12:11:15 -04:00
datagram.c net: Save TX flow hash in sock and set in skbuf on xmit 2014-07-07 21:14:21 -07:00
devinet.c ipv4: coding style: comparison for inequality with NULL 2015-04-03 12:11:15 -04:00
esp4.c esp4: Use high-order sequence number bits for IV generation 2015-05-13 09:34:53 +02:00
fib_frontend.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2015-04-06 22:34:15 -04:00
fib_lookup.h ipv4: FIB Local/MAIN table collapse 2015-03-11 16:22:14 -04:00
fib_rules.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
fib_semantics.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
fib_trie.c ipv4: fill in table id when replacing a route 2015-05-22 14:33:17 -04:00
fou.c fou: avoid missing unlock in failure path 2015-04-16 12:11:19 -04:00
geneve.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2015-04-14 15:44:14 -04:00
gre_demux.c net: Fix GRE RX to use skb_transport_header for GRE header offset 2014-09-08 15:23:05 -07:00
gre_offload.c ipv4: coding style: comparison for inequality with NULL 2015-04-03 12:11:15 -04:00
icmp.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
igmp.c ipv4: coding style: comparison for inequality with NULL 2015-04-03 12:11:15 -04:00
inet_connection_sock.c inet: fix possible panic in reqsk_queue_unlink() 2015-04-24 11:39:15 -04:00
inet_diag.c tcp: prepare CC get_info() access from getsockopt() 2015-04-29 17:10:38 -04:00
inet_fragment.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
inet_hashtables.c tcp/dccp: get rid of central timewait timer 2015-04-13 16:40:05 -04:00
inet_lro.c lro: remove dead code 2013-12-29 16:34:25 -05:00
inet_timewait_sock.c tcp/dccp: get rid of central timewait timer 2015-04-13 16:40:05 -04:00
inetpeer.c inet: remove dead inetpeer sequence code 2014-09-08 16:42:42 -07:00
ip_forward.c ip_forward: Drop frames with attached skb->sk 2015-04-20 14:07:33 -04:00
ip_fragment.c ipv4: coding style: comparison for inequality with NULL 2015-04-03 12:11:15 -04:00
ip_gre.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
ip_input.c netfilter: Pass socket pointer down through okfn(). 2015-04-07 15:25:55 -04:00
ip_options.c ipv4: coding style: comparison for inequality with NULL 2015-04-03 12:11:15 -04:00
ip_output.c net: remove extra newlines 2015-04-07 22:24:37 -04:00
ip_sockglue.c ipv4: coding style: comparison for inequality with NULL 2015-04-03 12:11:15 -04:00
ip_tunnel_core.c ipv4: ip_tunnel: use net namespace from rtable not socket 2015-04-08 12:09:42 -04:00
ip_tunnel.c udp_tunnel: Pass UDP socket down through udp_tunnel{, 6}_xmit_skb(). 2015-04-07 15:29:08 -04:00
ip_vti.c ip_vti/ip6_vti: Preserve skb->mark after rcv_cb call 2015-05-28 06:23:32 +02:00
ipcomp.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
ipconfig.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
ipip.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
ipmr.c netfilter: Pass socket pointer down through okfn(). 2015-04-07 15:25:55 -04:00
Kconfig net: Move fou_build_header into fou.c and refactor 2014-11-05 16:30:02 -05:00
Makefile net: Add Geneve tunneling protocol driver 2014-10-06 00:32:20 -04:00
netfilter.c netfilter: Use nf_hook_state in nf_queue_entry. 2015-04-04 12:25:22 -04:00
ping.c ipv4: Missing sk_nulls_node_init() in ping_unhash(). 2015-05-01 22:02:47 -04:00
proc.c tcp/dccp: get rid of central timewait timer 2015-04-13 16:40:05 -04:00
protocol.c net: Export inet_offloads and inet6_offloads 2014-09-19 17:15:31 -04:00
raw.c Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-04-13 18:18:05 -04:00
route.c ipv4: Avoid crashing in ip_error 2015-05-22 14:23:40 -04:00
syncookies.c tcp: fix ipv4 mapped request socks 2015-03-25 00:57:48 -04:00
sysctl_net_ipv4.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
tcp_bic.c tcp: stretch ACK fixes prep 2015-01-28 22:18:37 -08:00
tcp_cong.c tcp: fix child sockets to use system default congestion control if not set 2015-05-31 21:49:14 -07:00
tcp_cubic.c tcp: restore 1.5x per RTT limit to CUBIC cwnd growth in congestion avoidance 2015-03-11 16:51:51 -04:00
tcp_dctcp.c tcp: prepare CC get_info() access from getsockopt() 2015-04-29 17:10:38 -04:00
tcp_diag.c ipv4: coding style: comparison for inequality with NULL 2015-04-03 12:11:15 -04:00
tcp_fastopen.c tcp: Do not call tcp_fastopen_reset_cipher from interrupt context 2015-06-23 02:38:10 -07:00
tcp_highspeed.c tcp: whitespace fixes 2014-09-01 18:12:45 -07:00
tcp_htcp.c tcp: whitespace fixes 2014-09-01 18:12:45 -07:00
tcp_hybla.c tcp: whitespace fixes 2014-09-01 18:12:45 -07:00
tcp_illinois.c tcp: prepare CC get_info() access from getsockopt() 2015-04-29 17:10:38 -04:00
tcp_input.c tcp: fix a potential deadlock in tcp_get_info() 2015-05-22 13:46:06 -04:00
tcp_ipv4.c inet: fix possible panic in reqsk_queue_unlink() 2015-04-24 11:39:15 -04:00
tcp_lp.c tcp: remove in_flight parameter from cong_avoid() methods 2014-05-03 19:23:07 -04:00
tcp_memcontrol.c memcg: cleanup static keys decrement 2015-02-12 18:54:10 -08:00
tcp_metrics.c tcp: RFC7413 option support for Fast Open client 2015-04-07 18:36:39 -04:00
tcp_minisocks.c tcp: fix child sockets to use system default congestion control if not set 2015-05-31 21:49:14 -07:00
tcp_offload.c tcp: cleanup static functions 2015-02-28 16:56:51 -05:00
tcp_output.c tcp: avoid looping in tcp_send_fin() 2015-04-24 11:06:48 -04:00
tcp_probe.c tcp: whitespace fixes 2014-09-01 18:12:45 -07:00
tcp_scalable.c tcp: stretch ACK fixes prep 2015-01-28 22:18:37 -08:00
tcp_timer.c tcp: RFC7413 option support for Fast Open client 2015-04-07 18:36:39 -04:00
tcp_vegas.c tcp: prepare CC get_info() access from getsockopt() 2015-04-29 17:10:38 -04:00
tcp_vegas.h tcp: prepare CC get_info() access from getsockopt() 2015-04-29 17:10:38 -04:00
tcp_veno.c tcp: stretch ACK fixes prep 2015-01-28 22:18:37 -08:00
tcp_westwood.c tcp_westwood: fix tcp_westwood_info() 2015-05-05 19:50:09 -04:00
tcp_yeah.c tcp: stretch ACK fixes prep 2015-01-28 22:18:37 -08:00
tcp.c tcp: Do not call tcp_fastopen_reset_cipher from interrupt context 2015-06-23 02:38:10 -07:00
tunnel4.c
udp_diag.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
udp_impl.h net: Remove iocb argument from sendmsg and recvmsg 2015-03-02 13:06:31 -05:00
udp_offload.c ipv4: coding style: comparison for inequality with NULL 2015-04-03 12:11:15 -04:00
udp_tunnel.c udp_tunnel: Pass UDP socket down through udp_tunnel{, 6}_xmit_skb(). 2015-04-07 15:29:08 -04:00
udp.c ipv4/udp: Verify multicast group is ours in upd_v4_early_demux() 2015-06-04 00:46:26 -07:00
udplite.c net: Eliminate no_check from protosw 2014-05-23 16:28:53 -04:00
xfrm4_input.c netfilter: Pass socket pointer down through okfn(). 2015-04-07 15:25:55 -04:00
xfrm4_mode_beet.c ipv4: ERROR: code indent should use tabs where possible 2013-12-26 13:43:21 -05:00
xfrm4_mode_transport.c
xfrm4_mode_tunnel.c ipv4: hash net ptr into fragmentation bucket selection 2015-03-25 14:07:04 -04:00
xfrm4_output.c netfilter: Pass socket pointer down through okfn(). 2015-04-07 15:25:55 -04:00
xfrm4_policy.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
xfrm4_protocol.c xfrm4: Remove duplicate semicolon 2014-06-30 07:49:47 +02:00
xfrm4_state.c inet: make no_pmtu_disc per namespace and kill ipv4_config 2013-12-18 16:58:20 -05:00
xfrm4_tunnel.c