@@ -1259,9 +1259,16 @@ static int resize_reference_state(struct bpf_func_state *state, size_t n)
1259
1259
return 0;
1260
1260
}
1261
1261
1262
- static int grow_stack_state(struct bpf_func_state *state, int size)
1262
+ /* Possibly update state->allocated_stack to be at least size bytes. Also
1263
+ * possibly update the function's high-water mark in its bpf_subprog_info.
1264
+ */
1265
+ static int grow_stack_state(struct bpf_verifier_env *env, struct bpf_func_state *state, int size)
1263
1266
{
1264
- size_t old_n = state->allocated_stack / BPF_REG_SIZE, n = size / BPF_REG_SIZE;
1267
+ size_t old_n = state->allocated_stack / BPF_REG_SIZE, n;
1268
+
1269
+ /* The stack size is always a multiple of BPF_REG_SIZE. */
1270
+ size = round_up(size, BPF_REG_SIZE);
1271
+ n = size / BPF_REG_SIZE;
1265
1272
1266
1273
if (old_n >= n)
1267
1274
return 0;
@@ -1271,6 +1278,11 @@ static int grow_stack_state(struct bpf_func_state *state, int size)
1271
1278
return -ENOMEM;
1272
1279
1273
1280
state->allocated_stack = size;
1281
+
1282
+ /* update known max for given subprogram */
1283
+ if (env->subprog_info[state->subprogno].stack_depth < size)
1284
+ env->subprog_info[state->subprogno].stack_depth = size;
1285
+
1274
1286
return 0;
1275
1287
}
1276
1288
@@ -4440,9 +4452,6 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
4440
4452
struct bpf_reg_state *reg = NULL;
4441
4453
int insn_flags = insn_stack_access_flags(state->frameno, spi);
4442
4454
4443
- err = grow_stack_state(state, round_up(slot + 1, BPF_REG_SIZE));
4444
- if (err)
4445
- return err;
4446
4455
/* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0,
4447
4456
* so it's aligned access and [off, off + size) are within stack limits
4448
4457
*/
@@ -4595,10 +4604,6 @@ static int check_stack_write_var_off(struct bpf_verifier_env *env,
4595
4604
(!value_reg && is_bpf_st_mem(insn) && insn->imm == 0))
4596
4605
writing_zero = true;
4597
4606
4598
- err = grow_stack_state(state, round_up(-min_off, BPF_REG_SIZE));
4599
- if (err)
4600
- return err;
4601
-
4602
4607
for (i = min_off; i < max_off; i++) {
4603
4608
int spi;
4604
4609
@@ -5774,20 +5779,6 @@ static int check_ptr_alignment(struct bpf_verifier_env *env,
5774
5779
strict);
5775
5780
}
5776
5781
5777
- static int update_stack_depth(struct bpf_verifier_env *env,
5778
- const struct bpf_func_state *func,
5779
- int off)
5780
- {
5781
- u16 stack = env->subprog_info[func->subprogno].stack_depth;
5782
-
5783
- if (stack >= -off)
5784
- return 0;
5785
-
5786
- /* update known max for given subprogram */
5787
- env->subprog_info[func->subprogno].stack_depth = -off;
5788
- return 0;
5789
- }
5790
-
5791
5782
/* starting from main bpf function walk all instructions of the function
5792
5783
* and recursively walk all callees that given function can call.
5793
5784
* Ignore jump and exit insns.
@@ -6577,13 +6568,14 @@ static int check_ptr_to_map_access(struct bpf_verifier_env *env,
6577
6568
* The minimum valid offset is -MAX_BPF_STACK for writes, and
6578
6569
* -state->allocated_stack for reads.
6579
6570
*/
6580
- static int check_stack_slot_within_bounds(s64 off,
6581
- struct bpf_func_state *state,
6582
- enum bpf_access_type t)
6571
+ static int check_stack_slot_within_bounds(struct bpf_verifier_env *env,
6572
+ s64 off,
6573
+ struct bpf_func_state *state,
6574
+ enum bpf_access_type t)
6583
6575
{
6584
6576
int min_valid_off;
6585
6577
6586
- if (t == BPF_WRITE)
6578
+ if (t == BPF_WRITE || env->allow_uninit_stack )
6587
6579
min_valid_off = -MAX_BPF_STACK;
6588
6580
else
6589
6581
min_valid_off = -state->allocated_stack;
@@ -6632,7 +6624,7 @@ static int check_stack_access_within_bounds(
6632
6624
max_off = reg->smax_value + off + access_size;
6633
6625
}
6634
6626
6635
- err = check_stack_slot_within_bounds(min_off, state, type);
6627
+ err = check_stack_slot_within_bounds(env, min_off, state, type);
6636
6628
if (!err && max_off > 0)
6637
6629
err = -EINVAL; /* out of stack access into non-negative offsets */
6638
6630
@@ -6647,8 +6639,13 @@ static int check_stack_access_within_bounds(
6647
6639
verbose(env, "invalid variable-offset%s stack R%d var_off=%s off=%d size=%d\n",
6648
6640
err_extra, regno, tn_buf, off, access_size);
6649
6641
}
6642
+ return err;
6650
6643
}
6651
- return err;
6644
+
6645
+ /* Note that there is no stack access with offset zero, so the needed stack
6646
+ * size is -min_off, not -min_off+1.
6647
+ */
6648
+ return grow_stack_state(env, state, -min_off /* size */);
6652
6649
}
6653
6650
6654
6651
/* check whether memory at (regno + off) is accessible for t = (read | write)
@@ -6663,7 +6660,6 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
6663
6660
{
6664
6661
struct bpf_reg_state *regs = cur_regs(env);
6665
6662
struct bpf_reg_state *reg = regs + regno;
6666
- struct bpf_func_state *state;
6667
6663
int size, err = 0;
6668
6664
6669
6665
size = bpf_size_to_bytes(bpf_size);
@@ -6806,11 +6802,6 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
6806
6802
if (err)
6807
6803
return err;
6808
6804
6809
- state = func(env, reg);
6810
- err = update_stack_depth(env, state, off);
6811
- if (err)
6812
- return err;
6813
-
6814
6805
if (t == BPF_READ)
6815
6806
err = check_stack_read(env, regno, off, size,
6816
6807
value_regno);
@@ -7004,7 +6995,8 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
7004
6995
7005
6996
/* When register 'regno' is used to read the stack (either directly or through
7006
6997
* a helper function) make sure that it's within stack boundary and, depending
7007
- * on the access type, that all elements of the stack are initialized.
6998
+ * on the access type and privileges, that all elements of the stack are
6999
+ * initialized.
7008
7000
*
7009
7001
* 'off' includes 'regno->off', but not its dynamic part (if any).
7010
7002
*
@@ -7112,8 +7104,11 @@ static int check_stack_range_initialized(
7112
7104
7113
7105
slot = -i - 1;
7114
7106
spi = slot / BPF_REG_SIZE;
7115
- if (state->allocated_stack <= slot)
7116
- goto err;
7107
+ if (state->allocated_stack <= slot) {
7108
+ verbose(env, "verifier bug: allocated_stack too small");
7109
+ return -EFAULT;
7110
+ }
7111
+
7117
7112
stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE];
7118
7113
if (*stype == STACK_MISC)
7119
7114
goto mark;
@@ -7137,7 +7132,6 @@ static int check_stack_range_initialized(
7137
7132
goto mark;
7138
7133
}
7139
7134
7140
- err:
7141
7135
if (tnum_is_const(reg->var_off)) {
7142
7136
verbose(env, "invalid%s read from stack R%d off %d+%d size %d\n",
7143
7137
err_extra, regno, min_off, i - min_off, access_size);
@@ -7162,7 +7156,7 @@ static int check_stack_range_initialized(
7162
7156
* helper may write to the entire memory range.
7163
7157
*/
7164
7158
}
7165
- return update_stack_depth(env, state, min_off) ;
7159
+ return 0 ;
7166
7160
}
7167
7161
7168
7162
static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
0 commit comments