Skip to content

Commit c4aa454

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
bpf: support for void/primitive __arg_untrusted global func params
Allow specifying __arg_untrusted for void */char */int */long * parameters. Treat such parameters as PTR_TO_MEM|MEM_RDONLY|PTR_UNTRUSTED of size zero. Intended usage is as follows: int memcmp(char *a __arg_untrusted, char *b __arg_untrusted, size_t n) { bpf_for(i, 0, n) { if (a[i] - b[i]) // load at any offset is allowed return a[i] - b[i]; } return 0; } Allocate register id for ARG_PTR_TO_MEM parameters only when PTR_MAYBE_NULL is set. Register id for PTR_TO_MEM is used only to propagate non-null status after conditionals. Suggested-by: Alexei Starovoitov <[email protected]> Acked-by: Kumar Kartikeya Dwivedi <[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 54ac2c9 commit c4aa454

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

include/linux/btf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ u32 btf_nr_types(const struct btf *btf);
223223
struct btf *btf_base_btf(const struct btf *btf);
224224
bool btf_type_is_i32(const struct btf_type *t);
225225
bool btf_type_is_i64(const struct btf_type *t);
226+
bool btf_type_is_primitive(const struct btf_type *t);
226227
bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s,
227228
const struct btf_member *m,
228229
u32 expected_offset, u32 expected_size);

kernel/bpf/btf.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,12 @@ bool btf_type_is_i64(const struct btf_type *t)
891891
return btf_type_is_int(t) && __btf_type_int_is_regular(t, 8);
892892
}
893893

894+
bool btf_type_is_primitive(const struct btf_type *t)
895+
{
896+
return (btf_type_is_int(t) && btf_type_int_is_regular(t)) ||
897+
btf_is_any_enum(t);
898+
}
899+
894900
/*
895901
* Check that given struct member is a regular int with expected
896902
* offset and size.
@@ -7830,6 +7836,13 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
78307836
return -EINVAL;
78317837
}
78327838

7839+
ref_t = btf_type_skip_modifiers(btf, t->type, NULL);
7840+
if (btf_type_is_void(ref_t) || btf_type_is_primitive(ref_t)) {
7841+
sub->args[i].arg_type = ARG_PTR_TO_MEM | MEM_RDONLY | PTR_UNTRUSTED;
7842+
sub->args[i].mem_size = 0;
7843+
continue;
7844+
}
7845+
78337846
kern_type_id = btf_get_ptr_to_btf_id(log, i, btf, t);
78347847
if (kern_type_id < 0)
78357848
return kern_type_id;
@@ -7838,7 +7851,7 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
78387851
ref_t = btf_type_by_id(vmlinux_btf, kern_type_id);
78397852
if (!btf_type_is_struct(ref_t)) {
78407853
tname = __btf_name_by_offset(vmlinux_btf, t->name_off);
7841-
bpf_log(log, "arg#%d has type %s '%s', but only struct types are allowed\n",
7854+
bpf_log(log, "arg#%d has type %s '%s', but only struct or primitive types are allowed\n",
78427855
i, btf_type_str(ref_t), tname);
78437856
return -EINVAL;
78447857
}

kernel/bpf/verifier.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23152,11 +23152,12 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
2315223152
__mark_dynptr_reg(reg, BPF_DYNPTR_TYPE_LOCAL, true, ++env->id_gen);
2315323153
} else if (base_type(arg->arg_type) == ARG_PTR_TO_MEM) {
2315423154
reg->type = PTR_TO_MEM;
23155-
if (arg->arg_type & PTR_MAYBE_NULL)
23156-
reg->type |= PTR_MAYBE_NULL;
23155+
reg->type |= arg->arg_type &
23156+
(PTR_MAYBE_NULL | PTR_UNTRUSTED | MEM_RDONLY);
2315723157
mark_reg_known_zero(env, regs, i);
2315823158
reg->mem_size = arg->mem_size;
23159-
reg->id = ++env->id_gen;
23159+
if (arg->arg_type & PTR_MAYBE_NULL)
23160+
reg->id = ++env->id_gen;
2316023161
} else if (base_type(arg->arg_type) == ARG_PTR_TO_BTF_ID) {
2316123162
reg->type = PTR_TO_BTF_ID;
2316223163
if (arg->arg_type & PTR_MAYBE_NULL)

0 commit comments

Comments
 (0)