summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--patches/cve/CVE-2017-17852-bpf-fix-32-bit-ALU-op-verification.patch96
1 files changed, 96 insertions, 0 deletions
diff --git a/patches/cve/CVE-2017-17852-bpf-fix-32-bit-ALU-op-verification.patch b/patches/cve/CVE-2017-17852-bpf-fix-32-bit-ALU-op-verification.patch
new file mode 100644
index 0000000..000e5cd
--- /dev/null
+++ b/patches/cve/CVE-2017-17852-bpf-fix-32-bit-ALU-op-verification.patch
@@ -0,0 +1,96 @@
1From 6c8e098d0324412d4ae9e06c7e611a96b87faf80 Mon Sep 17 00:00:00 2001
2From: Daniel Borkmann <daniel@iogearbox.net>
3Date: Fri, 22 Dec 2017 16:23:07 +0100
4Subject: [PATCH] bpf: fix 32-bit ALU op verification
5
6From: Jann Horn <jannh@google.com>
7
8[ Upstream commit 468f6eafa6c44cb2c5d8aad35e12f06c240a812a ]
9
1032-bit ALU ops operate on 32-bit values and have 32-bit outputs.
11Adjust the verifier accordingly.
12
13CVE: CVE-2017-17852
14Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.14.y&id=6c8e098d0324412d4ae9e06c7e611a96b87faf80]
15
16Fixes: f1174f77b50c ("bpf/verifier: rework value tracking")
17Signed-off-by: Jann Horn <jannh@google.com>
18Signed-off-by: Alexei Starovoitov <ast@kernel.org>
19Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
20Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
21Signed-off-by: Andreas Wellving <andreas.wellving@enea.com>
22---
23 kernel/bpf/verifier.c | 28 +++++++++++++++++-----------
24 1 file changed, 17 insertions(+), 11 deletions(-)
25
26diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
27index 1e2afb264c31..0c7e4c8a2b8a 100644
28--- a/kernel/bpf/verifier.c
29+++ b/kernel/bpf/verifier.c
30@@ -1984,6 +1984,10 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
31 return 0;
32 }
33
34+/* WARNING: This function does calculations on 64-bit values, but the actual
35+ * execution may occur on 32-bit values. Therefore, things like bitshifts
36+ * need extra checks in the 32-bit case.
37+ */
38 static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
39 struct bpf_insn *insn,
40 struct bpf_reg_state *dst_reg,
41@@ -1994,12 +1998,8 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
42 bool src_known, dst_known;
43 s64 smin_val, smax_val;
44 u64 umin_val, umax_val;
45+ u64 insn_bitness = (BPF_CLASS(insn->code) == BPF_ALU64) ? 64 : 32;
46
47- if (BPF_CLASS(insn->code) != BPF_ALU64) {
48- /* 32-bit ALU ops are (32,32)->64 */
49- coerce_reg_to_size(dst_reg, 4);
50- coerce_reg_to_size(&src_reg, 4);
51- }
52 smin_val = src_reg.smin_value;
53 smax_val = src_reg.smax_value;
54 umin_val = src_reg.umin_value;
55@@ -2135,9 +2135,9 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
56 __update_reg_bounds(dst_reg);
57 break;
58 case BPF_LSH:
59- if (umax_val > 63) {
60- /* Shifts greater than 63 are undefined. This includes
61- * shifts by a negative number.
62+ if (umax_val >= insn_bitness) {
63+ /* Shifts greater than 31 or 63 are undefined.
64+ * This includes shifts by a negative number.
65 */
66 mark_reg_unknown(regs, insn->dst_reg);
67 break;
68@@ -2163,9 +2163,9 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
69 __update_reg_bounds(dst_reg);
70 break;
71 case BPF_RSH:
72- if (umax_val > 63) {
73- /* Shifts greater than 63 are undefined. This includes
74- * shifts by a negative number.
75+ if (umax_val >= insn_bitness) {
76+ /* Shifts greater than 31 or 63 are undefined.
77+ * This includes shifts by a negative number.
78 */
79 mark_reg_unknown(regs, insn->dst_reg);
80 break;
81@@ -2201,6 +2201,12 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
82 break;
83 }
84
85+ if (BPF_CLASS(insn->code) != BPF_ALU64) {
86+ /* 32-bit ALU ops are (32,32)->32 */
87+ coerce_reg_to_size(dst_reg, 4);
88+ coerce_reg_to_size(&src_reg, 4);
89+ }
90+
91 __reg_deduce_bounds(dst_reg);
92 __reg_bound_offset(dst_reg);
93 return 0;
94--
952.20.1
96