]>
Commit | Line | Data |
---|---|---|
59d5af67 | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
321d628a FG |
2 | From: Jann Horn <jannh@google.com> |
3 | Date: Thu, 4 Jan 2018 08:01:22 -0600 | |
59d5af67 | 4 | Subject: [PATCH] bpf: fix incorrect sign extension in check_alu_op() |
321d628a FG |
5 | MIME-Version: 1.0 |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | [ Upstream commit 95a762e2c8c942780948091f8f2a4f32fce1ac6f ] | |
10 | ||
11 | Distinguish between | |
12 | BPF_ALU64|BPF_MOV|BPF_K (load 32-bit immediate, sign-extended to 64-bit) | |
13 | and BPF_ALU|BPF_MOV|BPF_K (load 32-bit immediate, zero-padded to 64-bit); | |
14 | only perform sign extension in the first case. | |
15 | ||
16 | Starting with v4.14, this is exploitable by unprivileged users as long as | |
17 | the unprivileged_bpf_disabled sysctl isn't set. | |
18 | ||
19 | Debian assigned CVE-2017-16995 for this issue. | |
20 | ||
21 | v3: | |
22 | - add CVE number (Ben Hutchings) | |
23 | ||
24 | Fixes: 484611357c19 ("bpf: allow access into map value arrays") | |
25 | Signed-off-by: Jann Horn <jannh@google.com> | |
26 | Acked-by: Edward Cree <ecree@solarflare.com> | |
27 | Signed-off-by: Alexei Starovoitov <ast@kernel.org> | |
28 | Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> | |
29 | CVE-2017-16995 | |
30 | Signed-off-by: Seth Forshee <seth.forshee@canonical.com> | |
31 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
32 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
33 | (cherry picked from commit 868c88129c7567525dbde3cb6989a5acd478bd80) | |
34 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
35 | --- | |
36 | kernel/bpf/verifier.c | 15 +++++++++++---- | |
37 | 1 file changed, 11 insertions(+), 4 deletions(-) | |
38 | ||
39 | diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c | |
40 | index 4321625fe32a..cdfa07a4ef27 100644 | |
41 | --- a/kernel/bpf/verifier.c | |
42 | +++ b/kernel/bpf/verifier.c | |
43 | @@ -2048,12 +2048,19 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) | |
44 | /* case: R = imm | |
45 | * remember the value we stored into this reg | |
46 | */ | |
47 | + u64 imm; | |
48 | + | |
49 | + if (BPF_CLASS(insn->code) == BPF_ALU64) | |
50 | + imm = insn->imm; | |
51 | + else | |
52 | + imm = (u32)insn->imm; | |
53 | + | |
54 | regs[insn->dst_reg].type = CONST_IMM; | |
55 | - regs[insn->dst_reg].imm = insn->imm; | |
56 | + regs[insn->dst_reg].imm = imm; | |
57 | regs[insn->dst_reg].id = 0; | |
58 | - regs[insn->dst_reg].max_value = insn->imm; | |
59 | - regs[insn->dst_reg].min_value = insn->imm; | |
60 | - regs[insn->dst_reg].min_align = calc_align(insn->imm); | |
61 | + regs[insn->dst_reg].max_value = imm; | |
62 | + regs[insn->dst_reg].min_value = imm; | |
63 | + regs[insn->dst_reg].min_align = calc_align(imm); | |
64 | regs[insn->dst_reg].value_from_signed = false; | |
65 | } | |
66 | ||
67 | -- | |
68 | 2.14.2 | |
69 |