1. 28 Sep, 2021 23 commits
  2. 27 Sep, 2021 14 commits
  3. 26 Sep, 2021 3 commits
    • Alexei Starovoitov's avatar
      Merge branch 'bpf: Support <8-byte scalar spill and refill' · e7d5184b
      Alexei Starovoitov authored
      Martin KaFai says:
      
      ====================
      
      The verifier currently does not save the reg state when
      spilling <8byte bounded scalar to the stack.  The bpf program
      will be incorrectly rejected when this scalar is refilled to
      the reg and then used to offset into a packet header.
      The later patch has a simplified bpf prog from a real use case
      to demonstrate this case.  The current work around is
      to reparse the packet again such that this offset scalar
      is close to where the packet data will be accessed to
      avoid the spill.  Thus, the header is parsed twice.
      
      The llvm patch [1] will align the <8bytes spill to
      the 8-byte stack address.  This set is to make the necessary
      changes in verifier to support <8byte scalar spill and refill.
      
      [1] https://reviews.llvm.org/D109073
      
      v2:
      - Changed the xdpwall selftest in patch 3 to trigger a u32
        spill at a non 8-byte aligned stack address.  The v1 has
        simplified the real example too much such that it only
        triggers a u32 spill but does not spill at a non
        8-byte aligned stack address.
      - Changed README.rst in patch 3 to explain the llvm dependency
        for the xdpwall test.
      ====================
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      e7d5184b
    • Martin KaFai Lau's avatar
      bpf: selftest: Add verifier tests for <8-byte scalar spill and refill · ef979017
      Martin KaFai Lau authored
      This patch adds a few verifier tests for <8-byte spill and refill.
      Signed-off-by: default avatarMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20210922004953.627183-1-kafai@fb.com
      ef979017
    • Martin KaFai Lau's avatar
      bpf: selftest: A bpf prog that has a 32bit scalar spill · 54ea6079
      Martin KaFai Lau authored
      It is a simplified example that can trigger a 32bit scalar spill.
      The const scalar is refilled and added to a skb->data later.
      Since the reg state of the 32bit scalar spill is not saved now,
      adding the refilled reg to skb->data and then comparing it with
      skb->data_end cannot verify the skb->data access.
      
      With the earlier verifier patch and the llvm patch [1].  The verifier
      can correctly verify the bpf prog.
      
      Here is the snippet of the verifier log that leads to verifier conclusion
      that the packet data is unsafe to read.  The log is from the kerne
      without the previous verifier patch to save the <8-byte scalar spill.
      67: R0=inv1 R1=inv17 R2=invP2 R3=inv1 R4=pkt(id=0,off=68,r=102,imm=0) R5=inv102 R6=pkt(id=0,off=62,r=102,imm=0) R7=pkt(id=0,off=0,r=102,imm=0) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0
      67: (63) *(u32 *)(r10 -12) = r5
      68: R0=inv1 R1=inv17 R2=invP2 R3=inv1 R4=pkt(id=0,off=68,r=102,imm=0) R5=inv102 R6=pkt(id=0,off=62,r=102,imm=0) R7=pkt(id=0,off=0,r=102,imm=0) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 fp-16=mmmm????
      ...
      101: R0_w=map_value_or_null(id=2,off=0,ks=16,vs=1,imm=0) R6_w=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=0,off=0,r=102,imm=0) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 fp-16=mmmmmmmm
      101: (61) r1 = *(u32 *)(r10 -12)
      102: R0_w=map_value_or_null(id=2,off=0,ks=16,vs=1,imm=0) R1_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6_w=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=0,off=0,r=102,imm=0) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 fp-16=mmmmmmmm
      102: (bc) w1 = w1
      103: R0_w=map_value_or_null(id=2,off=0,ks=16,vs=1,imm=0) R1_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6_w=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=0,off=0,r=102,imm=0) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 fp-16=mmmmmmmm
      103: (0f) r7 += r1
      last_idx 103 first_idx 67
      regs=2 stack=0 before 102: (bc) w1 = w1
      regs=2 stack=0 before 101: (61) r1 = *(u32 *)(r10 -12)
      104: R0_w=map_value_or_null(id=2,off=0,ks=16,vs=1,imm=0) R1_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6_w=pkt(id=0,off=70,r=102,imm=0) R7_w=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 fp-16=mmmmmmmm
      ...
      127: R0_w=inv1 R1=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9_w=invP17 R10=fp0 fp-16=mmmmmmmm
      127: (bf) r1 = r7
      128: R0_w=inv1 R1_w=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9_w=invP17 R10=fp0 fp-16=mmmmmmmm
      128: (07) r1 += 8
      129: R0_w=inv1 R1_w=pkt(id=3,off=8,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9_w=invP17 R10=fp0 fp-16=mmmmmmmm
      129: (b4) w0 = 1
      130: R0=inv1 R1=pkt(id=3,off=8,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9=invP17 R10=fp0 fp-16=mmmmmmmm
      130: (2d) if r1 > r8 goto pc-66
       R0=inv1 R1=pkt(id=3,off=8,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9=invP17 R10=fp0 fp-16=mmmmmmmm
      131: R0=inv1 R1=pkt(id=3,off=8,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9=invP17 R10=fp0 fp-16=mmmmmmmm
      131: (69) r6 = *(u16 *)(r7 +0)
      invalid access to packet, off=0 size=2, R7(id=3,off=0,r=0)
      R7 offset is outside of the packet
      
      [1]: https://reviews.llvm.org/D109073Signed-off-by: default avatarMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20210922004947.626286-1-kafai@fb.com
      54ea6079