Skip to content

Commit 24b4d2a

Browse files
Alex Gartrelldavem330
authored andcommitted
ebpf: Allow dereferences of PTR_TO_STACK registers
mov %rsp, %r1 ; r1 = rsp add $-8, %r1 ; r1 = rsp - 8 store_q $123, -8(%rsp) ; *(u64*)r1 = 123 <- valid store_q $123, (%r1) ; *(u64*)r1 = 123 <- previously invalid mov $0, %r0 exit ; Always need to exit And we'd get the following error: 0: (bf) r1 = r10 1: (07) r1 += -8 2: (7a) *(u64 *)(r10 -8) = 999 3: (7a) *(u64 *)(r1 +0) = 999 R1 invalid mem access 'fp' Unable to load program We already know that a register is a stack address and the appropriate offset, so we should be able to validate those references as well. Signed-off-by: Alex Gartrell <agartrell@fb.com> Acked-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 6ecfdd2 commit 24b4d2a

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

kernel/bpf/verifier.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,9 @@ static int check_mem_access(struct verifier_env *env, u32 regno, int off,
648648
struct verifier_state *state = &env->cur_state;
649649
int size, err = 0;
650650

651+
if (state->regs[regno].type == PTR_TO_STACK)
652+
off += state->regs[regno].imm;
653+
651654
size = bpf_size_to_bytes(bpf_size);
652655
if (size < 0)
653656
return size;
@@ -667,7 +670,8 @@ static int check_mem_access(struct verifier_env *env, u32 regno, int off,
667670
if (!err && t == BPF_READ && value_regno >= 0)
668671
mark_reg_unknown_value(state->regs, value_regno);
669672

670-
} else if (state->regs[regno].type == FRAME_PTR) {
673+
} else if (state->regs[regno].type == FRAME_PTR ||
674+
state->regs[regno].type == PTR_TO_STACK) {
671675
if (off >= 0 || off < -MAX_BPF_STACK) {
672676
verbose("invalid stack off=%d size=%d\n", off, size);
673677
return -EACCES;

samples/bpf/test_verifier.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,65 @@ static struct bpf_test tests[] = {
822822
.result = ACCEPT,
823823
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
824824
},
825+
{
826+
"PTR_TO_STACK store/load",
827+
.insns = {
828+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
829+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
830+
BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
831+
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
832+
BPF_EXIT_INSN(),
833+
},
834+
.result = ACCEPT,
835+
},
836+
{
837+
"PTR_TO_STACK store/load - bad alignment on off",
838+
.insns = {
839+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
840+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
841+
BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
842+
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
843+
BPF_EXIT_INSN(),
844+
},
845+
.result = REJECT,
846+
.errstr = "misaligned access off -6 size 8",
847+
},
848+
{
849+
"PTR_TO_STACK store/load - bad alignment on reg",
850+
.insns = {
851+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
852+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
853+
BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
854+
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
855+
BPF_EXIT_INSN(),
856+
},
857+
.result = REJECT,
858+
.errstr = "misaligned access off -2 size 8",
859+
},
860+
{
861+
"PTR_TO_STACK store/load - out of bounds low",
862+
.insns = {
863+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
864+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
865+
BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
866+
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
867+
BPF_EXIT_INSN(),
868+
},
869+
.result = REJECT,
870+
.errstr = "invalid stack off=-79992 size=8",
871+
},
872+
{
873+
"PTR_TO_STACK store/load - out of bounds high",
874+
.insns = {
875+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
876+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
877+
BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
878+
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
879+
BPF_EXIT_INSN(),
880+
},
881+
.result = REJECT,
882+
.errstr = "invalid stack off=0 size=8",
883+
},
825884
};
826885

827886
static int probe_filter_length(struct bpf_insn *fp)

0 commit comments

Comments
 (0)