From 36a40ded7cf283f89b6d0f30bd474f822f94359d Mon Sep 17 00:00:00 2001 From: Sona Sarmadi Date: Fri, 1 Apr 2016 14:33:51 +0200 Subject: Kernel/bpf: CVE-2016-2383 Incorrect branch fixups for eBPG allow arbitrary read Reference to CVE assignement: http://seclists.org/oss-sec/2016/q1/333 Reference to upstrem patch: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/ patch/?id=0f912f6700a3f14481c13cbda2b9cc1b636948ac Signed-off-by: Sona Sarmadi Signed-off-by: Tudor Florea --- .../linux-hierofalcon-4.1/bpf-CVE-2016-2383.patch | 99 ++++++++++++++++++++++ recipes-kernel/linux/linux-hierofalcon_4.1.bb | 1 + 2 files changed, 100 insertions(+) create mode 100644 recipes-kernel/linux/linux-hierofalcon-4.1/bpf-CVE-2016-2383.patch diff --git a/recipes-kernel/linux/linux-hierofalcon-4.1/bpf-CVE-2016-2383.patch b/recipes-kernel/linux/linux-hierofalcon-4.1/bpf-CVE-2016-2383.patch new file mode 100644 index 0000000..d72d90d --- /dev/null +++ b/recipes-kernel/linux/linux-hierofalcon-4.1/bpf-CVE-2016-2383.patch @@ -0,0 +1,99 @@ +From 0f912f6700a3f14481c13cbda2b9cc1b636948ac Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 10 Feb 2016 16:47:11 +0100 +Subject: [PATCH] bpf: fix branch offset adjustment on backjumps after patching + ctx expansion + +[ Upstream commit a1b14d27ed0965838350f1377ff97c93ee383492 ] + +When ctx access is used, the kernel often needs to expand/rewrite +instructions, so after that patching, branch offsets have to be +adjusted for both forward and backward jumps in the new eBPF program, +but for backward jumps it fails to account the delta. Meaning, for +example, if the expansion happens exactly on the insn that sits at +the jump target, it doesn't fix up the back jump offset. + +Analysis on what the check in adjust_branches() is currently doing: + + /* adjust offset of jmps if necessary */ + if (i < pos && i + insn->off + 1 > pos) + insn->off += delta; + else if (i > pos && i + insn->off + 1 < pos) + insn->off -= delta; + +First condition (forward jumps): + + Before: After: + + insns[0] insns[0] + insns[1] <--- i/insn insns[1] <--- i/insn + insns[2] <--- pos insns[P] <--- pos + insns[3] insns[P] `------| delta + insns[4] <--- target_X insns[P] `-----| + insns[5] insns[3] + insns[4] <--- target_X + insns[5] + +First case is if we cross pos-boundary and the jump instruction was +before pos. This is handeled correctly. I.e. if i == pos, then this +would mean our jump that we currently check was the patchlet itself +that we just injected. Since such patchlets are self-contained and +have no awareness of any insns before or after the patched one, the +delta is correctly not adjusted. Also, for the second condition in +case of i + insn->off + 1 == pos, means we jump to that newly patched +instruction, so no offset adjustment are needed. That part is correct. + +Second condition (backward jumps): + + Before: After: + + insns[0] insns[0] + insns[1] <--- target_X insns[1] <--- target_X + insns[2] <--- pos <-- target_Y insns[P] <--- pos <-- target_Y + insns[3] insns[P] `------| delta + insns[4] <--- i/insn insns[P] `-----| + insns[5] insns[3] + insns[4] <--- i/insn + insns[5] + +Second interesting case is where we cross pos-boundary and the jump +instruction was after pos. Backward jump with i == pos would be +impossible and pose a bug somewhere in the patchlet, so the first +condition checking i > pos is okay only by itself. However, i + +insn->off + 1 < pos does not always work as intended to trigger the +adjustment. It works when jump targets would be far off where the +delta wouldn't matter. But, for example, where the fixed insn->off +before pointed to pos (target_Y), it now points to pos + delta, so +that additional room needs to be taken into account for the check. +This means that i) both tests here need to be adjusted into pos + delta, +and ii) for the second condition, the test needs to be <= as pos +itself can be a target in the backjump, too. + +Fixes CVE-2016-2383. +Upstream-Status: Backport + +Fixes: 9bac3d6d548e ("bpf: allow extended BPF programs access skb fields") +Signed-off-by: Daniel Borkmann +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Sona Sarmadi +--- + kernel/bpf/verifier.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 141d562..6582410 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -1944,7 +1944,7 @@ static void adjust_branches(struct bpf_prog *prog, int pos, int delta) + /* adjust offset of jmps if necessary */ + if (i < pos && i + insn->off + 1 > pos) + insn->off += delta; +- else if (i > pos && i + insn->off + 1 < pos) ++ else if (i > pos + delta && i + insn->off + 1 <= pos + delta) + insn->off -= delta; + } + } +-- +1.9.1 + diff --git a/recipes-kernel/linux/linux-hierofalcon_4.1.bb b/recipes-kernel/linux/linux-hierofalcon_4.1.bb index 8112cdd..1227c71 100644 --- a/recipes-kernel/linux/linux-hierofalcon_4.1.bb +++ b/recipes-kernel/linux/linux-hierofalcon_4.1.bb @@ -34,6 +34,7 @@ SRC_URI = "git://git.yoctoproject.org/linux-yocto-4.1;branch="standard/qemuarm64 file://ipc-CVE-2015-7613.patch \ file://net-unix-CVE-2013-7446.patch \ file://usb-CVE-2015-8816.patch \ + file://bpf-CVE-2016-2383.patch \ " S = "${WORKDIR}/git" -- cgit v1.2.3-54-g00ecf