mirror of
https://github.com/torvalds/linux.git
synced 2026-04-20 07:43:57 -04:00
The verifier currently limits direct offsets into a map to 512MiB to avoid overflow during pointer arithmetic. However, this prevents arena maps from using direct addressing instructions to access data at the end of > 512MiB arena maps. This is necessary when moving arena globals to the end of the arena instead of the front. Refactor the verifier code to remove the offset calculation during direct value access calculations. This is possible because the only two map types that implement .map_direct_value_addr() are arrays and arenas, and they both do their own internal checks to ensure the offset is within bounds. Adjust selftests that expect the old error. These tests still fail because the verifier identifies the access as out of bounds for the map, so change them to expect an "invalid access to map value pointer" error instead. Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20251216173325.98465-3-emil@etsalapatis.com
351 lines
8.2 KiB
C
351 lines
8.2 KiB
C
{
|
|
"direct map access, write test 1",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 0),
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 4242),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = ACCEPT,
|
|
.retval = 1,
|
|
},
|
|
{
|
|
"direct map access, write test 2",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 8),
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 4242),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = ACCEPT,
|
|
.retval = 1,
|
|
},
|
|
{
|
|
"direct map access, write test 3",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 8),
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 4242),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = ACCEPT,
|
|
.retval = 1,
|
|
},
|
|
{
|
|
"direct map access, write test 4",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 40),
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 4242),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = ACCEPT,
|
|
.retval = 1,
|
|
},
|
|
{
|
|
"direct map access, write test 5",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 32),
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 4242),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = ACCEPT,
|
|
.retval = 1,
|
|
},
|
|
{
|
|
"direct map access, write test 6",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 40),
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_1, 4, 4242),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "R1 min value is outside of the allowed memory range",
|
|
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
|
},
|
|
{
|
|
"direct map access, write test 7",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, -1),
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_1, 4, 4242),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid access to map value pointer, value_size=48 off=4294967295",
|
|
},
|
|
{
|
|
"direct map access, write test 8",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 1),
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_1, -1, 4242),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = ACCEPT,
|
|
.retval = 1,
|
|
},
|
|
{
|
|
"direct map access, write test 9",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 48),
|
|
BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 4242),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid access to map value pointer",
|
|
},
|
|
{
|
|
"direct map access, write test 10",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 47),
|
|
BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 4),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = ACCEPT,
|
|
.retval = 1,
|
|
},
|
|
{
|
|
"direct map access, write test 11",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 48),
|
|
BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 4),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid access to map value pointer",
|
|
},
|
|
{
|
|
"direct map access, write test 12",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, (1<<29)),
|
|
BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 4),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid access to map value pointer, value_size=48 off=536870912",
|
|
},
|
|
{
|
|
"direct map access, write test 13",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, (1<<29)-1),
|
|
BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 4),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid access to map value pointer, value_size=48 off=536870911",
|
|
},
|
|
{
|
|
"direct map access, write test 14",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 47),
|
|
BPF_LD_MAP_VALUE(BPF_REG_2, 0, 46),
|
|
BPF_ST_MEM(BPF_H, BPF_REG_2, 0, 0xffff),
|
|
BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1, 3 },
|
|
.result = ACCEPT,
|
|
.retval = 0xff,
|
|
},
|
|
{
|
|
"direct map access, write test 15",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 46),
|
|
BPF_LD_MAP_VALUE(BPF_REG_2, 0, 46),
|
|
BPF_ST_MEM(BPF_H, BPF_REG_2, 0, 0xffff),
|
|
BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1, 0),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1, 3 },
|
|
.result = ACCEPT,
|
|
.retval = 0xffff,
|
|
},
|
|
{
|
|
"direct map access, write test 16",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 46),
|
|
BPF_LD_MAP_VALUE(BPF_REG_2, 0, 47),
|
|
BPF_ST_MEM(BPF_H, BPF_REG_2, 0, 0xffff),
|
|
BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1, 0),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1, 3 },
|
|
.result = REJECT,
|
|
.errstr = "invalid access to map value, value_size=48 off=47 size=2",
|
|
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
|
},
|
|
{
|
|
"direct map access, write test 17",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 46),
|
|
BPF_LD_MAP_VALUE(BPF_REG_2, 0, 46),
|
|
BPF_ST_MEM(BPF_H, BPF_REG_2, 1, 0xffff),
|
|
BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1, 0),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1, 3 },
|
|
.result = REJECT,
|
|
.errstr = "invalid access to map value, value_size=48 off=47 size=2",
|
|
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
|
},
|
|
{
|
|
"direct map access, write test 18",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 0),
|
|
BPF_ST_MEM(BPF_H, BPF_REG_1, 0, 42),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_small = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "R1 min value is outside of the allowed memory range",
|
|
},
|
|
{
|
|
"direct map access, write test 19",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 0),
|
|
BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_small = { 1 },
|
|
.result = ACCEPT,
|
|
.retval = 1,
|
|
},
|
|
{
|
|
"direct map access, write test 20",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 1),
|
|
BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_small = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid access to map value pointer",
|
|
},
|
|
{
|
|
"direct map access, invalid insn test 1",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, 0, 1, 0, 47),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid bpf_ld_imm64 insn",
|
|
},
|
|
{
|
|
"direct map access, invalid insn test 2",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, 1, 0, 0, 47),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "BPF_LD_IMM64 uses reserved fields",
|
|
},
|
|
{
|
|
"direct map access, invalid insn test 3",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, ~0, 0, 0, 47),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "BPF_LD_IMM64 uses reserved fields",
|
|
},
|
|
{
|
|
"direct map access, invalid insn test 4",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, 0, ~0, 0, 47),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid bpf_ld_imm64 insn",
|
|
},
|
|
{
|
|
"direct map access, invalid insn test 5",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, ~0, ~0, 0, 47),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid bpf_ld_imm64 insn",
|
|
},
|
|
{
|
|
"direct map access, invalid insn test 6",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_FD, ~0, 0, 0, 0),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "BPF_LD_IMM64 uses reserved fields",
|
|
},
|
|
{
|
|
"direct map access, invalid insn test 7",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_FD, 0, ~0, 0, 0),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid bpf_ld_imm64 insn",
|
|
},
|
|
{
|
|
"direct map access, invalid insn test 8",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_FD, ~0, ~0, 0, 0),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "invalid bpf_ld_imm64 insn",
|
|
},
|
|
{
|
|
"direct map access, invalid insn test 9",
|
|
.insns = {
|
|
BPF_MOV64_IMM(BPF_REG_0, 1),
|
|
BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_FD, 0, 0, 0, 47),
|
|
BPF_EXIT_INSN(),
|
|
},
|
|
.fixup_map_array_48b = { 1 },
|
|
.result = REJECT,
|
|
.errstr = "unrecognized bpf_ld_imm64 insn",
|
|
},
|