Skip to content

Commit 182f7df

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
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 <[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 f1f5d6f commit 182f7df

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

kernel/bpf/btf.c

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7646,11 +7646,12 @@ static int btf_get_ptr_to_btf_id(struct bpf_verifier_log *log, int arg_idx,
76467646
}
76477647

76487648
enum btf_arg_tag {
7649-
ARG_TAG_CTX = BIT_ULL(0),
7650-
ARG_TAG_NONNULL = BIT_ULL(1),
7651-
ARG_TAG_TRUSTED = BIT_ULL(2),
7652-
ARG_TAG_NULLABLE = BIT_ULL(3),
7653-
ARG_TAG_ARENA = BIT_ULL(4),
7649+
ARG_TAG_CTX = BIT_ULL(0),
7650+
ARG_TAG_NONNULL = BIT_ULL(1),
7651+
ARG_TAG_TRUSTED = BIT_ULL(2),
7652+
ARG_TAG_UNTRUSTED = BIT_ULL(3),
7653+
ARG_TAG_NULLABLE = BIT_ULL(4),
7654+
ARG_TAG_ARENA = BIT_ULL(5),
76547655
};
76557656

76567657
/* 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)
77587759
tags |= ARG_TAG_CTX;
77597760
} else if (strcmp(tag, "trusted") == 0) {
77607761
tags |= ARG_TAG_TRUSTED;
7762+
} else if (strcmp(tag, "untrusted") == 0) {
7763+
tags |= ARG_TAG_UNTRUSTED;
77617764
} else if (strcmp(tag, "nonnull") == 0) {
77627765
tags |= ARG_TAG_NONNULL;
77637766
} else if (strcmp(tag, "nullable") == 0) {
@@ -7818,6 +7821,31 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
78187821
sub->args[i].btf_id = kern_type_id;
78197822
continue;
78207823
}
7824+
if (tags & ARG_TAG_UNTRUSTED) {
7825+
struct btf *vmlinux_btf;
7826+
int kern_type_id;
7827+
7828+
if (tags & ~ARG_TAG_UNTRUSTED) {
7829+
bpf_log(log, "arg#%d untrusted cannot be combined with any other tags\n", i);
7830+
return -EINVAL;
7831+
}
7832+
7833+
kern_type_id = btf_get_ptr_to_btf_id(log, i, btf, t);
7834+
if (kern_type_id < 0)
7835+
return kern_type_id;
7836+
7837+
vmlinux_btf = bpf_get_btf_vmlinux();
7838+
ref_t = btf_type_by_id(vmlinux_btf, kern_type_id);
7839+
if (!btf_type_is_struct(ref_t)) {
7840+
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",
7842+
i, btf_type_str(ref_t), tname);
7843+
return -EINVAL;
7844+
}
7845+
sub->args[i].arg_type = ARG_PTR_TO_BTF_ID | PTR_UNTRUSTED;
7846+
sub->args[i].btf_id = kern_type_id;
7847+
continue;
7848+
}
78217849
if (tags & ARG_TAG_ARENA) {
78227850
if (tags & ~ARG_TAG_ARENA) {
78237851
bpf_log(log, "arg#%d arena cannot be combined with any other tags\n", i);

kernel/bpf/verifier.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10437,6 +10437,12 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env, int subprog,
1043710437
bpf_log(log, "R%d is not a scalar\n", regno);
1043810438
return -EINVAL;
1043910439
}
10440+
} else if (arg->arg_type & PTR_UNTRUSTED) {
10441+
/*
10442+
* Anything is allowed for untrusted arguments, as these are
10443+
* read-only and probe read instructions would protect against
10444+
* invalid memory access.
10445+
*/
1044010446
} else if (arg->arg_type == ARG_PTR_TO_CTX) {
1044110447
ret = check_func_arg_reg_off(env, reg, regno, ARG_DONTCARE);
1044210448
if (ret < 0)

0 commit comments

Comments
 (0)