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.