summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSona Sarmadi <sona.sarmadi@enea.com>2017-02-03 08:37:29 +0100
committerAdrian Dudau <adrian.dudau@enea.com>2017-02-03 11:00:14 +0100
commit5027488b26d6102220ca2444aa73c03c035f0277 (patch)
tree7fce9cb07194f21275f42dcfad9f6026e5aa9959
parent5efb264f10ac2c2753500f862a11b0d9de175930 (diff)
downloadmeta-enea-bsp-ppc-5027488b26d6102220ca2444aa73c03c035f0277.tar.gz
Kernel: CVE-2016-9754
Integer overflow in ring_buffer_resize() The ring_buffer_resize function in kernel/trace/ring_buffer.c in the profiling subsystem in the Linux kernel before 4.6.1 mishandles certain integer calculations, which allows local users to gain privileges by writing to the /sys/kernel/debug/tracing/buffer_size_kb file. References: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9754 References to upstream patch: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=59643d1535eb220668692a5359de22545af579f6 Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> Signed-off-by: Adrian Dudau <adrian.dudau@enea.com>
-rw-r--r--recipes-kernel/linux/files/ring-buffer-CVE-2016-9754.patch95
-rw-r--r--recipes-kernel/linux/linux-qoriq_3.12.bbappend1
2 files changed, 96 insertions, 0 deletions
diff --git a/recipes-kernel/linux/files/ring-buffer-CVE-2016-9754.patch b/recipes-kernel/linux/files/ring-buffer-CVE-2016-9754.patch
new file mode 100644
index 0000000..49d3e42
--- /dev/null
+++ b/recipes-kernel/linux/files/ring-buffer-CVE-2016-9754.patch
@@ -0,0 +1,95 @@
1From 5feada97176f05f92088911fa807d30445c6a0c6 Mon Sep 17 00:00:00 2001
2From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
3Date: Fri, 13 May 2016 09:34:12 -0400
4Subject: [PATCH] ring-buffer: Prevent overflow of size in ring_buffer_resize()
5
6commit 59643d1535eb220668692a5359de22545af579f6 upstream.
7
8If the size passed to ring_buffer_resize() is greater than MAX_LONG - BUF_PAGE_SIZE
9then the DIV_ROUND_UP() will return zero.
10
11Here's the details:
12
13 # echo 18014398509481980 > /sys/kernel/debug/tracing/buffer_size_kb
14
15tracing_entries_write() processes this and converts kb to bytes.
16
17 18014398509481980 << 10 = 18446744073709547520
18
19and this is passed to ring_buffer_resize() as unsigned long size.
20
21 size = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
22
23Where DIV_ROUND_UP(a, b) is (a + b - 1)/b
24
25BUF_PAGE_SIZE is 4080 and here
26
27 18446744073709547520 + 4080 - 1 = 18446744073709551599
28
29where 18446744073709551599 is still smaller than 2^64
30
31 2^64 - 18446744073709551599 = 17
32
33But now 18446744073709551599 / 4080 = 4521260802379792
34
35and size = size * 4080 = 18446744073709551360
36
37This is checked to make sure its still greater than 2 * 4080,
38which it is.
39
40Then we convert to the number of buffer pages needed.
41
42 nr_page = DIV_ROUND_UP(size, BUF_PAGE_SIZE)
43
44but this time size is 18446744073709551360 and
45
46 2^64 - (18446744073709551360 + 4080 - 1) = -3823
47
48Thus it overflows and the resulting number is less than 4080, which makes
49
50 3823 / 4080 = 0
51
52an nr_pages is set to this. As we already checked against the minimum that
53nr_pages may be, this causes the logic to fail as well, and we crash the
54kernel.
55
56There's no reason to have the two DIV_ROUND_UP() (that's just result of
57historical code changes), clean up the code and fix this bug.
58
59CVE: CVE-2016-9754
60Upstream-Status: Backport
61
62Fixes: 83f40318dab00 ("ring-buffer: Make removal of ring buffer pages atomic")
63Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
64Signed-off-by: Jiri Slaby <jslaby@suse.cz>
65Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
66---
67 kernel/trace/ring_buffer.c | 9 ++++-----
68 1 file changed, 4 insertions(+), 5 deletions(-)
69
70diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
71index 4940115..f100767 100644
72--- a/kernel/trace/ring_buffer.c
73+++ b/kernel/trace/ring_buffer.c
74@@ -1645,14 +1645,13 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size,
75 !cpumask_test_cpu(cpu_id, buffer->cpumask))
76 return size;
77
78- size = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
79- size *= BUF_PAGE_SIZE;
80+ nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
81
82 /* we need a minimum of two pages */
83- if (size < BUF_PAGE_SIZE * 2)
84- size = BUF_PAGE_SIZE * 2;
85+ if (nr_pages < 2)
86+ nr_pages = 2;
87
88- nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
89+ size = nr_pages * BUF_PAGE_SIZE;
90
91 /*
92 * Don't succeed if resizing is disabled, as a reader might be
93--
941.9.1
95
diff --git a/recipes-kernel/linux/linux-qoriq_3.12.bbappend b/recipes-kernel/linux/linux-qoriq_3.12.bbappend
index 596cd1b..be8cf93 100644
--- a/recipes-kernel/linux/linux-qoriq_3.12.bbappend
+++ b/recipes-kernel/linux/linux-qoriq_3.12.bbappend
@@ -9,5 +9,6 @@ SRC_URI += "file://ppp-CVE-2015-8569.patch \
9 file://CVE-2016-3136.patch \ 9 file://CVE-2016-3136.patch \
10 file://CVE-2016-5195.patch \ 10 file://CVE-2016-5195.patch \
11 file://CVE-2016-6480.patch \ 11 file://CVE-2016-6480.patch \
12 file://ring-buffer-CVE-2016-9754.patch \
12 " 13 "
13 14