Skip to content

Commit 95a762e

Browse files
thejhborkmann
authored andcommitted
bpf: fix incorrect sign extension in check_alu_op()
Distinguish between BPF_ALU64|BPF_MOV|BPF_K (load 32-bit immediate, sign-extended to 64-bit) and BPF_ALU|BPF_MOV|BPF_K (load 32-bit immediate, zero-padded to 64-bit); only perform sign extension in the first case. Starting with v4.14, this is exploitable by unprivileged users as long as the unprivileged_bpf_disabled sysctl isn't set. Debian assigned CVE-2017-16995 for this issue. v3: - add CVE number (Ben Hutchings) Fixes: 4846113 ("bpf: allow access into map value arrays") Signed-off-by: Jann Horn <jannh@google.com> Acked-by: Edward Cree <ecree@solarflare.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 4374f25 commit 95a762e

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

kernel/bpf/verifier.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2408,7 +2408,13 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
24082408
* remember the value we stored into this reg
24092409
*/
24102410
regs[insn->dst_reg].type = SCALAR_VALUE;
2411-
__mark_reg_known(regs + insn->dst_reg, insn->imm);
2411+
if (BPF_CLASS(insn->code) == BPF_ALU64) {
2412+
__mark_reg_known(regs + insn->dst_reg,
2413+
insn->imm);
2414+
} else {
2415+
__mark_reg_known(regs + insn->dst_reg,
2416+
(u32)insn->imm);
2417+
}
24122418
}
24132419

24142420
} else if (opcode > BPF_END) {

0 commit comments

Comments
 (0)