requesting stable backport for 4.1 and 4.4: 95a762e2c8c9 ("bpf: fix incorrect sign extension in check_alu_op()")

Jann Horn
2018-03-18T02:17:39Z

Hi!

Someone on Twitter
(https://twitter.com/vnik5287/status/974277953394651137) is pointing
out that the BPF fix commit 95a762e2c8c942780948091f8f2a4f32fce1ac6f
("bpf: fix incorrect sign extension in check_alu_op()") needs to be
applied all the way back to 4.4, and probably also 4.1; my "Fixes:"
tag on that commit is incorrect. I assumed that without map access,
math correctness issues don't matter, but actually, this one does
matter because check_cond_jmp_op() will omit verification for branches
that appear to be unreachable (comparison of CONST_IMM register and a
constant value). :/

FWIW, I checked by hand what the binary blob of BPF code in the linked
PoC does, and it's basically this (with some error checking and other
minor stuff omitted):

// trick the verifier into not checking any of the code below
r9 = (u32)-1
if (r9 == (s32)-1) exit 0

// read some configuration
r6 = *map_lookup_elem(MAP_FD, &0) // operation selector
r7 = *map_lookup_elem(MAP_FD, &1) // pointer to access
r8 = *map_lookup_elem(MAP_FD, &2) // value to write
r2 = map_lookup_elem(MAP_FD, &2)

if r6 == 0: // operation: read
r3 = *r7
*r2 = r3
exit
if r6 == 1: // operation: get frame pointer
*r2 = fp
exit
*r7 = r8 // operation: write
exit

The author of the tweet does point out that this exploit is mitigated
by sanitize_dead_code() (introduced in "bpf: fix branch pruning logic"
and backported all the way), but 95a762e2c8c9 should still be applied.