]> git.proxmox.com Git - pve-kernel-jessie.git/blame - CVE-2016-8655-packet-fix-race-condition.patch
update to Ubuntu 4.4.0-58-79
[pve-kernel-jessie.git] / CVE-2016-8655-packet-fix-race-condition.patch
CommitLineData
527d75c3
FG
1From 84ac7260236a49c79eede91617700174c2c19b0c Mon Sep 17 00:00:00 2001
2From: Philip Pettersson <philip.pettersson@gmail.com>
3Date: Wed, 30 Nov 2016 14:55:36 -0800
4Subject: packet: fix race condition in packet_set_ring
5
6When packet_set_ring creates a ring buffer it will initialize a
7struct timer_list if the packet version is TPACKET_V3. This value
8can then be raced by a different thread calling setsockopt to
9set the version to TPACKET_V1 before packet_set_ring has finished.
10
11This leads to a use-after-free on a function pointer in the
12struct timer_list when the socket is closed as the previously
13initialized timer will not be deleted.
14
15The bug is fixed by taking lock_sock(sk) in packet_setsockopt when
16changing the packet version while also taking the lock at the start
17of packet_set_ring.
18
19Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.")
20Signed-off-by: Philip Pettersson <philip.pettersson@gmail.com>
21Signed-off-by: Eric Dumazet <edumazet@google.com>
22Signed-off-by: David S. Miller <davem@davemloft.net>
23---
24 net/packet/af_packet.c | 18 ++++++++++++------
25 1 file changed, 12 insertions(+), 6 deletions(-)
26
27diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
28index d2238b2..dd23323 100644
29--- a/net/packet/af_packet.c
30+++ b/net/packet/af_packet.c
31@@ -3648,19 +3648,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
32
33 if (optlen != sizeof(val))
34 return -EINVAL;
35- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
36- return -EBUSY;
37 if (copy_from_user(&val, optval, sizeof(val)))
38 return -EFAULT;
39 switch (val) {
40 case TPACKET_V1:
41 case TPACKET_V2:
42 case TPACKET_V3:
43- po->tp_version = val;
44- return 0;
45+ break;
46 default:
47 return -EINVAL;
48 }
49+ lock_sock(sk);
50+ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
51+ ret = -EBUSY;
52+ } else {
53+ po->tp_version = val;
54+ ret = 0;
55+ }
56+ release_sock(sk);
57+ return ret;
58 }
59 case PACKET_RESERVE:
60 {
61@@ -4164,6 +4170,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
62 /* Added to avoid minimal code churn */
63 struct tpacket_req *req = &req_u->req;
64
65+ lock_sock(sk);
66 /* Opening a Tx-ring is NOT supported in TPACKET_V3 */
67 if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
68 net_warn_ratelimited("Tx-ring is not supported.\n");
69@@ -4245,7 +4252,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
70 goto out;
71 }
72
73- lock_sock(sk);
74
75 /* Detach socket from network */
76 spin_lock(&po->bind_lock);
77@@ -4294,11 +4300,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
78 if (!tx_ring)
79 prb_shutdown_retire_blk_timer(po, rb_queue);
80 }
81- release_sock(sk);
82
83 if (pg_vec)
84 free_pg_vec(pg_vec, order, req->tp_block_nr);
85 out:
86+ release_sock(sk);
87 return err;
88 }
89
90--
91cgit v0.12
92