Skip to content

Commit 1a3148f

Browse files
Xu Kuohaianakryiko
authored andcommitted
selftests/bpf: Check when bounds are not in the 32-bit range
Add cases to check if bound is updated correctly when 64-bit value is not in the 32-bit range. Signed-off-by: Xu Kuohai <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Acked-by: John Fastabend <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 7be14c1 commit 1a3148f

File tree

1 file changed

+121
-0
lines changed
  • tools/testing/selftests/bpf/verifier

1 file changed

+121
-0
lines changed

tools/testing/selftests/bpf/verifier/bounds.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,3 +753,124 @@
753753
.result_unpriv = REJECT,
754754
.result = ACCEPT,
755755
},
756+
{
757+
"bound check with JMP_JLT for crossing 64-bit signed boundary",
758+
.insns = {
759+
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
760+
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data_end)),
761+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
762+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
763+
BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 8),
764+
765+
BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0),
766+
BPF_LD_IMM64(BPF_REG_0, 0x7fffffffffffff10),
767+
BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
768+
769+
BPF_LD_IMM64(BPF_REG_0, 0x8000000000000000),
770+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
771+
/* r1 unsigned range is [0x7fffffffffffff10, 0x800000000000000f] */
772+
BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_1, -2),
773+
774+
BPF_MOV64_IMM(BPF_REG_0, 0),
775+
BPF_EXIT_INSN(),
776+
},
777+
.result = ACCEPT,
778+
.prog_type = BPF_PROG_TYPE_XDP,
779+
},
780+
{
781+
"bound check with JMP_JSLT for crossing 64-bit signed boundary",
782+
.insns = {
783+
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
784+
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data_end)),
785+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
786+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
787+
BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 8),
788+
789+
BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0),
790+
BPF_LD_IMM64(BPF_REG_0, 0x7fffffffffffff10),
791+
BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
792+
793+
BPF_LD_IMM64(BPF_REG_0, 0x8000000000000000),
794+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
795+
/* r1 signed range is [S64_MIN, S64_MAX] */
796+
BPF_JMP_REG(BPF_JSLT, BPF_REG_0, BPF_REG_1, -2),
797+
798+
BPF_MOV64_IMM(BPF_REG_0, 0),
799+
BPF_EXIT_INSN(),
800+
},
801+
.errstr = "BPF program is too large",
802+
.result = REJECT,
803+
.prog_type = BPF_PROG_TYPE_XDP,
804+
},
805+
{
806+
"bound check for loop upper bound greater than U32_MAX",
807+
.insns = {
808+
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
809+
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data_end)),
810+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
811+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
812+
BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 8),
813+
814+
BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0),
815+
BPF_LD_IMM64(BPF_REG_0, 0x100000000),
816+
BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
817+
818+
BPF_LD_IMM64(BPF_REG_0, 0x100000000),
819+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
820+
BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_1, -2),
821+
822+
BPF_MOV64_IMM(BPF_REG_0, 0),
823+
BPF_EXIT_INSN(),
824+
},
825+
.result = ACCEPT,
826+
.prog_type = BPF_PROG_TYPE_XDP,
827+
},
828+
{
829+
"bound check with JMP32_JLT for crossing 32-bit signed boundary",
830+
.insns = {
831+
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
832+
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data_end)),
833+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
834+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
835+
BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 6),
836+
837+
BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0),
838+
BPF_MOV32_IMM(BPF_REG_0, 0x7fffff10),
839+
BPF_ALU32_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
840+
841+
BPF_MOV32_IMM(BPF_REG_0, 0x80000000),
842+
BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 1),
843+
/* r1 unsigned range is [0, 0x8000000f] */
844+
BPF_JMP32_REG(BPF_JLT, BPF_REG_0, BPF_REG_1, -2),
845+
846+
BPF_MOV64_IMM(BPF_REG_0, 0),
847+
BPF_EXIT_INSN(),
848+
},
849+
.result = ACCEPT,
850+
.prog_type = BPF_PROG_TYPE_XDP,
851+
},
852+
{
853+
"bound check with JMP32_JSLT for crossing 32-bit signed boundary",
854+
.insns = {
855+
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
856+
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data_end)),
857+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
858+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
859+
BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 6),
860+
861+
BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0),
862+
BPF_MOV32_IMM(BPF_REG_0, 0x7fffff10),
863+
BPF_ALU32_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
864+
865+
BPF_MOV32_IMM(BPF_REG_0, 0x80000000),
866+
BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 1),
867+
/* r1 signed range is [S32_MIN, S32_MAX] */
868+
BPF_JMP32_REG(BPF_JSLT, BPF_REG_0, BPF_REG_1, -2),
869+
870+
BPF_MOV64_IMM(BPF_REG_0, 0),
871+
BPF_EXIT_INSN(),
872+
},
873+
.errstr = "BPF program is too large",
874+
.result = REJECT,
875+
.prog_type = BPF_PROG_TYPE_XDP,
876+
},

0 commit comments

Comments
 (0)