Skip to content

Commit 51fda35

Browse files
shiloongmaqiao-mq
authored andcommitted
Revert "bpf: track spill/fill of constants"
ANBZ: torvalds#342 This reverts commit 565c32b. Signed-off-by: Qiao Ma <[email protected]> Acked-by: Mao Wenan <[email protected]> Acked-by: Tony Lu <[email protected]>
1 parent 6238854 commit 51fda35

File tree

1 file changed

+23
-63
lines changed

1 file changed

+23
-63
lines changed

kernel/bpf/verifier.c

Lines changed: 23 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -964,23 +964,6 @@ static bool register_is_null(struct bpf_reg_state *reg)
964964
return reg->type == SCALAR_VALUE && tnum_equals_const(reg->var_off, 0);
965965
}
966966

967-
static bool register_is_const(struct bpf_reg_state *reg)
968-
{
969-
return reg->type == SCALAR_VALUE && tnum_is_const(reg->var_off);
970-
}
971-
972-
static void save_register_state(struct bpf_func_state *state,
973-
int spi, struct bpf_reg_state *reg)
974-
{
975-
int i;
976-
977-
state->stack[spi].spilled_ptr = *reg;
978-
state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN;
979-
980-
for (i = 0; i < BPF_REG_SIZE; i++)
981-
state->stack[spi].slot_type[i] = STACK_SPILL;
982-
}
983-
984967
/* check_stack_read/write functions track spill/fill of registers,
985968
* stack boundary and alignment are checked in check_mem_access()
986969
*/
@@ -990,7 +973,7 @@ static int check_stack_write(struct bpf_verifier_env *env,
990973
{
991974
struct bpf_func_state *cur; /* state of the current function */
992975
int i, slot = -off - 1, spi = slot / BPF_REG_SIZE, err;
993-
struct bpf_reg_state *reg = NULL;
976+
enum bpf_reg_type type;
994977

995978
err = realloc_func_state(state, round_up(slot + 1, BPF_REG_SIZE),
996979
true);
@@ -1007,36 +990,27 @@ static int check_stack_write(struct bpf_verifier_env *env,
1007990
}
1008991

1009992
cur = env->cur_state->frame[env->cur_state->curframe];
1010-
if (value_regno >= 0)
1011-
reg = &cur->regs[value_regno];
993+
if (value_regno >= 0 &&
994+
is_spillable_regtype((type = cur->regs[value_regno].type))) {
1012995

1013-
if (reg && size == BPF_REG_SIZE && register_is_const(reg) &&
1014-
!register_is_null(reg) && env->allow_ptr_leaks) {
1015-
save_register_state(state, spi, reg);
1016-
} else if (reg && is_spillable_regtype(reg->type)) {
1017996
/* register containing pointer is being spilled into stack */
1018997
if (size != BPF_REG_SIZE) {
1019998
verbose(env, "invalid size of register spill\n");
1020999
return -EACCES;
10211000
}
10221001

1023-
if (state != cur && reg->type == PTR_TO_STACK) {
1002+
if (state != cur && type == PTR_TO_STACK) {
10241003
verbose(env, "cannot spill pointers to stack into stack frame of the caller\n");
10251004
return -EINVAL;
10261005
}
10271006

1028-
if (!env->allow_ptr_leaks) {
1029-
bool sanitize = false;
1007+
/* save register state */
1008+
state->stack[spi].spilled_ptr = cur->regs[value_regno];
1009+
state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN;
10301010

1031-
if (state->stack[spi].slot_type[0] == STACK_SPILL &&
1032-
register_is_const(&state->stack[spi].spilled_ptr))
1033-
sanitize = true;
1034-
for (i = 0; i < BPF_REG_SIZE; i++)
1035-
if (state->stack[spi].slot_type[i] == STACK_MISC) {
1036-
sanitize = true;
1037-
break;
1038-
}
1039-
if (sanitize) {
1011+
for (i = 0; i < BPF_REG_SIZE; i++) {
1012+
if (state->stack[spi].slot_type[i] == STACK_MISC &&
1013+
!env->allow_ptr_leaks) {
10401014
int *poff = &env->insn_aux_data[insn_idx].sanitize_stack_off;
10411015
int soff = (-spi - 1) * BPF_REG_SIZE;
10421016

@@ -1059,8 +1033,8 @@ static int check_stack_write(struct bpf_verifier_env *env,
10591033
}
10601034
*poff = soff;
10611035
}
1036+
state->stack[spi].slot_type[i] = STACK_SPILL;
10621037
}
1063-
save_register_state(state, spi, reg);
10641038
} else {
10651039
u8 type = STACK_MISC;
10661040

@@ -1083,7 +1057,8 @@ static int check_stack_write(struct bpf_verifier_env *env,
10831057
state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN;
10841058

10851059
/* when we zero initialize stack slots mark them as such */
1086-
if (reg && register_is_null(reg))
1060+
if (value_regno >= 0 &&
1061+
register_is_null(&cur->regs[value_regno]))
10871062
type = STACK_ZERO;
10881063

10891064
/* Mark slots affected by this stack write. */
@@ -1101,7 +1076,6 @@ static int check_stack_read(struct bpf_verifier_env *env,
11011076
struct bpf_verifier_state *vstate = env->cur_state;
11021077
struct bpf_func_state *state = vstate->frame[vstate->curframe];
11031078
int i, slot = -off - 1, spi = slot / BPF_REG_SIZE;
1104-
struct bpf_reg_state *reg;
11051079
u8 *stype;
11061080

11071081
if (reg_state->allocated_stack <= slot) {
@@ -1110,20 +1084,11 @@ static int check_stack_read(struct bpf_verifier_env *env,
11101084
return -EACCES;
11111085
}
11121086
stype = reg_state->stack[spi].slot_type;
1113-
reg = &reg_state->stack[spi].spilled_ptr;
11141087

11151088
if (stype[0] == STACK_SPILL) {
11161089
if (size != BPF_REG_SIZE) {
1117-
if (reg->type != SCALAR_VALUE) {
1118-
verbose(env, "invalid size of register fill\n");
1119-
return -EACCES;
1120-
}
1121-
if (value_regno >= 0) {
1122-
mark_reg_unknown(env, state->regs, value_regno);
1123-
state->regs[value_regno].live |= REG_LIVE_WRITTEN;
1124-
}
1125-
mark_reg_read(env, reg, reg->parent);
1126-
return 0;
1090+
verbose(env, "invalid size of register spill\n");
1091+
return -EACCES;
11271092
}
11281093
for (i = 1; i < BPF_REG_SIZE; i++) {
11291094
if (stype[(slot - i) % BPF_REG_SIZE] != STACK_SPILL) {
@@ -1134,14 +1099,16 @@ static int check_stack_read(struct bpf_verifier_env *env,
11341099

11351100
if (value_regno >= 0) {
11361101
/* restore register state from stack */
1137-
state->regs[value_regno] = *reg;
1102+
state->regs[value_regno] = reg_state->stack[spi].spilled_ptr;
11381103
/* mark reg as written since spilled pointer state likely
11391104
* has its liveness marks cleared by is_state_visited()
11401105
* which resets stack/reg liveness for state transitions
11411106
*/
11421107
state->regs[value_regno].live |= REG_LIVE_WRITTEN;
11431108
}
1144-
mark_reg_read(env, reg, reg->parent);
1109+
mark_reg_read(env, &reg_state->stack[spi].spilled_ptr,
1110+
reg_state->stack[spi].spilled_ptr.parent);
1111+
return 0;
11451112
} else {
11461113
int zeros = 0;
11471114

@@ -1156,7 +1123,8 @@ static int check_stack_read(struct bpf_verifier_env *env,
11561123
off, i, size);
11571124
return -EACCES;
11581125
}
1159-
mark_reg_read(env, reg, reg->parent);
1126+
mark_reg_read(env, &reg_state->stack[spi].spilled_ptr,
1127+
reg_state->stack[spi].spilled_ptr.parent);
11601128
if (value_regno >= 0) {
11611129
if (zeros == size) {
11621130
/* any size read into register is zero extended,
@@ -1169,8 +1137,8 @@ static int check_stack_read(struct bpf_verifier_env *env,
11691137
}
11701138
state->regs[value_regno].live |= REG_LIVE_WRITTEN;
11711139
}
1140+
return 0;
11721141
}
1173-
return 0;
11741142
}
11751143

11761144
static int check_stack_access(struct bpf_verifier_env *env,
@@ -1823,7 +1791,7 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno,
18231791
{
18241792
struct bpf_reg_state *reg = cur_regs(env) + regno;
18251793
struct bpf_func_state *state = func(env, reg);
1826-
int err, min_off, max_off, i, j, slot, spi;
1794+
int err, min_off, max_off, i, slot, spi;
18271795

18281796
if (reg->type != PTR_TO_STACK) {
18291797
/* Allow zero-byte read from NULL, regardless of pointer type */
@@ -1911,14 +1879,6 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno,
19111879
*stype = STACK_MISC;
19121880
goto mark;
19131881
}
1914-
if (state->stack[spi].slot_type[0] == STACK_SPILL &&
1915-
state->stack[spi].spilled_ptr.type == SCALAR_VALUE) {
1916-
__mark_reg_unknown(&state->stack[spi].spilled_ptr);
1917-
for (j = 0; j < BPF_REG_SIZE; j++)
1918-
state->stack[spi].slot_type[j] = STACK_MISC;
1919-
goto mark;
1920-
}
1921-
19221882
err:
19231883
if (tnum_is_const(reg->var_off)) {
19241884
verbose(env, "invalid indirect read from stack off %d+%d size %d\n",

0 commit comments

Comments
 (0)