Patch "bpf: improve verifier packet range checks" has been added to the 4.10-stable tree
Subsystems (5)
This is a note to let you know that I've just added the patch titled
bpf: improve verifier packet range checks
to the 4.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
bpf-improve-verifier-packet-range-checks.patch
and it can be found in the queue-4.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Sat Apr 29 08:22:40 CEST 2017
From: Alexei Starovoitov <[email protected]>
Date: Fri, 24 Mar 2017 15:57:33 -0700
Subject: bpf: improve verifier packet range checks
From: Alexei Starovoitov <[email protected]>
[ Upstream commit b1977682a3858b5584ffea7cfb7bd863f68db18d ]
llvm can optimize the 'if (ptr > data_end)' checks to be in the order slightly different than the original C code which will confuse verifier. Like:
if (ptr + 16 > data_end)
return TC_ACT_SHOT;
// may be followed by
if (ptr + 14 > data_end)
return TC_ACT_SHOT;
while llvm can see that 'ptr' is valid for all 16 bytes,
the verifier could not.
Fix verifier logic to account for such case and add a test.
--- kernel/bpf/verifier.c | 5 +++-- tools/testing/selftests/bpf/test_verifier.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-)
kernel/bpf/verifier.c +3 -2
@@ -1859,14 +1859,15 @@ static void find_good_pkt_pointers(strucfor (i =0 ; i <MAX_BPF_REG ; i++)if (regs[i].type ==PTR_TO_PACKET && regs[i].id == dst_reg->id) - regs[i].range = dst_reg->off; +/* keep the maximum range already checked */ + regs[i].range =max (regs[i].range, dst_reg->off);for (i =0 ; i <MAX_BPF_STACK ; i +=BPF_REG_SIZE ) {if (state->stack_slot_type[i] !=STACK_SPILL )continue ; reg = &state->spilled_regs[i /BPF_REG_SIZE ];if (reg->type ==PTR_TO_PACKET && reg->id == dst_reg->id) - reg->range = dst_reg->off; + reg->range =max (reg->range, dst_reg->off); } }
tools/testing/selftests/bpf/test_verifier.c +20 -0
@@ -2876,6 +2876,26 @@ static struct bpf_test tests[] = { .prog_type = BPF_PROG_TYPE_LWT_XMIT, }, { + "overlapping checks for direct packet access", + .insns = { +BPF_LDX_MEM (BPF_W ,BPF_REG_2 ,BPF_REG_1 , + offsetof(struct __sk_buff , data)), +BPF_LDX_MEM (BPF_W ,BPF_REG_3 ,BPF_REG_1 , + offsetof(struct __sk_buff , data_end)), +BPF_MOV64_REG (BPF_REG_0 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_0 ,8 ), +BPF_JMP_REG (BPF_JGT ,BPF_REG_0 ,BPF_REG_3 ,4 ), +BPF_MOV64_REG (BPF_REG_1 ,BPF_REG_2 ), +BPF_ALU64_IMM (BPF_ADD ,BPF_REG_1 ,6 ), +BPF_JMP_REG (BPF_JGT ,BPF_REG_1 ,BPF_REG_3 ,1 ), +BPF_LDX_MEM (BPF_H ,BPF_REG_0 ,BPF_REG_2 ,6 ), +BPF_MOV64_IMM (BPF_REG_0 ,0 ), + BPF_EXIT_INSN(), + }, + .result =ACCEPT , + .prog_type = BPF_PROG_TYPE_LWT_XMIT, + }, + {"invalid access of tc_classid for LWT_IN" , .insns = { BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
Patches currently in stable-queue which might be from [email protected] are
queue-4.10/bpf-improve-verifier-packet-range-checks.patch