diff options
author | Andreas Wellving <andreas.wellving@enea.com> | 2018-10-17 14:15:52 +0200 |
---|---|---|
committer | Andreas Wellving <andreas.wellving@enea.com> | 2018-10-17 14:15:52 +0200 |
commit | 26a5aeb5f6e2d2af95f21cc8b3e80a02c2380a58 (patch) | |
tree | 009e2d06624da86e0c2d1a0b48ee253a7f3d7147 | |
parent | 603c99ecf5d16918c4062b273aa269d8ccdd6145 (diff) | |
download | enea-kernel-cache-26a5aeb5f6e2d2af95f21cc8b3e80a02c2380a58.tar.gz |
packet: CVE-2016-8665
packet: fix race condition in packet_set_ring
References:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.1.y&id=e29fdf045048addaea61c837b60e3c4d2ec43614
Change-Id: I3a9abfa653c6a2d3fede70c8c7f4f7f8df7b3063
Signed-off-by: Andreas Wellving <andreas.wellving@enea.com>
-rw-r--r-- | patches/cve/4.1.x.scc | 1 | ||||
-rw-r--r-- | patches/cve/CVE-2016-8655-packet-fix-race-condition-in-packet_set_ring.patch | 99 |
2 files changed, 100 insertions, 0 deletions
diff --git a/patches/cve/4.1.x.scc b/patches/cve/4.1.x.scc index 26b7fd8..4451d85 100644 --- a/patches/cve/4.1.x.scc +++ b/patches/cve/4.1.x.scc | |||
@@ -1,3 +1,4 @@ | |||
1 | #fixed in 4.1.37 | 1 | #fixed in 4.1.37 |
2 | patch CVE-2016-7039-net-add-recursion-limit-to-GRO.patch | 2 | patch CVE-2016-7039-net-add-recursion-limit-to-GRO.patch |
3 | patch CVE-2016-8399-net-ping-check-minimum-size-on-ICMP-header-length.patch | 3 | patch CVE-2016-8399-net-ping-check-minimum-size-on-ICMP-header-length.patch |
4 | patch CVE-2016-8655-packet-fix-race-condition-in-packet_set_ring.patch | ||
diff --git a/patches/cve/CVE-2016-8655-packet-fix-race-condition-in-packet_set_ring.patch b/patches/cve/CVE-2016-8655-packet-fix-race-condition-in-packet_set_ring.patch new file mode 100644 index 0000000..edaecc6 --- /dev/null +++ b/patches/cve/CVE-2016-8655-packet-fix-race-condition-in-packet_set_ring.patch | |||
@@ -0,0 +1,99 @@ | |||
1 | From e29fdf045048addaea61c837b60e3c4d2ec43614 Mon Sep 17 00:00:00 2001 | ||
2 | From: Philip Pettersson <philip.pettersson@gmail.com> | ||
3 | Date: Wed, 14 Dec 2016 13:24:56 +0100 | ||
4 | Subject: [PATCH] packet: fix race condition in packet_set_ring | ||
5 | |||
6 | [ Upstream commit 84ac7260236a49c79eede91617700174c2c19b0c ] | ||
7 | |||
8 | When packet_set_ring creates a ring buffer it will initialize a | ||
9 | struct timer_list if the packet version is TPACKET_V3. This value | ||
10 | can then be raced by a different thread calling setsockopt to | ||
11 | set the version to TPACKET_V1 before packet_set_ring has finished. | ||
12 | |||
13 | This leads to a use-after-free on a function pointer in the | ||
14 | struct timer_list when the socket is closed as the previously | ||
15 | initialized timer will not be deleted. | ||
16 | |||
17 | The bug is fixed by taking lock_sock(sk) in packet_setsockopt when | ||
18 | changing the packet version while also taking the lock at the start | ||
19 | of packet_set_ring. | ||
20 | |||
21 | Upstream-Status: Backport | ||
22 | References: CVE-2016-8655 | ||
23 | Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.") | ||
24 | Signed-off-by: Philip Pettersson <philip.pettersson@gmail.com> | ||
25 | Signed-off-by: Eric Dumazet <edumazet@google.com> | ||
26 | Signed-off-by: David S. Miller <davem@davemloft.net> | ||
27 | Signed-off-by: Philipp Hahn <hahn@univention.de> | ||
28 | Signed-off-by: Sasha Levin <alexander.levin@verizon.com> | ||
29 | Signed-off-by: Andreas Wellving <andreas.wellving@enea.com> | ||
30 | --- | ||
31 | net/packet/af_packet.c | 18 ++++++++++++------ | ||
32 | 1 file changed, 12 insertions(+), 6 deletions(-) | ||
33 | |||
34 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c | ||
35 | index a3654d9..b9d1baa 100644 | ||
36 | --- a/net/packet/af_packet.c | ||
37 | +++ b/net/packet/af_packet.c | ||
38 | @@ -3344,19 +3344,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv | ||
39 | |||
40 | if (optlen != sizeof(val)) | ||
41 | return -EINVAL; | ||
42 | - if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) | ||
43 | - return -EBUSY; | ||
44 | if (copy_from_user(&val, optval, sizeof(val))) | ||
45 | return -EFAULT; | ||
46 | switch (val) { | ||
47 | case TPACKET_V1: | ||
48 | case TPACKET_V2: | ||
49 | case TPACKET_V3: | ||
50 | - po->tp_version = val; | ||
51 | - return 0; | ||
52 | + break; | ||
53 | default: | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | + lock_sock(sk); | ||
57 | + if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { | ||
58 | + ret = -EBUSY; | ||
59 | + } else { | ||
60 | + po->tp_version = val; | ||
61 | + ret = 0; | ||
62 | + } | ||
63 | + release_sock(sk); | ||
64 | + return ret; | ||
65 | } | ||
66 | case PACKET_RESERVE: | ||
67 | { | ||
68 | @@ -3819,6 +3825,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | ||
69 | /* Added to avoid minimal code churn */ | ||
70 | struct tpacket_req *req = &req_u->req; | ||
71 | |||
72 | + lock_sock(sk); | ||
73 | /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ | ||
74 | if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { | ||
75 | WARN(1, "Tx-ring is not supported.\n"); | ||
76 | @@ -3900,7 +3907,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | ||
77 | goto out; | ||
78 | } | ||
79 | |||
80 | - lock_sock(sk); | ||
81 | |||
82 | /* Detach socket from network */ | ||
83 | spin_lock(&po->bind_lock); | ||
84 | @@ -3949,11 +3955,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | ||
85 | if (!tx_ring) | ||
86 | prb_shutdown_retire_blk_timer(po, tx_ring, rb_queue); | ||
87 | } | ||
88 | - release_sock(sk); | ||
89 | |||
90 | if (pg_vec) | ||
91 | free_pg_vec(pg_vec, order, req->tp_block_nr); | ||
92 | out: | ||
93 | + release_sock(sk); | ||
94 | return err; | ||
95 | } | ||
96 | |||
97 | -- | ||
98 | 2.7.4 | ||
99 | |||