Skip to content

Commit 980ca8c

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
bpf: check bpf_dummy_struct_ops program params for test runs
When doing BPF_PROG_TEST_RUN for bpf_dummy_struct_ops programs, reject execution when NULL is passed for non-nullable params. For programs with non-nullable params verifier assumes that such params are never NULL and thus might optimize out NULL checks. Suggested-by: Kui-Feng Lee <[email protected]> Signed-off-by: Eduard Zingerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent f612210 commit 980ca8c

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

net/bpf/bpf_dummy_struct_ops.c

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,51 @@ static int dummy_ops_call_op(void *image, struct bpf_dummy_ops_test_args *args)
7979
args->args[3], args->args[4]);
8080
}
8181

82+
static const struct bpf_ctx_arg_aux *find_ctx_arg_info(struct bpf_prog_aux *aux, int offset)
83+
{
84+
int i;
85+
86+
for (i = 0; i < aux->ctx_arg_info_size; i++)
87+
if (aux->ctx_arg_info[i].offset == offset)
88+
return &aux->ctx_arg_info[i];
89+
90+
return NULL;
91+
}
92+
93+
/* There is only one check at the moment:
94+
* - zero should not be passed for pointer parameters not marked as nullable.
95+
*/
96+
static int check_test_run_args(struct bpf_prog *prog, struct bpf_dummy_ops_test_args *args)
97+
{
98+
const struct btf_type *func_proto = prog->aux->attach_func_proto;
99+
100+
for (u32 arg_no = 0; arg_no < btf_type_vlen(func_proto) ; ++arg_no) {
101+
const struct btf_param *param = &btf_params(func_proto)[arg_no];
102+
const struct bpf_ctx_arg_aux *info;
103+
const struct btf_type *t;
104+
int offset;
105+
106+
if (args->args[arg_no] != 0)
107+
continue;
108+
109+
/* Program is validated already, so there is no need
110+
* to check if t is NULL.
111+
*/
112+
t = btf_type_skip_modifiers(bpf_dummy_ops_btf, param->type, NULL);
113+
if (!btf_type_is_ptr(t))
114+
continue;
115+
116+
offset = btf_ctx_arg_offset(bpf_dummy_ops_btf, func_proto, arg_no);
117+
info = find_ctx_arg_info(prog->aux, offset);
118+
if (info && (info->reg_type & PTR_MAYBE_NULL))
119+
continue;
120+
121+
return -EINVAL;
122+
}
123+
124+
return 0;
125+
}
126+
82127
extern const struct bpf_link_ops bpf_struct_ops_link_lops;
83128

84129
int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
@@ -87,7 +132,7 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
87132
const struct bpf_struct_ops *st_ops = &bpf_bpf_dummy_ops;
88133
const struct btf_type *func_proto;
89134
struct bpf_dummy_ops_test_args *args;
90-
struct bpf_tramp_links *tlinks;
135+
struct bpf_tramp_links *tlinks = NULL;
91136
struct bpf_tramp_link *link = NULL;
92137
void *image = NULL;
93138
unsigned int op_idx;
@@ -109,6 +154,10 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
109154
if (IS_ERR(args))
110155
return PTR_ERR(args);
111156

157+
err = check_test_run_args(prog, args);
158+
if (err)
159+
goto out;
160+
112161
tlinks = kcalloc(BPF_TRAMP_MAX, sizeof(*tlinks), GFP_KERNEL);
113162
if (!tlinks) {
114163
err = -ENOMEM;

0 commit comments

Comments
 (0)