bpf: attribute __arg_untrusted for global function parameters
Add support for PTR_TO_BTF_ID | PTR_UNTRUSTED global function parameters. Anything is allowed to pass to such parameters, as these are read-only and probe read instructions would protect against invalid memory access. Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com> Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20250704230354.1323244-5-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>pull/1309/head
parent
f1f5d6f25d
commit
182f7df704
|
|
@ -7649,8 +7649,9 @@ enum btf_arg_tag {
|
|||
ARG_TAG_CTX = BIT_ULL(0),
|
||||
ARG_TAG_NONNULL = BIT_ULL(1),
|
||||
ARG_TAG_TRUSTED = BIT_ULL(2),
|
||||
ARG_TAG_NULLABLE = BIT_ULL(3),
|
||||
ARG_TAG_ARENA = BIT_ULL(4),
|
||||
ARG_TAG_UNTRUSTED = BIT_ULL(3),
|
||||
ARG_TAG_NULLABLE = BIT_ULL(4),
|
||||
ARG_TAG_ARENA = BIT_ULL(5),
|
||||
};
|
||||
|
||||
/* Process BTF of a function to produce high-level expectation of function
|
||||
|
|
@ -7758,6 +7759,8 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
|
|||
tags |= ARG_TAG_CTX;
|
||||
} else if (strcmp(tag, "trusted") == 0) {
|
||||
tags |= ARG_TAG_TRUSTED;
|
||||
} else if (strcmp(tag, "untrusted") == 0) {
|
||||
tags |= ARG_TAG_UNTRUSTED;
|
||||
} else if (strcmp(tag, "nonnull") == 0) {
|
||||
tags |= ARG_TAG_NONNULL;
|
||||
} else if (strcmp(tag, "nullable") == 0) {
|
||||
|
|
@ -7818,6 +7821,31 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
|
|||
sub->args[i].btf_id = kern_type_id;
|
||||
continue;
|
||||
}
|
||||
if (tags & ARG_TAG_UNTRUSTED) {
|
||||
struct btf *vmlinux_btf;
|
||||
int kern_type_id;
|
||||
|
||||
if (tags & ~ARG_TAG_UNTRUSTED) {
|
||||
bpf_log(log, "arg#%d untrusted cannot be combined with any other tags\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kern_type_id = btf_get_ptr_to_btf_id(log, i, btf, t);
|
||||
if (kern_type_id < 0)
|
||||
return kern_type_id;
|
||||
|
||||
vmlinux_btf = bpf_get_btf_vmlinux();
|
||||
ref_t = btf_type_by_id(vmlinux_btf, kern_type_id);
|
||||
if (!btf_type_is_struct(ref_t)) {
|
||||
tname = __btf_name_by_offset(vmlinux_btf, t->name_off);
|
||||
bpf_log(log, "arg#%d has type %s '%s', but only struct types are allowed\n",
|
||||
i, btf_type_str(ref_t), tname);
|
||||
return -EINVAL;
|
||||
}
|
||||
sub->args[i].arg_type = ARG_PTR_TO_BTF_ID | PTR_UNTRUSTED;
|
||||
sub->args[i].btf_id = kern_type_id;
|
||||
continue;
|
||||
}
|
||||
if (tags & ARG_TAG_ARENA) {
|
||||
if (tags & ~ARG_TAG_ARENA) {
|
||||
bpf_log(log, "arg#%d arena cannot be combined with any other tags\n", i);
|
||||
|
|
|
|||
|
|
@ -10437,6 +10437,12 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env, int subprog,
|
|||
bpf_log(log, "R%d is not a scalar\n", regno);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (arg->arg_type & PTR_UNTRUSTED) {
|
||||
/*
|
||||
* Anything is allowed for untrusted arguments, as these are
|
||||
* read-only and probe read instructions would protect against
|
||||
* invalid memory access.
|
||||
*/
|
||||
} else if (arg->arg_type == ARG_PTR_TO_CTX) {
|
||||
ret = check_func_arg_reg_off(env, reg, regno, ARG_DONTCARE);
|
||||
if (ret < 0)
|
||||
|
|
|
|||
Loading…
Reference in New Issue