@@ -9249,101 +9249,54 @@ static int setup_func_entry(struct bpf_verifier_env *env, int subprog, int calls
9249
9249
return err;
9250
9250
}
9251
9251
9252
- static int btf_check_func_arg_match(struct bpf_verifier_env *env,
9253
- const struct btf *btf, u32 func_id,
9254
- struct bpf_reg_state *regs,
9255
- bool ptr_to_mem_ok)
9252
+ static int btf_check_func_arg_match(struct bpf_verifier_env *env, int subprog,
9253
+ const struct btf *btf,
9254
+ struct bpf_reg_state *regs)
9256
9255
{
9257
- enum bpf_prog_type prog_type = resolve_prog_type (env->prog );
9256
+ struct bpf_subprog_info *sub = subprog_info (env, subprog );
9258
9257
struct bpf_verifier_log *log = &env->log;
9259
- const char *func_name, *ref_tname;
9260
- const struct btf_type *t, *ref_t;
9261
- const struct btf_param *args;
9262
- u32 i, nargs, ref_id;
9258
+ u32 i;
9263
9259
int ret;
9264
9260
9265
- t = btf_type_by_id(btf, func_id);
9266
- if (!t || !btf_type_is_func(t)) {
9267
- /* These checks were already done by the verifier while loading
9268
- * struct bpf_func_info or in add_kfunc_call().
9269
- */
9270
- bpf_log(log, "BTF of func_id %u doesn't point to KIND_FUNC\n",
9271
- func_id);
9272
- return -EFAULT;
9273
- }
9274
- func_name = btf_name_by_offset(btf, t->name_off);
9275
-
9276
- t = btf_type_by_id(btf, t->type);
9277
- if (!t || !btf_type_is_func_proto(t)) {
9278
- bpf_log(log, "Invalid BTF of func %s\n", func_name);
9279
- return -EFAULT;
9280
- }
9281
- args = (const struct btf_param *)(t + 1);
9282
- nargs = btf_type_vlen(t);
9283
- if (nargs > MAX_BPF_FUNC_REG_ARGS) {
9284
- bpf_log(log, "Function %s has %d > %d args\n", func_name, nargs,
9285
- MAX_BPF_FUNC_REG_ARGS);
9286
- return -EINVAL;
9287
- }
9261
+ ret = btf_prepare_func_args(env, subprog);
9262
+ if (ret)
9263
+ return ret;
9288
9264
9289
9265
/* check that BTF function arguments match actual types that the
9290
9266
* verifier sees.
9291
9267
*/
9292
- for (i = 0; i < nargs; i++) {
9293
- enum bpf_arg_type arg_type = ARG_DONTCARE;
9268
+ for (i = 0; i < sub->arg_cnt; i++) {
9294
9269
u32 regno = i + 1;
9295
9270
struct bpf_reg_state *reg = ®s[regno];
9271
+ struct bpf_subprog_arg_info *arg = &sub->args[i];
9296
9272
9297
- t = btf_type_skip_modifiers(btf, args[i].type, NULL);
9298
- if (btf_type_is_scalar(t)) {
9299
- if (reg->type == SCALAR_VALUE)
9300
- continue;
9301
- bpf_log(log, "R%d is not a scalar\n", regno);
9302
- return -EINVAL;
9303
- }
9304
-
9305
- if (!btf_type_is_ptr(t)) {
9306
- bpf_log(log, "Unrecognized arg#%d type %s\n",
9307
- i, btf_type_str(t));
9308
- return -EINVAL;
9309
- }
9310
-
9311
- ref_t = btf_type_skip_modifiers(btf, t->type, &ref_id);
9312
- ref_tname = btf_name_by_offset(btf, ref_t->name_off);
9313
-
9314
- ret = check_func_arg_reg_off(env, reg, regno, arg_type);
9315
- if (ret < 0)
9316
- return ret;
9317
-
9318
- if (btf_get_prog_ctx_type(log, btf, t, prog_type, i)) {
9273
+ if (arg->arg_type == ARG_ANYTHING) {
9274
+ if (reg->type != SCALAR_VALUE) {
9275
+ bpf_log(log, "R%d is not a scalar\n", regno);
9276
+ return -EINVAL;
9277
+ }
9278
+ } else if (arg->arg_type == ARG_PTR_TO_CTX) {
9279
+ ret = check_func_arg_reg_off(env, reg, regno, ARG_DONTCARE);
9280
+ if (ret < 0)
9281
+ return ret;
9319
9282
/* If function expects ctx type in BTF check that caller
9320
9283
* is passing PTR_TO_CTX.
9321
9284
*/
9322
9285
if (reg->type != PTR_TO_CTX) {
9323
- bpf_log(log,
9324
- "arg#%d expected pointer to ctx, but got %s\n",
9325
- i, btf_type_str(t));
9326
- return -EINVAL;
9327
- }
9328
- } else if (ptr_to_mem_ok) {
9329
- const struct btf_type *resolve_ret;
9330
- u32 type_size;
9331
-
9332
- resolve_ret = btf_resolve_size(btf, ref_t, &type_size);
9333
- if (IS_ERR(resolve_ret)) {
9334
- bpf_log(log,
9335
- "arg#%d reference type('%s %s') size cannot be determined: %ld\n",
9336
- i, btf_type_str(ref_t), ref_tname,
9337
- PTR_ERR(resolve_ret));
9286
+ bpf_log(log, "arg#%d expects pointer to ctx\n", i);
9338
9287
return -EINVAL;
9339
9288
}
9289
+ } else if (base_type(arg->arg_type) == ARG_PTR_TO_MEM) {
9290
+ ret = check_func_arg_reg_off(env, reg, regno, ARG_DONTCARE);
9291
+ if (ret < 0)
9292
+ return ret;
9340
9293
9341
- if (check_mem_reg(env, reg, regno, type_size ))
9294
+ if (check_mem_reg(env, reg, regno, arg->mem_size ))
9342
9295
return -EINVAL;
9343
9296
} else {
9344
- bpf_log(log, "reg type unsupported for arg#%d function %s#% d\n", i ,
9345
- func_name, func_id );
9346
- return -EINVAL ;
9297
+ bpf_log(log, "verifier bug: unrecognized arg#%d type % d\n",
9298
+ i, arg->arg_type );
9299
+ return -EFAULT ;
9347
9300
}
9348
9301
}
9349
9302
@@ -9358,11 +9311,10 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
9358
9311
* Only PTR_TO_CTX and SCALAR_VALUE states are recognized.
9359
9312
*/
9360
9313
static int btf_check_subprog_call(struct bpf_verifier_env *env, int subprog,
9361
- struct bpf_reg_state *regs)
9314
+ struct bpf_reg_state *regs)
9362
9315
{
9363
9316
struct bpf_prog *prog = env->prog;
9364
9317
struct btf *btf = prog->aux->btf;
9365
- bool is_global;
9366
9318
u32 btf_id;
9367
9319
int err;
9368
9320
@@ -9376,9 +9328,7 @@ static int btf_check_subprog_call(struct bpf_verifier_env *env, int subprog,
9376
9328
if (prog->aux->func_info_aux[subprog].unreliable)
9377
9329
return -EINVAL;
9378
9330
9379
- is_global = prog->aux->func_info_aux[subprog].linkage == BTF_FUNC_GLOBAL;
9380
- err = btf_check_func_arg_match(env, btf, btf_id, regs, is_global);
9381
-
9331
+ err = btf_check_func_arg_match(env, subprog, btf, regs);
9382
9332
/* Compiler optimizations can remove arguments from static functions
9383
9333
* or mismatched type can be passed into a global function.
9384
9334
* In such cases mark the function as unreliable from BTF point of view.
0 commit comments