This is a note to let you know that I've just added the patch titled packet: avoid panic in packet_getsockopt() to the 4.13-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: packet-avoid-panic-in-packet_getsockopt.patch and it can be found in the queue-4.13 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From foo@baz Wed Nov 15 17:25:34 CET 2017 From: Eric Dumazet <edumazet@xxxxxxxxxx> Date: Wed, 18 Oct 2017 16:14:52 -0700 Subject: packet: avoid panic in packet_getsockopt() From: Eric Dumazet <edumazet@xxxxxxxxxx> [ Upstream commit 509c7a1ecc8601f94ffba8a00889fefb239c00c6 ] syzkaller got crashes in packet_getsockopt() processing PACKET_ROLLOVER_STATS command while another thread was managing to change po->rollover Using RCU will fix this bug. We might later add proper RCU annotations for sparse sake. In v2: I replaced kfree(rollover) in fanout_add() to kfree_rcu() variant, as spotted by John. Fixes: a9b6391814d5 ("packet: rollover statistics") Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx> Cc: Willem de Bruijn <willemb@xxxxxxxxxx> Cc: John Sperbeck <jsperbeck@xxxxxxxxxx> Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- net/packet/af_packet.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1771,7 +1771,7 @@ static int fanout_add(struct sock *sk, u out: if (err && rollover) { - kfree(rollover); + kfree_rcu(rollover, rcu); po->rollover = NULL; } mutex_unlock(&fanout_mutex); @@ -1798,8 +1798,10 @@ static struct packet_fanout *fanout_rele else f = NULL; - if (po->rollover) + if (po->rollover) { kfree_rcu(po->rollover, rcu); + po->rollover = NULL; + } } mutex_unlock(&fanout_mutex); @@ -3853,6 +3855,7 @@ static int packet_getsockopt(struct sock void *data = &val; union tpacket_stats_u st; struct tpacket_rollover_stats rstats; + struct packet_rollover *rollover; if (level != SOL_PACKET) return -ENOPROTOOPT; @@ -3931,13 +3934,18 @@ static int packet_getsockopt(struct sock 0); break; case PACKET_ROLLOVER_STATS: - if (!po->rollover) + rcu_read_lock(); + rollover = rcu_dereference(po->rollover); + if (rollover) { + rstats.tp_all = atomic_long_read(&rollover->num); + rstats.tp_huge = atomic_long_read(&rollover->num_huge); + rstats.tp_failed = atomic_long_read(&rollover->num_failed); + data = &rstats; + lv = sizeof(rstats); + } + rcu_read_unlock(); + if (!rollover) return -EINVAL; - rstats.tp_all = atomic_long_read(&po->rollover->num); - rstats.tp_huge = atomic_long_read(&po->rollover->num_huge); - rstats.tp_failed = atomic_long_read(&po->rollover->num_failed); - data = &rstats; - lv = sizeof(rstats); break; case PACKET_TX_HAS_OFF: val = po->tp_tx_has_off; Patches currently in stable-queue which might be from edumazet@xxxxxxxxxx are queue-4.13/tcp-refresh-tp-timestamp-before-tcp_mtu_probe.patch queue-4.13/net-call-cgroup_sk_alloc-earlier-in-sk_clone_lock.patch queue-4.13/tcp-dccp-fix-ireq-opt-races.patch queue-4.13/tcp-fix-tcp_mtu_probe-vs-highest_sack.patch queue-4.13/ipv6-addrconf-increment-ifp-refcount-before-ipv6_del_addr.patch queue-4.13/ipv6-flowlabel-do-not-leave-opt-tot_len-with-garbage.patch queue-4.13/packet-avoid-panic-in-packet_getsockopt.patch queue-4.13/sctp-add-the-missing-sock_owned_by_user-check-in-sctp_icmp_redirect.patch queue-4.13/net_sched-avoid-matching-qdisc-with-zero-handle.patch queue-4.13/tun-tap-sanitize-tunsetsndbuf-input.patch queue-4.13/tcp-dccp-fix-lockdep-splat-in-inet_csk_route_req.patch queue-4.13/tcp-dccp-fix-other-lockdep-splats-accessing-ireq_opt.patch