Skip to content

Commit 4c01b7f

Browse files
ecree-solarflareshiloong
authored andcommitted
bpf/verifier: per-register parent pointers
OpenAnolis Bug Tracker: 0000429 commit 679c782 upstream. By giving each register its own liveness chain, we elide the skip_callee() logic. Instead, each register's parent is the state it inherits from; both check_func_call() and prepare_func_exit() automatically connect reg states to the correct chain since when they copy the reg state across (r1-r5 into the callee as args, and r0 out as the return value) they also copy the parent pointer. Signed-off-by: Edward Cree <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> [OP: adjusted context for 4.19] Signed-off-by: Ovidiu Panait <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Fixes: CVE-2021-34556, CVE-2021-35477 Signed-off-by: Shile Zhang <[email protected]> Acked-by: Mao Wenan <[email protected]>
1 parent 518cf6c commit 4c01b7f

File tree

2 files changed

+47
-144
lines changed

2 files changed

+47
-144
lines changed

include/linux/bpf_verifier.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum bpf_reg_liveness {
4141
};
4242

4343
struct bpf_reg_state {
44+
/* Ordering of fields matters. See states_equal() */
4445
enum bpf_reg_type type;
4546
union {
4647
/* valid when type == PTR_TO_PACKET */
@@ -62,7 +63,6 @@ struct bpf_reg_state {
6263
* came from, when one is tested for != NULL.
6364
*/
6465
u32 id;
65-
/* Ordering of fields matters. See states_equal() */
6666
/* For scalar types (SCALAR_VALUE), this represents our knowledge of
6767
* the actual value.
6868
* For pointer types, this represents the variable part of the offset
@@ -79,15 +79,15 @@ struct bpf_reg_state {
7979
s64 smax_value; /* maximum possible (s64)value */
8080
u64 umin_value; /* minimum possible (u64)value */
8181
u64 umax_value; /* maximum possible (u64)value */
82+
/* parentage chain for liveness checking */
83+
struct bpf_reg_state *parent;
8284
/* Inside the callee two registers can be both PTR_TO_STACK like
8385
* R1=fp-8 and R2=fp-8, but one of them points to this function stack
8486
* while another to the caller's stack. To differentiate them 'frameno'
8587
* is used which is an index in bpf_verifier_state->frame[] array
8688
* pointing to bpf_func_state.
87-
* This field must be second to last, for states_equal() reasons.
8889
*/
8990
u32 frameno;
90-
/* This field must be last, for states_equal() reasons. */
9191
enum bpf_reg_liveness live;
9292
};
9393

@@ -110,7 +110,6 @@ struct bpf_stack_state {
110110
*/
111111
struct bpf_func_state {
112112
struct bpf_reg_state regs[MAX_BPF_REG];
113-
struct bpf_verifier_state *parent;
114113
/* index of call instruction that called into this func */
115114
int callsite;
116115
/* stack frame number of this function state from pov of
@@ -132,7 +131,6 @@ struct bpf_func_state {
132131
struct bpf_verifier_state {
133132
/* call stack tracking */
134133
struct bpf_func_state *frame[MAX_CALL_FRAMES];
135-
struct bpf_verifier_state *parent;
136134
u32 curframe;
137135
bool speculative;
138136
};

kernel/bpf/verifier.c

Lines changed: 44 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,9 @@ static int copy_stack_state(struct bpf_func_state *dst,
381381
/* do_check() starts with zero-sized stack in struct bpf_verifier_state to
382382
* make it consume minimal amount of memory. check_stack_write() access from
383383
* the program calls into realloc_func_state() to grow the stack size.
384-
* Note there is a non-zero 'parent' pointer inside bpf_verifier_state
385-
* which this function copies over. It points to previous bpf_verifier_state
386-
* which is never reallocated
384+
* Note there is a non-zero parent pointer inside each reg of bpf_verifier_state
385+
* which this function copies over. It points to corresponding reg in previous
386+
* bpf_verifier_state which is never reallocated
387387
*/
388388
static int realloc_func_state(struct bpf_func_state *state, int size,
389389
bool copy_old)
@@ -468,7 +468,6 @@ static int copy_verifier_state(struct bpf_verifier_state *dst_state,
468468
}
469469
dst_state->speculative = src->speculative;
470470
dst_state->curframe = src->curframe;
471-
dst_state->parent = src->parent;
472471
for (i = 0; i <= src->curframe; i++) {
473472
dst = dst_state->frame[i];
474473
if (!dst) {
@@ -740,6 +739,7 @@ static void init_reg_state(struct bpf_verifier_env *env,
740739
for (i = 0; i < MAX_BPF_REG; i++) {
741740
mark_reg_not_init(env, regs, i);
742741
regs[i].live = REG_LIVE_NONE;
742+
regs[i].parent = NULL;
743743
}
744744

745745
/* frame pointer */
@@ -884,74 +884,21 @@ static int check_subprogs(struct bpf_verifier_env *env)
884884
return 0;
885885
}
886886

887-
static
888-
struct bpf_verifier_state *skip_callee(struct bpf_verifier_env *env,
889-
const struct bpf_verifier_state *state,
890-
struct bpf_verifier_state *parent,
891-
u32 regno)
892-
{
893-
struct bpf_verifier_state *tmp = NULL;
894-
895-
/* 'parent' could be a state of caller and
896-
* 'state' could be a state of callee. In such case
897-
* parent->curframe < state->curframe
898-
* and it's ok for r1 - r5 registers
899-
*
900-
* 'parent' could be a callee's state after it bpf_exit-ed.
901-
* In such case parent->curframe > state->curframe
902-
* and it's ok for r0 only
903-
*/
904-
if (parent->curframe == state->curframe ||
905-
(parent->curframe < state->curframe &&
906-
regno >= BPF_REG_1 && regno <= BPF_REG_5) ||
907-
(parent->curframe > state->curframe &&
908-
regno == BPF_REG_0))
909-
return parent;
910-
911-
if (parent->curframe > state->curframe &&
912-
regno >= BPF_REG_6) {
913-
/* for callee saved regs we have to skip the whole chain
914-
* of states that belong to callee and mark as LIVE_READ
915-
* the registers before the call
916-
*/
917-
tmp = parent;
918-
while (tmp && tmp->curframe != state->curframe) {
919-
tmp = tmp->parent;
920-
}
921-
if (!tmp)
922-
goto bug;
923-
parent = tmp;
924-
} else {
925-
goto bug;
926-
}
927-
return parent;
928-
bug:
929-
verbose(env, "verifier bug regno %d tmp %p\n", regno, tmp);
930-
verbose(env, "regno %d parent frame %d current frame %d\n",
931-
regno, parent->curframe, state->curframe);
932-
return NULL;
933-
}
934-
887+
/* Parentage chain of this register (or stack slot) should take care of all
888+
* issues like callee-saved registers, stack slot allocation time, etc.
889+
*/
935890
static int mark_reg_read(struct bpf_verifier_env *env,
936-
const struct bpf_verifier_state *state,
937-
struct bpf_verifier_state *parent,
938-
u32 regno)
891+
const struct bpf_reg_state *state,
892+
struct bpf_reg_state *parent)
939893
{
940894
bool writes = parent == state->parent; /* Observe write marks */
941895

942-
if (regno == BPF_REG_FP)
943-
/* We don't need to worry about FP liveness because it's read-only */
944-
return 0;
945-
946896
while (parent) {
947897
/* if read wasn't screened by an earlier write ... */
948-
if (writes && state->frame[state->curframe]->regs[regno].live & REG_LIVE_WRITTEN)
898+
if (writes && state->live & REG_LIVE_WRITTEN)
949899
break;
950-
parent = skip_callee(env, state, parent, regno);
951-
if (!parent)
952-
return -EFAULT;
953900
/* ... then we depend on parent's value */
954-
parent->frame[parent->curframe]->regs[regno].live |= REG_LIVE_READ;
901+
parent->live |= REG_LIVE_READ;
955902
state = parent;
956903
parent = state->parent;
957904
writes = true;
@@ -977,7 +924,10 @@ static int check_reg_arg(struct bpf_verifier_env *env, u32 regno,
977924
verbose(env, "R%d !read_ok\n", regno);
978925
return -EACCES;
979926
}
980-
return mark_reg_read(env, vstate, vstate->parent, regno);
927+
/* We don't need to worry about FP liveness because it's read-only */
928+
if (regno != BPF_REG_FP)
929+
return mark_reg_read(env, &regs[regno],
930+
regs[regno].parent);
981931
} else {
982932
/* check whether register used as dest operand can be written to */
983933
if (regno == BPF_REG_FP) {
@@ -1088,8 +1038,8 @@ static int check_stack_write(struct bpf_verifier_env *env,
10881038
} else {
10891039
u8 type = STACK_MISC;
10901040

1091-
/* regular write of data into stack */
1092-
state->stack[spi].spilled_ptr = (struct bpf_reg_state) {};
1041+
/* regular write of data into stack destroys any spilled ptr */
1042+
state->stack[spi].spilled_ptr.type = NOT_INIT;
10931043

10941044
/* only mark the slot as written if all 8 bytes were written
10951045
* otherwise read propagation may incorrectly stop too soon
@@ -1114,61 +1064,6 @@ static int check_stack_write(struct bpf_verifier_env *env,
11141064
return 0;
11151065
}
11161066

1117-
/* registers of every function are unique and mark_reg_read() propagates
1118-
* the liveness in the following cases:
1119-
* - from callee into caller for R1 - R5 that were used as arguments
1120-
* - from caller into callee for R0 that used as result of the call
1121-
* - from caller to the same caller skipping states of the callee for R6 - R9,
1122-
* since R6 - R9 are callee saved by implicit function prologue and
1123-
* caller's R6 != callee's R6, so when we propagate liveness up to
1124-
* parent states we need to skip callee states for R6 - R9.
1125-
*
1126-
* stack slot marking is different, since stacks of caller and callee are
1127-
* accessible in both (since caller can pass a pointer to caller's stack to
1128-
* callee which can pass it to another function), hence mark_stack_slot_read()
1129-
* has to propagate the stack liveness to all parent states at given frame number.
1130-
* Consider code:
1131-
* f1() {
1132-
* ptr = fp - 8;
1133-
* *ptr = ctx;
1134-
* call f2 {
1135-
* .. = *ptr;
1136-
* }
1137-
* .. = *ptr;
1138-
* }
1139-
* First *ptr is reading from f1's stack and mark_stack_slot_read() has
1140-
* to mark liveness at the f1's frame and not f2's frame.
1141-
* Second *ptr is also reading from f1's stack and mark_stack_slot_read() has
1142-
* to propagate liveness to f2 states at f1's frame level and further into
1143-
* f1 states at f1's frame level until write into that stack slot
1144-
*/
1145-
static void mark_stack_slot_read(struct bpf_verifier_env *env,
1146-
const struct bpf_verifier_state *state,
1147-
struct bpf_verifier_state *parent,
1148-
int slot, int frameno)
1149-
{
1150-
bool writes = parent == state->parent; /* Observe write marks */
1151-
1152-
while (parent) {
1153-
if (parent->frame[frameno]->allocated_stack <= slot * BPF_REG_SIZE)
1154-
/* since LIVE_WRITTEN mark is only done for full 8-byte
1155-
* write the read marks are conservative and parent
1156-
* state may not even have the stack allocated. In such case
1157-
* end the propagation, since the loop reached beginning
1158-
* of the function
1159-
*/
1160-
break;
1161-
/* if read wasn't screened by an earlier write ... */
1162-
if (writes && state->frame[frameno]->stack[slot].spilled_ptr.live & REG_LIVE_WRITTEN)
1163-
break;
1164-
/* ... then we depend on parent's value */
1165-
parent->frame[frameno]->stack[slot].spilled_ptr.live |= REG_LIVE_READ;
1166-
state = parent;
1167-
parent = state->parent;
1168-
writes = true;
1169-
}
1170-
}
1171-
11721067
static int check_stack_read(struct bpf_verifier_env *env,
11731068
struct bpf_func_state *reg_state /* func where register points to */,
11741069
int off, int size, int value_regno)
@@ -1206,8 +1101,8 @@ static int check_stack_read(struct bpf_verifier_env *env,
12061101
*/
12071102
state->regs[value_regno].live |= REG_LIVE_WRITTEN;
12081103
}
1209-
mark_stack_slot_read(env, vstate, vstate->parent, spi,
1210-
reg_state->frameno);
1104+
mark_reg_read(env, &reg_state->stack[spi].spilled_ptr,
1105+
reg_state->stack[spi].spilled_ptr.parent);
12111106
return 0;
12121107
} else {
12131108
int zeros = 0;
@@ -1223,8 +1118,8 @@ static int check_stack_read(struct bpf_verifier_env *env,
12231118
off, i, size);
12241119
return -EACCES;
12251120
}
1226-
mark_stack_slot_read(env, vstate, vstate->parent, spi,
1227-
reg_state->frameno);
1121+
mark_reg_read(env, &reg_state->stack[spi].spilled_ptr,
1122+
reg_state->stack[spi].spilled_ptr.parent);
12281123
if (value_regno >= 0) {
12291124
if (zeros == size) {
12301125
/* any size read into register is zero extended,
@@ -1928,8 +1823,8 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno,
19281823
/* reading any byte out of 8-byte 'spill_slot' will cause
19291824
* the whole slot to be marked as 'read'
19301825
*/
1931-
mark_stack_slot_read(env, env->cur_state, env->cur_state->parent,
1932-
spi, state->frameno);
1826+
mark_reg_read(env, &state->stack[spi].spilled_ptr,
1827+
state->stack[spi].spilled_ptr.parent);
19331828
}
19341829
return update_stack_depth(env, state, off);
19351830
}
@@ -2386,11 +2281,13 @@ static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
23862281
state->curframe + 1 /* frameno within this callchain */,
23872282
subprog /* subprog number within this prog */);
23882283

2389-
/* copy r1 - r5 args that callee can access */
2284+
/* copy r1 - r5 args that callee can access. The copy includes parent
2285+
* pointers, which connects us up to the liveness chain
2286+
*/
23902287
for (i = BPF_REG_1; i <= BPF_REG_5; i++)
23912288
callee->regs[i] = caller->regs[i];
23922289

2393-
/* after the call regsiters r0 - r5 were scratched */
2290+
/* after the call registers r0 - r5 were scratched */
23942291
for (i = 0; i < CALLER_SAVED_REGS; i++) {
23952292
mark_reg_not_init(env, caller->regs, caller_saved[i]);
23962293
check_reg_arg(env, caller_saved[i], DST_OP_NO_MARK);
@@ -4809,7 +4706,7 @@ static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur,
48094706
/* explored state didn't use this */
48104707
return true;
48114708

4812-
equal = memcmp(rold, rcur, offsetof(struct bpf_reg_state, frameno)) == 0;
4709+
equal = memcmp(rold, rcur, offsetof(struct bpf_reg_state, parent)) == 0;
48134710

48144711
if (rold->type == PTR_TO_STACK)
48154712
/* two stack pointers are equal only if they're pointing to
@@ -5048,7 +4945,7 @@ static bool states_equal(struct bpf_verifier_env *env,
50484945
* equivalent state (jump target or such) we didn't arrive by the straight-line
50494946
* code, so read marks in the state must propagate to the parent regardless
50504947
* of the state's write marks. That's what 'parent == state->parent' comparison
5051-
* in mark_reg_read() and mark_stack_slot_read() is for.
4948+
* in mark_reg_read() is for.
50524949
*/
50534950
static int propagate_liveness(struct bpf_verifier_env *env,
50544951
const struct bpf_verifier_state *vstate,
@@ -5069,7 +4966,8 @@ static int propagate_liveness(struct bpf_verifier_env *env,
50694966
if (vparent->frame[vparent->curframe]->regs[i].live & REG_LIVE_READ)
50704967
continue;
50714968
if (vstate->frame[vstate->curframe]->regs[i].live & REG_LIVE_READ) {
5072-
err = mark_reg_read(env, vstate, vparent, i);
4969+
err = mark_reg_read(env, &vstate->frame[vstate->curframe]->regs[i],
4970+
&vparent->frame[vstate->curframe]->regs[i]);
50734971
if (err)
50744972
return err;
50754973
}
@@ -5084,7 +4982,8 @@ static int propagate_liveness(struct bpf_verifier_env *env,
50844982
if (parent->stack[i].spilled_ptr.live & REG_LIVE_READ)
50854983
continue;
50864984
if (state->stack[i].spilled_ptr.live & REG_LIVE_READ)
5087-
mark_stack_slot_read(env, vstate, vparent, i, frame);
4985+
mark_reg_read(env, &state->stack[i].spilled_ptr,
4986+
&parent->stack[i].spilled_ptr);
50884987
}
50894988
}
50904989
return err;
@@ -5094,7 +4993,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
50944993
{
50954994
struct bpf_verifier_state_list *new_sl;
50964995
struct bpf_verifier_state_list *sl;
5097-
struct bpf_verifier_state *cur = env->cur_state;
4996+
struct bpf_verifier_state *cur = env->cur_state, *new;
50984997
int i, j, err, states_cnt = 0;
50994998

51004999
sl = env->explored_states[insn_idx];
@@ -5140,16 +5039,18 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
51405039
return -ENOMEM;
51415040

51425041
/* add new state to the head of linked list */
5143-
err = copy_verifier_state(&new_sl->state, cur);
5042+
new = &new_sl->state;
5043+
err = copy_verifier_state(new, cur);
51445044
if (err) {
5145-
free_verifier_state(&new_sl->state, false);
5045+
free_verifier_state(new, false);
51465046
kfree(new_sl);
51475047
return err;
51485048
}
51495049
new_sl->next = env->explored_states[insn_idx];
51505050
env->explored_states[insn_idx] = new_sl;
51515051
/* connect new state to parentage chain */
5152-
cur->parent = &new_sl->state;
5052+
for (i = 0; i < BPF_REG_FP; i++)
5053+
cur_regs(env)[i].parent = &new->frame[new->curframe]->regs[i];
51535054
/* clear write marks in current state: the writes we did are not writes
51545055
* our child did, so they don't screen off its reads from us.
51555056
* (There are no read marks in current state, because reads always mark
@@ -5162,9 +5063,13 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
51625063
/* all stack frames are accessible from callee, clear them all */
51635064
for (j = 0; j <= cur->curframe; j++) {
51645065
struct bpf_func_state *frame = cur->frame[j];
5066+
struct bpf_func_state *newframe = new->frame[j];
51655067

5166-
for (i = 0; i < frame->allocated_stack / BPF_REG_SIZE; i++)
5068+
for (i = 0; i < frame->allocated_stack / BPF_REG_SIZE; i++) {
51675069
frame->stack[i].spilled_ptr.live = REG_LIVE_NONE;
5070+
frame->stack[i].spilled_ptr.parent =
5071+
&newframe->stack[i].spilled_ptr;
5072+
}
51685073
}
51695074
return 0;
51705075
}

0 commit comments

Comments
 (0)