]>
Commit | Line | Data |
---|---|---|
321d628a FG |
1 | From 3c5659ffcc9d2497045dda465a35720f78314e87 Mon Sep 17 00:00:00 2001 |
2 | From: Jann Horn <jannh@google.com> | |
3 | Date: Thu, 4 Jan 2018 08:01:21 -0600 | |
633c5ed1 | 4 | Subject: [PATCH 226/242] UBUNTU: SAUCE: bpf: reject out-of-bounds stack |
321d628a FG |
5 | pointer calculation |
6 | MIME-Version: 1.0 | |
7 | Content-Type: text/plain; charset=UTF-8 | |
8 | Content-Transfer-Encoding: 8bit | |
9 | ||
10 | Reject programs that compute wildly out-of-bounds stack pointers. | |
11 | Otherwise, pointers can be computed with an offset that doesn't fit into an | |
12 | `int`, causing security issues in the stack memory access check (as well as | |
13 | signed integer overflow during offset addition). | |
14 | ||
15 | This is a fix specifically for the v4.9 stable tree because the mainline | |
16 | code looks very different at this point. | |
17 | ||
18 | Fixes: 7bca0a9702edf ("bpf: enhance verifier to understand stack pointer arithmetic") | |
19 | Signed-off-by: Jann Horn <jannh@google.com> | |
20 | Acked-by: Daniel Borkmann <daniel@iogearbox.net> | |
21 | CVE-2017-17863 | |
22 | Link: https://www.spinics.net/lists/stable/msg206985.html | |
23 | Signed-off-by: Seth Forshee <seth.forshee@canonical.com> | |
24 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
25 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
26 | (cherry picked from commit 1c26ffd0e9b24d512824cabc6687a14d4777d0f3) | |
27 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
28 | --- | |
29 | kernel/bpf/verifier.c | 22 ++++++++++++++++++++-- | |
30 | 1 file changed, 20 insertions(+), 2 deletions(-) | |
31 | ||
32 | diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c | |
33 | index 3940019b9740..4321625fe32a 100644 | |
34 | --- a/kernel/bpf/verifier.c | |
35 | +++ b/kernel/bpf/verifier.c | |
36 | @@ -2122,10 +2122,28 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) | |
37 | ((BPF_SRC(insn->code) == BPF_X && | |
38 | regs[insn->src_reg].type == CONST_IMM) || | |
39 | BPF_SRC(insn->code) == BPF_K)) { | |
40 | - if (BPF_SRC(insn->code) == BPF_X) | |
41 | + if (BPF_SRC(insn->code) == BPF_X) { | |
42 | + /* check in case the register contains a big | |
43 | + * 64-bit value | |
44 | + */ | |
45 | + if (regs[insn->src_reg].imm < -MAX_BPF_STACK || | |
46 | + regs[insn->src_reg].imm > MAX_BPF_STACK) { | |
47 | + verbose("R%d value too big in R%d pointer arithmetic\n", | |
48 | + insn->src_reg, insn->dst_reg); | |
49 | + return -EACCES; | |
50 | + } | |
51 | dst_reg->imm += regs[insn->src_reg].imm; | |
52 | - else | |
53 | + } else { | |
54 | + /* safe against overflow: addition of 32-bit | |
55 | + * numbers in 64-bit representation | |
56 | + */ | |
57 | dst_reg->imm += insn->imm; | |
58 | + } | |
59 | + if (dst_reg->imm > 0 || dst_reg->imm < -MAX_BPF_STACK) { | |
60 | + verbose("R%d out-of-bounds pointer arithmetic\n", | |
61 | + insn->dst_reg); | |
62 | + return -EACCES; | |
63 | + } | |
64 | return 0; | |
65 | } else if (opcode == BPF_ADD && | |
66 | BPF_CLASS(insn->code) == BPF_ALU64 && | |
67 | -- | |
68 | 2.14.2 | |
69 |