android_kernel_oneplus_msm8998/net/core
Daniel Borkmann 95aa915c2f socket, bpf: fix sk_filter use after free in sk_clone_lock
[ Upstream commit a97e50cc4cb67e1e7bff56f6b41cda62ca832336 ]

In sk_clone_lock(), we create a new socket and inherit most of the
parent's members via sock_copy() which memcpy()'s various sections.
Now, in case the parent socket had a BPF socket filter attached,
then newsk->sk_filter points to the same instance as the original
sk->sk_filter.

sk_filter_charge() is then called on the newsk->sk_filter to take a
reference and should that fail due to hitting max optmem, we bail
out and release the newsk instance.

The issue is that commit 278571baca ("net: filter: simplify socket
charging") wrongly combined the dismantle path with the failure path
of xfrm_sk_clone_policy(). This means, even when charging failed, we
call sk_free_unlock_clone() on the newsk, which then still points to
the same sk_filter as the original sk.

Thus, sk_free_unlock_clone() calls into __sk_destruct() eventually
where it tests for present sk_filter and calls sk_filter_uncharge()
on it, which potentially lets sk_omem_alloc wrap around and releases
the eBPF prog and sk_filter structure from the (still intact) parent.

Fix it by making sure that when sk_filter_charge() failed, we reset
newsk->sk_filter back to NULL before passing to sk_free_unlock_clone(),
so that we don't mess with the parents sk_filter.

Only if xfrm_sk_clone_policy() fails, we did reach the point where
either the parent's filter was NULL and as a result newsk's as well
or where we previously had a successful sk_filter_charge(), thus for
that case, we do need sk_filter_uncharge() to release the prior taken
reference on sk_filter.

Fixes: 278571baca ("net: filter: simplify socket charging")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-03-30 09:35:14 +02:00
..
datagram.c net: rename SOCK_ASYNC_NOSPACE and SOCK_ASYNC_WAITDATA 2015-12-01 15:45:05 -05:00
dev.c net: net_enable_timestamp() can be called from irq contexts 2017-03-22 12:04:14 +01:00
dev_addr_lists.c
dev_ioctl.c
drop_monitor.c drop_monitor: consider inserted data in genlmsg_end 2017-01-15 13:41:35 +01:00
dst.c net: possible use after free in dst_release 2016-01-06 15:00:27 -05:00
ethtool.c
fib_rules.c
filter.c tcp: take care of truncations done by sk_filter() 2016-11-21 10:06:40 +01:00
flow.c
flow_dissector.c flow_dissect: call init_default_flow_dissectors() earlier 2016-12-02 09:09:02 +01:00
gen_estimator.c
gen_stats.c
link_watch.c
lwtunnel.c
Makefile
neighbour.c neigh: Explicitly declare RCU-bh read side critical section in neigh_xmit() 2016-07-11 09:31:12 -07:00
net-procfs.c
net-sysfs.c
net-sysfs.h
net-traces.c
net_namespace.c net: check dead netns for peernet2id_alloc() 2016-12-10 19:07:22 +01:00
netclassid_cgroup.c Merge branch 'master' into for-4.4-fixes 2015-12-07 10:09:03 -05:00
netevent.c
netpoll.c
netprio_cgroup.c cgroup: fix handling of multi-destination migration from subtree_control enabling 2015-12-03 10:18:21 -05:00
pktgen.c net: pktgen: remove rcu locking in pktgen_change_name() 2016-11-15 07:46:38 +01:00
ptp_classifier.c ptp: Change ptp_class to a proper bitmask 2015-11-03 11:08:22 -05:00
request_sock.c
rtnetlink.c rtnetlink: fix FDB size computation 2016-12-10 19:07:22 +01:00
scm.c unix: correctly track in-flight fds in sending process user_struct 2016-03-03 15:07:05 -08:00
secure_seq.c
skbuff.c net: fix socket refcounting in skb_complete_tx_timestamp() 2017-03-22 12:04:15 +01:00
sock.c socket, bpf: fix sk_filter use after free in sk_clone_lock 2017-03-30 09:35:14 +02:00
sock_diag.c
stream.c net: fix sock_wake_async() rcu protection 2015-12-01 15:45:05 -05:00
sysctl_net_core.c net:Add sysctl_max_skb_frags 2016-03-03 15:07:05 -08:00
timestamping.c
tso.c
utils.c