android_kernel_google_msm/net
Daniel Borkmann 0565f4368f net: sctp: fix slab corruption from use after free on INIT collisions
commit 600ddd6825543962fb807884169e57b580dba208 upstream.

When hitting an INIT collision case during the 4WHS with AUTH enabled, as
already described in detail in commit 1be9a950c6 ("net: sctp: inherit
auth_capable on INIT collisions"), it can happen that we occasionally
still remotely trigger the following panic on server side which seems to
have been uncovered after the fix from commit 1be9a950c6 ...

[  533.876389] BUG: unable to handle kernel paging request at 00000000ffffffff
[  533.913657] IP: [<ffffffff811ac385>] __kmalloc+0x95/0x230
[  533.940559] PGD 5030f2067 PUD 0
[  533.957104] Oops: 0000 [#1] SMP
[  533.974283] Modules linked in: sctp mlx4_en [...]
[  534.939704] Call Trace:
[  534.951833]  [<ffffffff81294e30>] ? crypto_init_shash_ops+0x60/0xf0
[  534.984213]  [<ffffffff81294e30>] crypto_init_shash_ops+0x60/0xf0
[  535.015025]  [<ffffffff8128c8ed>] __crypto_alloc_tfm+0x6d/0x170
[  535.045661]  [<ffffffff8128d12c>] crypto_alloc_base+0x4c/0xb0
[  535.074593]  [<ffffffff8160bd42>] ? _raw_spin_lock_bh+0x12/0x50
[  535.105239]  [<ffffffffa0418c11>] sctp_inet_listen+0x161/0x1e0 [sctp]
[  535.138606]  [<ffffffff814e43bd>] SyS_listen+0x9d/0xb0
[  535.166848]  [<ffffffff816149a9>] system_call_fastpath+0x16/0x1b

... or depending on the the application, for example this one:

[ 1370.026490] BUG: unable to handle kernel paging request at 00000000ffffffff
[ 1370.026506] IP: [<ffffffff811ab455>] kmem_cache_alloc+0x75/0x1d0
[ 1370.054568] PGD 633c94067 PUD 0
[ 1370.070446] Oops: 0000 [#1] SMP
[ 1370.085010] Modules linked in: sctp kvm_amd kvm [...]
[ 1370.963431] Call Trace:
[ 1370.974632]  [<ffffffff8120f7cf>] ? SyS_epoll_ctl+0x53f/0x960
[ 1371.000863]  [<ffffffff8120f7cf>] SyS_epoll_ctl+0x53f/0x960
[ 1371.027154]  [<ffffffff812100d3>] ? anon_inode_getfile+0xd3/0x170
[ 1371.054679]  [<ffffffff811e3d67>] ? __alloc_fd+0xa7/0x130
[ 1371.080183]  [<ffffffff816149a9>] system_call_fastpath+0x16/0x1b

With slab debugging enabled, we can see that the poison has been overwritten:

[  669.826368] BUG kmalloc-128 (Tainted: G        W     ): Poison overwritten
[  669.826385] INFO: 0xffff880228b32e50-0xffff880228b32e50. First byte 0x6a instead of 0x6b
[  669.826414] INFO: Allocated in sctp_auth_create_key+0x23/0x50 [sctp] age=3 cpu=0 pid=18494
[  669.826424]  __slab_alloc+0x4bf/0x566
[  669.826433]  __kmalloc+0x280/0x310
[  669.826453]  sctp_auth_create_key+0x23/0x50 [sctp]
[  669.826471]  sctp_auth_asoc_create_secret+0xcb/0x1e0 [sctp]
[  669.826488]  sctp_auth_asoc_init_active_key+0x68/0xa0 [sctp]
[  669.826505]  sctp_do_sm+0x29d/0x17c0 [sctp] [...]
[  669.826629] INFO: Freed in kzfree+0x31/0x40 age=1 cpu=0 pid=18494
[  669.826635]  __slab_free+0x39/0x2a8
[  669.826643]  kfree+0x1d6/0x230
[  669.826650]  kzfree+0x31/0x40
[  669.826666]  sctp_auth_key_put+0x19/0x20 [sctp]
[  669.826681]  sctp_assoc_update+0x1ee/0x2d0 [sctp]
[  669.826695]  sctp_do_sm+0x674/0x17c0 [sctp]

Since this only triggers in some collision-cases with AUTH, the problem at
heart is that sctp_auth_key_put() on asoc->asoc_shared_key is called twice
when having refcnt 1, once directly in sctp_assoc_update() and yet again
from within sctp_auth_asoc_init_active_key() via sctp_assoc_update() on
the already kzfree'd memory, which is also consistent with the observation
of the poison decrease from 0x6b to 0x6a (note: the overwrite is detected
at a later point in time when poison is checked on new allocation).

Reference counting of auth keys revisited:

Shared keys for AUTH chunks are being stored in endpoints and associations
in endpoint_shared_keys list. On endpoint creation, a null key is being
added; on association creation, all endpoint shared keys are being cached
and thus cloned over to the association. struct sctp_shared_key only holds
a pointer to the actual key bytes, that is, struct sctp_auth_bytes which
keeps track of users internally through refcounting. Naturally, on assoc
or enpoint destruction, sctp_shared_key are being destroyed directly and
the reference on sctp_auth_bytes dropped.

User space can add keys to either list via setsockopt(2) through struct
sctp_authkey and by passing that to sctp_auth_set_key() which replaces or
adds a new auth key. There, sctp_auth_create_key() creates a new sctp_auth_bytes
with refcount 1 and in case of replacement drops the reference on the old
sctp_auth_bytes. A key can be set active from user space through setsockopt()
on the id via sctp_auth_set_active_key(), which iterates through either
endpoint_shared_keys and in case of an assoc, invokes (one of various places)
sctp_auth_asoc_init_active_key().

sctp_auth_asoc_init_active_key() computes the actual secret from local's
and peer's random, hmac and shared key parameters and returns a new key
directly as sctp_auth_bytes, that is asoc->asoc_shared_key, plus drops
the reference if there was a previous one. The secret, which where we
eventually double drop the ref comes from sctp_auth_asoc_set_secret() with
intitial refcount of 1, which also stays unchanged eventually in
sctp_assoc_update(). This key is later being used for crypto layer to
set the key for the hash in crypto_hash_setkey() from sctp_auth_calculate_hmac().

To close the loop: asoc->asoc_shared_key is freshly allocated secret
material and independant of the sctp_shared_key management keeping track
of only shared keys in endpoints and assocs. Hence, also commit 4184b2a79a
("net: sctp: fix memory leak in auth key management") is independant of
this bug here since it concerns a different layer (though same structures
being used eventually). asoc->asoc_shared_key is reference dropped correctly
on assoc destruction in sctp_association_free() and when active keys are
being replaced in sctp_auth_asoc_init_active_key(), it always has a refcount
of 1. Hence, it's freed prematurely in sctp_assoc_update(). Simple fix is
to remove that sctp_auth_key_put() from there which fixes these panics.

Fixes: 730fc3d05c ("[SCTP]: Implete SCTP-AUTH parameter processing")
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Zefan Li <lizefan@huawei.com>
2015-04-14 17:33:57 +08:00
..
9p virtio: 9p: correctly pass physical address to userspace for high pages 2014-06-11 12:04:17 -07:00
802
8021q 8021q: fix a potential memory leak 2014-07-28 07:06:45 -07:00
appletalk appletalk: Fix socket referencing in skb 2014-07-28 07:06:45 -07:00
atm net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
ax25 net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
batman-adv batman-adv: fix random jitter calculation 2013-01-11 09:07:03 -08:00
bluetooth Bluetooth: Fix setting correct security level when initiating SMP 2015-02-02 17:04:37 +08:00
bridge netfilter: Can't fail and free after table replacement 2014-05-18 05:25:56 -07:00
caif net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
can can: gw: use kmem_cache_free() instead of kfree() 2013-04-12 09:38:47 -07:00
ceph libceph: do not crash on large auth tickets 2015-02-02 17:05:20 +08:00
core net: Fix stacked vlan offload features computation 2015-04-14 17:33:48 +08:00
dcb dcbnl: fix various netlink info leaks 2013-03-20 13:05:02 -07:00
dccp inet: Fix kmemleak in tcp_v4/6_syn_recv_sock and dccp_v4/6_request_recv_sock 2013-01-11 09:07:14 -08:00
decnet
dns_resolver dns_resolver: Null-terminate the right string 2014-07-28 07:06:46 -07:00
dsa
econet
ethernet
ieee802154 6lowpan: Uncompression of traffic class field was incorrect 2013-12-08 07:29:41 -08:00
ipv4 Patch for 3.2.x, 3.4.x IP identifier regression 2015-02-02 17:05:26 +08:00
ipv6 drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets 2015-02-02 17:05:26 +08:00
ipx net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
irda net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
iucv net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
key net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
l2tp l2tp: fix race while getting PMTU on PPP pseudo-wire 2014-12-01 18:02:45 +08:00
lapb
llc net: llc: fix use after free in llc_ui_recvmsg 2014-01-15 15:27:11 -08:00
mac80211 mac80211: fix multicast LED blinking and counter 2015-04-14 17:33:51 +08:00
netfilter inetpeer: get rid of ip_id_count 2014-08-14 08:42:35 +08:00
netlabel netlabel: improve domain mapping validation 2013-06-27 11:27:31 -07:00
netlink net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
netrom net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
nfc net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
openvswitch
packet af_packet: block BH in prb_shutdown_retire_blk_timer() 2013-12-08 07:29:42 -08:00
phonet inet: prevent leakage of uninitialized memory to user in recv syscalls 2013-12-08 07:29:41 -08:00
rds rds: prevent dereference of a NULL device in rds_iw_laddr_check 2014-04-26 17:13:18 -07:00
rfkill
rose net: rose: restore old recvmsg behavior 2014-01-15 15:27:11 -08:00
rxrpc net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
sched act_mirred: do not drop packets when fails to mirror it 2014-06-07 16:02:00 -07:00
sctp net: sctp: fix slab corruption from use after free on INIT collisions 2015-04-14 17:33:57 +08:00
sunrpc SUNRPC: Fix locking around callback channel reply receive 2015-04-14 17:33:36 +08:00
tipc tipc: clear 'next'-pointer of message fragments before reassembly 2014-07-28 07:06:45 -07:00
unix net: unix: non blocking recvmsg() should not return -EINTR 2014-04-26 17:13:16 -07:00
wanrouter
wimax
wireless nl80211: fix per-station group key get/del and memory leak 2015-04-14 17:33:56 +08:00
x25 net: rework recvmsg handler msg_name and msg_namelen logic 2013-12-08 07:29:41 -08:00
xfrm
compat.c net: sendmsg: fix NULL pointer dereference 2014-08-14 08:42:35 +08:00
Kconfig
Makefile
nonet.c
socket.c net: socket: error on a negative msg_namelen 2014-04-26 17:13:17 -07:00
sysctl_net.c