]> git.proxmox.com Git - pve-kernel.git/blob - patches/kernel/0226-UBUNTU-SAUCE-bpf-reject-out-of-bounds-stack-pointer-.patch
2d4c780e606c4fe43816d478273c953daf6cca81
[pve-kernel.git] / patches / kernel / 0226-UBUNTU-SAUCE-bpf-reject-out-of-bounds-stack-pointer-.patch
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
4 Subject: [PATCH 226/233] UBUNTU: SAUCE: bpf: reject out-of-bounds stack
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