linux/net
Alexander Sverdlin 294440ca86 sctp: Fix race between OOTB responce and route removal
[ Upstream commit 29c4afc4e9 ]

There is NULL pointer dereference possible during statistics update if the route
used for OOTB responce is removed at unfortunate time. If the route exists when
we receive OOTB packet and we finally jump into sctp_packet_transmit() to send
ABORT, but in the meantime route is removed under our feet, we take "no_route"
path and try to update stats with IP_INC_STATS(sock_net(asoc->base.sk), ...).

But sctp_ootb_pkt_new() used to prepare responce packet doesn't call
sctp_transport_set_owner() and therefore there is no asoc associated with this
packet. Probably temporary asoc just for OOTB responces is overkill, so just
introduce a check like in all other places in sctp_packet_transmit(), where
"asoc" is dereferenced.

To reproduce this, one needs to
0. ensure that sctp module is loaded (otherwise ABORT is not generated)
1. remove default route on the machine
2. while true; do
     ip route del [interface-specific route]
     ip route add [interface-specific route]
   done
3. send enough OOTB packets (i.e. HB REQs) from another host to trigger ABORT
   responce

On x86_64 the crash looks like this:

BUG: unable to handle kernel NULL pointer dereference at 0000000000000020
IP: [<ffffffffa05ec9ac>] sctp_packet_transmit+0x63c/0x730 [sctp]
PGD 0
Oops: 0000 [#1] PREEMPT SMP
Modules linked in: ...
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G           O    4.0.5-1-ARCH #1
Hardware name: ...
task: ffffffff818124c0 ti: ffffffff81800000 task.ti: ffffffff81800000
RIP: 0010:[<ffffffffa05ec9ac>]  [<ffffffffa05ec9ac>] sctp_packet_transmit+0x63c/0x730 [sctp]
RSP: 0018:ffff880127c037b8  EFLAGS: 00010296
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000015ff66b480
RDX: 00000015ff66b400 RSI: ffff880127c17200 RDI: ffff880123403700
RBP: ffff880127c03888 R08: 0000000000017200 R09: ffffffff814625af
R10: ffffea00047e4680 R11: 00000000ffffff80 R12: ffff8800b0d38a28
R13: ffff8800b0d38a28 R14: ffff8800b3e88000 R15: ffffffffa05f24e0
FS:  0000000000000000(0000) GS:ffff880127c00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000020 CR3: 00000000c855b000 CR4: 00000000000007f0
Stack:
 ffff880127c03910 ffff8800b0d38a28 ffffffff8189d240 ffff88011f91b400
 ffff880127c03828 ffffffffa05c94c5 0000000000000000 ffff8800baa1c520
 0000000000000000 0000000000000001 0000000000000000 0000000000000000
Call Trace:
 <IRQ>
 [<ffffffffa05c94c5>] ? sctp_sf_tabort_8_4_8.isra.20+0x85/0x140 [sctp]
 [<ffffffffa05d6b42>] ? sctp_transport_put+0x52/0x80 [sctp]
 [<ffffffffa05d0bfc>] sctp_do_sm+0xb8c/0x19a0 [sctp]
 [<ffffffff810b0e00>] ? trigger_load_balance+0x90/0x210
 [<ffffffff810e0329>] ? update_process_times+0x59/0x60
 [<ffffffff812c7a40>] ? timerqueue_add+0x60/0xb0
 [<ffffffff810e0549>] ? enqueue_hrtimer+0x29/0xa0
 [<ffffffff8101f599>] ? read_tsc+0x9/0x10
 [<ffffffff8116d4b5>] ? put_page+0x55/0x60
 [<ffffffff810ee1ad>] ? clockevents_program_event+0x6d/0x100
 [<ffffffff81462b68>] ? skb_free_head+0x58/0x80
 [<ffffffffa029a10b>] ? chksum_update+0x1b/0x27 [crc32c_generic]
 [<ffffffff81283f3e>] ? crypto_shash_update+0xce/0xf0
 [<ffffffffa05d3993>] sctp_endpoint_bh_rcv+0x113/0x280 [sctp]
 [<ffffffffa05dd4e6>] sctp_inq_push+0x46/0x60 [sctp]
 [<ffffffffa05ed7a0>] sctp_rcv+0x880/0x910 [sctp]
 [<ffffffffa05ecb50>] ? sctp_packet_transmit_chunk+0xb0/0xb0 [sctp]
 [<ffffffffa05ecb70>] ? sctp_csum_update+0x20/0x20 [sctp]
 [<ffffffff814b05a5>] ? ip_route_input_noref+0x235/0xd30
 [<ffffffff81051d6b>] ? ack_ioapic_level+0x7b/0x150
 [<ffffffff814b27be>] ip_local_deliver_finish+0xae/0x210
 [<ffffffff814b2e15>] ip_local_deliver+0x35/0x90
 [<ffffffff814b2a15>] ip_rcv_finish+0xf5/0x370
 [<ffffffff814b3128>] ip_rcv+0x2b8/0x3a0
 [<ffffffff81474193>] __netif_receive_skb_core+0x763/0xa50
 [<ffffffff81476c28>] __netif_receive_skb+0x18/0x60
 [<ffffffff81476cb0>] netif_receive_skb_internal+0x40/0xd0
 [<ffffffff814776c8>] napi_gro_receive+0xe8/0x120
 [<ffffffffa03946aa>] rtl8169_poll+0x2da/0x660 [r8169]
 [<ffffffff8147896a>] net_rx_action+0x21a/0x360
 [<ffffffff81078dc1>] __do_softirq+0xe1/0x2d0
 [<ffffffff8107912d>] irq_exit+0xad/0xb0
 [<ffffffff8157d158>] do_IRQ+0x58/0xf0
 [<ffffffff8157b06d>] common_interrupt+0x6d/0x6d
 <EOI>
 [<ffffffff810e1218>] ? hrtimer_start+0x18/0x20
 [<ffffffffa05d65f9>] ? sctp_transport_destroy_rcu+0x29/0x30 [sctp]
 [<ffffffff81020c50>] ? mwait_idle+0x60/0xa0
 [<ffffffff810216ef>] arch_cpu_idle+0xf/0x20
 [<ffffffff810b731c>] cpu_startup_entry+0x3ec/0x480
 [<ffffffff8156b365>] rest_init+0x85/0x90
 [<ffffffff818eb035>] start_kernel+0x48b/0x4ac
 [<ffffffff818ea120>] ? early_idt_handlers+0x120/0x120
 [<ffffffff818ea339>] x86_64_start_reservations+0x2a/0x2c
 [<ffffffff818ea49c>] x86_64_start_kernel+0x161/0x184
Code: 90 48 8b 80 b8 00 00 00 48 89 85 70 ff ff ff 48 83 bd 70 ff ff ff 00 0f 85 cd fa ff ff 48 89 df 31 db e8 18 63 e7 e0 48 8b 45 80 <48> 8b 40 20 48 8b 40 30 48 8b 80 68 01 00 00 65 48 ff 40 78 e9
RIP  [<ffffffffa05ec9ac>] sctp_packet_transmit+0x63c/0x730 [sctp]
 RSP <ffff880127c037b8>
CR2: 0000000000000020
---[ end trace 5aec7fd2dc983574 ]---
Kernel panic - not syncing: Fatal exception in interrupt
Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffff9fffffff)
drm_kms_helper: panic occurred, switching back to text console
---[ end Kernel panic - not syncing: Fatal exception in interrupt

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
History 2015-07-05 10:13:00 -04:00
..
6lowpan 6lowpan: Allow 6LoWPAN to be modular 2014-08-07 11:44:18 -07:00
9p 9p/trans_virtio: enable VQs early 2014-10-15 10:25:04 +10:30
802 net: set name_assign_type in alloc_netdev() 2014-07-15 16:12:48 -07:00
8021q net: better IFF_XMIT_DST_RELEASE support 2014-10-07 13:22:11 -04:00
appletalk Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-07-16 14:09:34 -07:00
atm net: better IFF_XMIT_DST_RELEASE support 2014-10-07 13:22:11 -04:00
ax25 net: Fix use after free by removing length arg from sk_data_ready callbacks. 2014-04-11 16:15:36 -04:00
batman-adv batman-adv: avoid NULL dereferences and fix if check 2015-01-27 08:29:33 -08:00
bluetooth Bluetooth: Fix valid Identity Address check 2015-03-06 14:52:44 -08:00
bridge bridge: fix br_stp_set_bridge_priority race conditions 2015-07-05 10:12:58 -04:00
caif unix/caif: sk_socket can disappear when state is unlocked 2015-06-15 14:26:52 -04:00
can can: add missing initialisations in CAN related skbuffs 2015-03-28 09:37:33 -04:00
ceph crush: ensuring at most num-rep osds are selected 2015-06-15 14:29:41 -04:00
core neigh: do not modify unlinked entries 2015-07-05 10:12:59 -04:00
dcb dcbnl : Disable software interrupts before taking dcb_lock 2014-11-16 14:50:52 -05:00
dccp Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-10-18 09:31:37 -07:00
decnet af_decnet: Use time_after_eq 2014-08-22 12:23:11 -07:00
dns_resolver Merge commit 'v3.16' into next 2014-10-01 00:44:04 +10:00
dsa net: dsa: slave: Fix autoneg for phys on switch MDIO bus 2014-11-06 15:06:28 -05:00
ethernet net: Add function for parsing the header length out of linear ethernet frames 2014-09-05 17:47:02 -07:00
hsr net/hsr: Remove left-over never-true conditional code. 2014-07-11 15:04:40 -07:00
ieee802154 Merge tag 'master-2014-10-02' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next 2014-10-05 21:34:39 -04:00
ipv4 tcp: Do not call tcp_fastopen_reset_cipher from interrupt context 2015-07-05 10:12:59 -04:00
ipv6 vti6: fix uninit when using x-netns 2015-06-28 13:39:22 -04:00
ipx ipx: fix locking regression in ipx_sendmsg and ipx_recvmsg 2014-11-20 22:57:03 -05:00
irda net: irda: fix wait_until_sent poll timeout 2015-03-14 15:37:25 -04:00
iucv iucv: Convert pr_warning to pr_warn 2014-09-10 12:40:10 -07:00
key af_key: remove unnecessary break after return 2014-07-15 16:27:00 -07:00
l2tp l2tp: Refactor l2tp core driver to make use of the common UDP tunnel functions 2014-09-19 15:57:15 -04:00
lapb net/lapb: re-send packets on timeout 2013-09-23 16:52:45 -04:00
llc net_dma: simple removal 2014-09-28 07:05:16 -07:00
mac80211 mac80211: don't use napi_gro_receive() outside NAPI context 2015-06-10 13:42:30 -04:00
mac802154 Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-10-08 21:40:54 -04:00
mpls mpls: Allow mpls_gso to be built as module 2014-10-31 15:47:21 -04:00
netfilter netfilter: nf_qeueue: Drop queue entries on nf_unregister_hook 2015-07-05 10:12:48 -04:00
netlabel cipso: don't use IPCB() to locate the CIPSO IP option 2015-03-06 14:52:59 -08:00
netlink lib/rhashtable: fix race between rhashtable_lookup_compare and hashtable resize 2015-07-01 15:33:16 -04:00
netrom netrom: use linux/uaccess.h 2014-10-17 23:52:54 -04:00
nfc NFC: nci: Add support for proprietary RF Protocols 2014-09-24 02:02:24 +02:00
openvswitch vlan: introduce *vlan_hwaccel_push_inside helpers 2015-04-27 16:48:34 -04:00
packet packet: avoid out of bounds read in round robin fanout 2015-07-05 10:12:58 -04:00
phonet net: fix rcu access on phonet_routes 2014-10-06 18:16:30 -04:00
rds rds: avoid potential stack overflow 2015-03-24 08:22:18 -04:00
rfkill net: rfkill: kernel-doc warning fixes 2014-10-09 11:16:15 +02:00
rose NET: ROSE: Don't dereference NULL neighbour pointer. 2015-07-05 10:12:48 -04:00
rxrpc rxrpc: bogus MSG_PEEK test in rxrpc_recvmsg() 2015-03-24 08:22:20 -04:00
sched net_sched: invoke ->attach() after setting dev->qdisc 2015-06-15 14:26:52 -04:00
sctp sctp: Fix race between OOTB responce and route removal 2015-07-05 10:13:00 -04:00
sunrpc SUNRPC: Fix a memory leak in the backchannel code 2015-07-03 23:02:23 -04:00
tipc tipc: fix lockdep warning when intra-node messages are delivered 2014-10-21 15:28:15 -04:00
unix unix/caif: sk_socket can disappear when state is unlocked 2015-06-15 14:26:52 -04:00
vmw_vsock vsock: Make transport the proto owner 2014-05-05 13:13:50 -04:00
wimax wimax: convert printk to pr_foo() 2014-10-07 20:28:44 -04:00
wireless cfg80211: wext: clear sinfo struct before calling driver 2015-07-03 12:34:46 -04:00
x25 net: Fix use after free by removing length arg from sk_data_ready callbacks. 2014-04-11 16:15:36 -04:00
xfrm xfrm: release dst_orig in case of error in xfrm_lookup() 2015-06-10 13:42:46 -04:00
compat.c net: compat: Update get_compat_msghdr() to match copy_msghdr_from_user() behaviour 2015-03-24 08:22:21 -04:00
Kconfig bpf: split eBPF out of NET 2014-10-27 19:09:59 -04:00
Makefile 6lowpan: introduce new net/6lowpan directory 2014-07-12 01:53:30 +02:00
nonet.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
socket.c net: socket: Fix the wrong returns for recvmsg and sendmsg 2015-07-03 12:34:30 -04:00
sysctl_net.c net: Update the sysctl permissions handler to test effective uid/gid 2013-10-07 15:57:56 -04:00