diff options
Diffstat (limited to 'net-packet-fix-tp_reserve-race-in-packet_set_ring.patch')
-rw-r--r-- | net-packet-fix-tp_reserve-race-in-packet_set_ring.patch | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/net-packet-fix-tp_reserve-race-in-packet_set_ring.patch b/net-packet-fix-tp_reserve-race-in-packet_set_ring.patch new file mode 100644 index 000000000..da7103dbe --- /dev/null +++ b/net-packet-fix-tp_reserve-race-in-packet_set_ring.patch @@ -0,0 +1,57 @@ +From patchwork Thu Aug 10 16:41:58 2017 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [net] packet: fix tp_reserve race in packet_set_ring +From: Willem de Bruijn <willemdebruijn.kernel@gmail.com> +X-Patchwork-Id: 800274 +X-Patchwork-Delegate: davem@davemloft.net +Message-Id: <20170810164158.52213-1-willemdebruijn.kernel@gmail.com> +To: netdev@vger.kernel.org +Cc: davem@davemloft.net, andreyknvl@gmail.com, + Willem de Bruijn <willemb@google.com> +Date: Thu, 10 Aug 2017 12:41:58 -0400 + +From: Willem de Bruijn <willemb@google.com> + +Updates to tp_reserve can race with reads of the field in +packet_set_ring. Avoid this by holding the socket lock during +updates in setsockopt PACKET_RESERVE. + +This bug was discovered by syzkaller. + +Fixes: 8913336a7e8d ("packet: add PACKET_RESERVE sockopt") +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: Willem de Bruijn <willemb@google.com> +--- + net/packet/af_packet.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 0615c2a950fa..008a45ca3112 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3700,14 +3700,19 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + + if (optlen != sizeof(val)) + return -EINVAL; +- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) +- return -EBUSY; + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; + if (val > INT_MAX) + return -EINVAL; +- po->tp_reserve = val; +- return 0; ++ lock_sock(sk); ++ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { ++ ret = -EBUSY; ++ } else { ++ po->tp_reserve = val; ++ ret = 0; ++ } ++ release_sock(sk); ++ return ret; + } + case PACKET_LOSS: + { |