* [PATCH bpf-next v4 0/2] bpf: Enforce trusted BTF ID argument provenance
@ 2026-10-07 16:25 Yiyang Chen
2026-10-07 16:25 ` [PATCH bpf-next v4 1/2] " Yiyang Chen
2026-10-07 16:25 ` [PATCH bpf-next v4 2/2] selftests/bpf: Cover " Yiyang Chen
0 siblings, 2 replies; 6+ messages in thread
From: Yiyang Chen @ 2026-10-07 16:25 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Ihor Solodrai, Shuah Khan
Cc: bpf, linux-kernel, linux-kselftest, Amery Hung, Brahmajit Das,
Yiyang Chen
A global subprogram parameter tagged __arg_trusted is verified with
PTR_TRUSTED, but its call-site type check also accepts bare PTR_TO_BTF_ID and
MEM_RCU registers. This lets a callee use a pointer with weaker provenance
under the trusted-pointer contract, including passing it to a non-KF_RCU
kfunc.
Encode the trusted-pointer requirement in generated kfunc prototypes and
drive the shared provenance check from the argument contract. A KF_RCU
kfunc additionally permits MEM_RCU, while a global __arg_trusted argument
requires a referenced or trusted pointer. Normalize nullability when the
argument contract permits it.
Add rejection coverage for bare and RCU-protected global-subprogram arguments
and acceptance coverage for a nullable kfunc receiving a trusted nullable
pointer.
A separate scx_cake caller fix has been prepared but is not yet submitted.
The current veristat-scx pin still uses the old caller, which this series
rejects.
Changes in v4:
- Rebase onto bpf-next and use the shared argument checker.
- Reject MEM_RCU for global __arg_trusted arguments.
- Encode trusted and KF_RCU provenance in generated kfunc prototypes.
- Add nullable-kfunc coverage and use a 12-character Fixes SHA.
- Link to v3: https://lore.kernel.org/r/20261006-a3-arg-trusted-v4-v3-0-4619daf30e1c@mails.tsinghua.edu.cn
Changes in v3:
- Preserve RCU-protected arguments accepted by existing sched-ext programs.
- Make the MEM_RCU case a positive regression test.
- Use the preferred multi-line comment style.
- Link to v2: https://lore.kernel.org/r/20261005-a3-arg-trusted-v4-v2-0-319ce2936949@mails.tsinghua.edu.cn
Changes in v2:
- Retarget the fix to btf_check_func_arg_match(), where the subprogram
argument check lives in this tree, instead of check_func_arg().
- Run the check after check_reg_type() and check_func_arg_reg_off() so type
and offset diagnostics keep their wording.
v1: https://lore.kernel.org/bpf/20261005-a3-arg-trusted-v4-v1-0-50ee0268fd39@mails.tsinghua.edu.cn/
---
Yiyang Chen (2):
bpf: Enforce trusted BTF ID argument provenance
selftests/bpf: Cover trusted BTF ID argument provenance
kernel/bpf/verifier.c | 27 ++++++++++++-----
tools/testing/selftests/bpf/progs/iters_testmod.c | 11 +++++++
.../selftests/bpf/progs/verifier_global_ptr_args.c | 35 ++++++++++++++++++++++
.../testing/selftests/bpf/test_kmods/bpf_testmod.c | 11 +++++++
.../selftests/bpf/test_kmods/bpf_testmod_kfunc.h | 2 ++
5 files changed, 79 insertions(+), 7 deletions(-)
base-commit: e1d84a37cba984388988d2f1ddc84561413f0db2
change-id: 20261005-a3-arg-trusted-v4-9d5d9485e5ba
--
Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH bpf-next v4 1/2] bpf: Enforce trusted BTF ID argument provenance
2026-10-07 16:25 [PATCH bpf-next v4 0/2] bpf: Enforce trusted BTF ID argument provenance Yiyang Chen
@ 2026-10-07 16:25 ` Yiyang Chen
2026-10-07 16:43 ` sashiko-bot
2026-10-07 22:30 ` Amery Hung
2026-10-07 16:25 ` [PATCH bpf-next v4 2/2] selftests/bpf: Cover " Yiyang Chen
1 sibling, 2 replies; 6+ messages in thread
From: Yiyang Chen @ 2026-10-07 16:25 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Ihor Solodrai, Shuah Khan
Cc: bpf, linux-kernel, linux-kselftest, Amery Hung, Brahmajit Das,
Yiyang Chen
A global subprogram parameter tagged __arg_trusted is verified with
PTR_TRUSTED, but the common call-site type check accepts bare PTR_TO_BTF_ID
and MEM_RCU registers. The callee can consequently pass a pointer with
weaker provenance to a kfunc that does not accept RCU-protected pointers.
RCU protection only guarantees that the object remains allocated through a
grace period. It does not guarantee that an object's refcount is nonzero,
so an RCU-protected pointer cannot satisfy the trusted-pointer contract.
For example, an RCU-protected bpf_cpumask loaded from a map may have a
zero refcount. Passing it through __arg_trusted lets the callee pass it
to bpf_cpumask_acquire(), whose plain refcount_inc() can retain an object
that will be freed after the grace period.
Make the existing provenance check contract-driven. Mark generated BTF ID
kfunc argument types with PTR_TRUSTED, and add MEM_RCU only for KF_RCU
kfuncs. Normalize PTR_MAYBE_NULL when the argument contract permits it.
Then use the argument flags to require trusted or referenced provenance
and allow MEM_RCU only when the contract says so.
Split is_trusted_reg() so the normalized type is used for type and modifier
checks while reference lookup still uses the original register. Conversion
of scalar-struct BTF ID arguments to fixed-size memory continues to
construct a new ARG_PTR_TO_MEM type without PTR_TRUSTED.
Fixes: e2b3c4ff5d18 ("bpf: add __arg_trusted global func arg tag")
Suggested-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
kernel/bpf/verifier.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 353bde9ae2274..a0ab793f041d8 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5327,15 +5327,17 @@ static u32 *reg2btf_ids[__BPF_REG_TYPE_MAX] = {
[CONST_PTR_TO_MAP] = btf_bpf_map_id,
};
-static bool is_trusted_reg(struct bpf_verifier_env *env, const struct bpf_reg_state *reg)
+static bool is_trusted_reg_type(struct bpf_verifier_env *env,
+ const struct bpf_reg_state *reg,
+ enum bpf_reg_type type)
{
/* A referenced register is always trusted. */
if (reg_is_referenced(env, reg))
return true;
/* Types listed in the reg2btf_ids are always trusted */
- if (reg2btf_ids[base_type(reg->type)] &&
- !bpf_type_has_unsafe_modifiers(reg->type))
+ if (reg2btf_ids[base_type(type)] &&
+ !bpf_type_has_unsafe_modifiers(type))
return true;
/* If a register is not referenced, it is trusted if it has the
@@ -5347,8 +5349,14 @@ static bool is_trusted_reg(struct bpf_verifier_env *env, const struct bpf_reg_st
* Eventually, we should make PTR_TRUSTED the single source of truth
* for whether a register is trusted.
*/
- return type_flag(reg->type) & BPF_REG_TRUSTED_MODIFIERS &&
- !bpf_type_has_unsafe_modifiers(reg->type);
+ return type_flag(type) & BPF_REG_TRUSTED_MODIFIERS &&
+ !bpf_type_has_unsafe_modifiers(type);
+}
+
+static bool is_trusted_reg(struct bpf_verifier_env *env,
+ const struct bpf_reg_state *reg)
+{
+ return is_trusted_reg_type(env, reg, reg->type);
}
static bool is_rcu_reg(const struct bpf_reg_state *reg)
@@ -9578,6 +9586,7 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, u32 slot, u32 p
{
const u32 *arg_btf_id = fn->arg_btf_id[arg];
const struct btf *arg_btf = is_kfunc(meta) ? meta->btf : btf_vmlinux;
+ enum bpf_reg_type reg_type;
if (!meta->btf) {
const struct bpf_reg_types *compatible;
@@ -9605,8 +9614,10 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, u32 slot, u32 p
}
}
- if (is_kfunc(meta) && (!is_trusted_reg(env, reg) ||
- bpf_type_has_unsafe_modifiers(reg->type))) {
+ reg_type = reg->type & ~(arg_type & PTR_MAYBE_NULL);
+ if ((arg_type & PTR_TRUSTED) &&
+ (!is_trusted_reg_type(env, reg, reg_type) ||
+ bpf_type_has_unsafe_modifiers(reg_type))) {
if (!(arg_type & MEM_RCU)) {
const char *actual_type, *arg_name, *expected_type;
@@ -13671,6 +13682,8 @@ get_kfunc_arg_type(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
else
proto->arg_btf_id[arg] = ref_id_ptr;
+ arg_type |= PTR_TRUSTED;
+
/*
* A KF_RCU kfunc accepts an RCU-protected pointer where it would
* otherwise demand a referenced or trusted one. Other argument kinds
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH bpf-next v4 2/2] selftests/bpf: Cover trusted BTF ID argument provenance
2026-10-07 16:25 [PATCH bpf-next v4 0/2] bpf: Enforce trusted BTF ID argument provenance Yiyang Chen
2026-10-07 16:25 ` [PATCH bpf-next v4 1/2] " Yiyang Chen
@ 2026-10-07 16:25 ` Yiyang Chen
2026-10-07 22:24 ` Amery Hung
1 sibling, 1 reply; 6+ messages in thread
From: Yiyang Chen @ 2026-10-07 16:25 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Ihor Solodrai, Shuah Khan
Cc: bpf, linux-kernel, linux-kselftest, Amery Hung, Brahmajit Das,
Yiyang Chen
Extend verifier_global_ptr_args.c with calls that pass bare and
RCU-protected task pointers to a global __arg_trusted parameter. Both
calls must be rejected because neither pointer is referenced or trusted.
Add paired test-module kfuncs that return and accept a nullable trusted
task pointer. Passing the return value directly must succeed, covering
PTR_TRUSTED | PTR_MAYBE_NULL handling in the common argument checker.
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
tools/testing/selftests/bpf/progs/iters_testmod.c | 11 +++++++
.../selftests/bpf/progs/verifier_global_ptr_args.c | 35 ++++++++++++++++++++++
.../testing/selftests/bpf/test_kmods/bpf_testmod.c | 11 +++++++
.../selftests/bpf/test_kmods/bpf_testmod_kfunc.h | 2 ++
4 files changed, 59 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/iters_testmod.c b/tools/testing/selftests/bpf/progs/iters_testmod.c
index f65cc9766633e..145750bb64ef8 100644
--- a/tools/testing/selftests/bpf/progs/iters_testmod.c
+++ b/tools/testing/selftests/bpf/progs/iters_testmod.c
@@ -46,6 +46,17 @@ int iter_next_trusted_or_null(const void *ctx)
return 0;
}
+SEC("syscall")
+__success
+int trusted_nullable_kfunc(const void *ctx)
+{
+ struct task_struct *task;
+
+ task = bpf_kfunc_trusted_null_test();
+ bpf_kfunc_trusted_nullable_test(task);
+ return 0;
+}
+
SEC("raw_tp/sys_enter")
__success
int iter_next_rcu(const void *ctx)
diff --git a/tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c b/tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c
index 03507eeae3cb3..4c55b70df0724 100644
--- a/tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c
+++ b/tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c
@@ -289,6 +289,41 @@ __weak int subprog_void_untrusted(void *p __arg_untrusted)
return *(int *)p;
}
+__weak int subprog_trusted_bare(struct task_struct *task __arg_trusted)
+{
+ return task->pid;
+}
+
+SEC("tp_btf/task_newtask")
+__failure
+__msg("R1 must be referenced or trusted")
+__msg("Caller passes invalid args into func#{{.*}} ('subprog_trusted_bare')")
+int bare_to_trusted(void *ctx)
+{
+ struct task_struct *cur = bpf_get_current_task_btf();
+ struct task_struct *wakee;
+
+ if (!cur)
+ return 0;
+ wakee = cur->last_wakee;
+ if (!wakee)
+ return 0;
+ return subprog_trusted_bare(wakee);
+}
+
+SEC("tp_btf/task_newtask")
+__failure
+__msg("R1 must be referenced or trusted")
+__msg("Caller passes invalid args into func#{{.*}}")
+int memrcu_to_trusted(void *ctx)
+{
+ struct task_struct *cur = bpf_get_current_task_btf();
+
+ if (!cur)
+ return 0;
+ return subprog_trusted_task_nullable(cur->real_parent);
+}
+
__weak int subprog_char_untrusted(char *p __arg_untrusted)
{
return *(int *)p;
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
index 93847ca6293b4..71d587b140570 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
@@ -313,6 +313,15 @@ __bpf_kfunc void bpf_kfunc_trusted_task_test(struct task_struct *ptr)
{
}
+__bpf_kfunc struct task_struct *bpf_kfunc_trusted_null_test(void)
+{
+ return NULL;
+}
+
+__bpf_kfunc void bpf_kfunc_trusted_nullable_test(struct task_struct *ptr__nullable)
+{
+}
+
__bpf_kfunc void bpf_kfunc_trusted_num_test(int *ptr)
{
}
@@ -907,6 +916,8 @@ BTF_ID_FLAGS(func, bpf_kfunc_nested_acquire_zero_offset_test, KF_ACQUIRE)
BTF_ID_FLAGS(func, bpf_kfunc_nested_release_test, KF_RELEASE)
BTF_ID_FLAGS(func, bpf_kfunc_trusted_vma_test)
BTF_ID_FLAGS(func, bpf_kfunc_trusted_task_test)
+BTF_ID_FLAGS(func, bpf_kfunc_trusted_null_test, KF_RET_NULL)
+BTF_ID_FLAGS(func, bpf_kfunc_trusted_nullable_test)
BTF_ID_FLAGS(func, bpf_kfunc_trusted_num_test)
BTF_ID_FLAGS(func, bpf_kfunc_rcu_task_test, KF_RCU)
BTF_ID_FLAGS(func, bpf_kfunc_ret_rcu_test, KF_RET_NULL | KF_RCU_PROTECTED)
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h b/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h
index 67c02a421d133..83abcd8e6200d 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h
@@ -340,6 +340,8 @@ int bpf_kfunc_st_ops_inc10(struct st_ops_args *args) __ksym;
void bpf_kfunc_trusted_vma_test(struct vm_area_struct *ptr) __ksym;
void bpf_kfunc_trusted_task_test(struct task_struct *ptr) __ksym;
+struct task_struct *bpf_kfunc_trusted_null_test(void) __ksym;
+void bpf_kfunc_trusted_nullable_test(struct task_struct *ptr__nullable) __ksym;
void bpf_kfunc_trusted_num_test(int *ptr) __ksym;
void bpf_kfunc_rcu_task_test(struct task_struct *ptr) __ksym;
struct task_struct *bpf_kfunc_ret_rcu_test(void) __ksym;
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH bpf-next v4 1/2] bpf: Enforce trusted BTF ID argument provenance
2026-10-07 16:25 ` [PATCH bpf-next v4 1/2] " Yiyang Chen
@ 2026-10-07 16:43 ` sashiko-bot
2026-10-07 22:30 ` Amery Hung
1 sibling, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-10-07 16:43 UTC (permalink / raw)
To: Yiyang Chen; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] bpf: check_func_arg() allows PTR_UNTRUSTED | MEM_RCU into KF_RCU kfuncs
--
commit 1e71cf476e59d8805f3765efcab69f9c9d9bba4a
Author: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
bpf: Enforce trusted BTF ID argument provenance
This commit modifies the verifier to make the provenance check contract-driven
by marking generated BTF ID kfunc argument types with PTR_TRUSTED and explicitly
adding MEM_RCU only for KF_RCU kfuncs. It uses the normalized type for modifier
checks while reference lookup uses the original register.
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 353bde9ae2274..a0ab793f041d8 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
[ ... ]
> @@ -9605,8 +9614,10 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, u32 slot, u32 p
> }
> }
>
> - if (is_kfunc(meta) && (!is_trusted_reg(env, reg) ||
> - bpf_type_has_unsafe_modifiers(reg->type))) {
> + reg_type = reg->type & ~(arg_type & PTR_MAYBE_NULL);
> + if ((arg_type & PTR_TRUSTED) &&
> + (!is_trusted_reg_type(env, reg, reg_type) ||
> + bpf_type_has_unsafe_modifiers(reg_type))) {
> if (!(arg_type & MEM_RCU)) {
[ ... ]
> return -EINVAL;
> }
> if (!is_rcu_reg(reg)) {
[ ... ]
> return -EINVAL;
> }
> }
[Severity: High]
Does this allow a register with both MEM_RCU and PTR_UNTRUSTED modifiers to be
passed into KF_RCU kfuncs?
If a BPF program loads a pointer that is marked as PTR_UNTRUSTED | MEM_RCU (for
example, when loading an __rcu pointer embedded in a union) inside an RCU
critical section, and passes it to a KF_RCU kfunc:
1. The arg_type has MEM_RCU, so the first inner check !(arg_type & MEM_RCU) is
false.
2. The register has MEM_RCU, so the second inner check !is_rcu_reg(reg) is
false.
3. The validation falls through and succeeds, even though the register has the
PTR_UNTRUSTED modifier.
Since check_reg_type() bypasses the strict compatible_reg_types check for kfunc
BTF_ID arguments, this appears to leave the verifier without any checks that
would reject the untrusted modifier here. Can this result in untrusted garbage
pointers being used as valid RCU pointers?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261007-a3-arg-trusted-v4-v4-0-253ef3a1a69a@mails.tsinghua.edu.cn?part=1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH bpf-next v4 2/2] selftests/bpf: Cover trusted BTF ID argument provenance
2026-10-07 16:25 ` [PATCH bpf-next v4 2/2] selftests/bpf: Cover " Yiyang Chen
@ 2026-10-07 22:24 ` Amery Hung
0 siblings, 0 replies; 6+ messages in thread
From: Amery Hung @ 2026-10-07 22:24 UTC (permalink / raw)
To: Yiyang Chen
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Ihor Solodrai, Shuah Khan, bpf, linux-kernel,
linux-kselftest, Brahmajit Das
On Wed, Oct 7, 2026 at 9:25 AM Yiyang Chen
<chenyy23@mails.tsinghua.edu.cn> wrote:
>
> Extend verifier_global_ptr_args.c with calls that pass bare and
> RCU-protected task pointers to a global __arg_trusted parameter. Both
> calls must be rejected because neither pointer is referenced or trusted.
>
> Add paired test-module kfuncs that return and accept a nullable trusted
> task pointer. Passing the return value directly must succeed, covering
> PTR_TRUSTED | PTR_MAYBE_NULL handling in the common argument checker.
>
> Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
Reviewed-by: Amery Hung <ameryhung@gmail.com>
> ---
> tools/testing/selftests/bpf/progs/iters_testmod.c | 11 +++++++
> .../selftests/bpf/progs/verifier_global_ptr_args.c | 35 ++++++++++++++++++++++
> .../testing/selftests/bpf/test_kmods/bpf_testmod.c | 11 +++++++
> .../selftests/bpf/test_kmods/bpf_testmod_kfunc.h | 2 ++
> 4 files changed, 59 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/progs/iters_testmod.c b/tools/testing/selftests/bpf/progs/iters_testmod.c
> index f65cc9766633e..145750bb64ef8 100644
> --- a/tools/testing/selftests/bpf/progs/iters_testmod.c
> +++ b/tools/testing/selftests/bpf/progs/iters_testmod.c
> @@ -46,6 +46,17 @@ int iter_next_trusted_or_null(const void *ctx)
> return 0;
> }
>
> +SEC("syscall")
> +__success
> +int trusted_nullable_kfunc(const void *ctx)
> +{
> + struct task_struct *task;
> +
> + task = bpf_kfunc_trusted_null_test();
> + bpf_kfunc_trusted_nullable_test(task);
> + return 0;
> +}
> +
nit: tools/testing/selftests/bpf/progs/test_kfunc_param_nullable.c
feels like a better place than iters_testmod.c for the test.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH bpf-next v4 1/2] bpf: Enforce trusted BTF ID argument provenance
2026-10-07 16:25 ` [PATCH bpf-next v4 1/2] " Yiyang Chen
2026-10-07 16:43 ` sashiko-bot
@ 2026-10-07 22:30 ` Amery Hung
1 sibling, 0 replies; 6+ messages in thread
From: Amery Hung @ 2026-10-07 22:30 UTC (permalink / raw)
To: Yiyang Chen
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Ihor Solodrai, Shuah Khan, bpf, linux-kernel,
linux-kselftest, Brahmajit Das
On Wed, Oct 7, 2026 at 9:25 AM Yiyang Chen
<chenyy23@mails.tsinghua.edu.cn> wrote:
>
> A global subprogram parameter tagged __arg_trusted is verified with
> PTR_TRUSTED, but the common call-site type check accepts bare PTR_TO_BTF_ID
> and MEM_RCU registers. The callee can consequently pass a pointer with
> weaker provenance to a kfunc that does not accept RCU-protected pointers.
>
> RCU protection only guarantees that the object remains allocated through a
> grace period. It does not guarantee that an object's refcount is nonzero,
> so an RCU-protected pointer cannot satisfy the trusted-pointer contract.
> For example, an RCU-protected bpf_cpumask loaded from a map may have a
> zero refcount. Passing it through __arg_trusted lets the callee pass it
> to bpf_cpumask_acquire(), whose plain refcount_inc() can retain an object
> that will be freed after the grace period.
>
> Make the existing provenance check contract-driven. Mark generated BTF ID
> kfunc argument types with PTR_TRUSTED, and add MEM_RCU only for KF_RCU
> kfuncs. Normalize PTR_MAYBE_NULL when the argument contract permits it.
> Then use the argument flags to require trusted or referenced provenance
> and allow MEM_RCU only when the contract says so.
>
> Split is_trusted_reg() so the normalized type is used for type and modifier
> checks while reference lookup still uses the original register. Conversion
> of scalar-struct BTF ID arguments to fixed-size memory continues to
> construct a new ARG_PTR_TO_MEM type without PTR_TRUSTED.
>
> Fixes: e2b3c4ff5d18 ("bpf: add __arg_trusted global func arg tag")
> Suggested-by: Amery Hung <ameryhung@gmail.com>
> Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
> ---
> kernel/bpf/verifier.c | 27 ++++++++++++++++++++-------
> 1 file changed, 20 insertions(+), 7 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 353bde9ae2274..a0ab793f041d8 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -5327,15 +5327,17 @@ static u32 *reg2btf_ids[__BPF_REG_TYPE_MAX] = {
> [CONST_PTR_TO_MAP] = btf_bpf_map_id,
> };
>
> -static bool is_trusted_reg(struct bpf_verifier_env *env, const struct bpf_reg_state *reg)
> +static bool is_trusted_reg_type(struct bpf_verifier_env *env,
> + const struct bpf_reg_state *reg,
> + enum bpf_reg_type type)
You might want to teach your agent that the line limit is 100 columns.
There are several unnecessary line wrapping.
The fix looks good to me. Sashiko’s finding is real but pre-existing,
so it does not need to block this patch. If you respin, consider
fixing it in a separate patch with a PTR_UNTRUSTED | MEM_RCU KF_RCU
regression test.
Reviewed-by: Amery Hung <ameryhung@gmail.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-07 22:30 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-07 16:25 [PATCH bpf-next v4 0/2] bpf: Enforce trusted BTF ID argument provenance Yiyang Chen
2026-10-07 16:25 ` [PATCH bpf-next v4 1/2] " Yiyang Chen
2026-10-07 16:43 ` sashiko-bot
2026-10-07 22:30 ` Amery Hung
2026-10-07 16:25 ` [PATCH bpf-next v4 2/2] selftests/bpf: Cover " Yiyang Chen
2026-10-07 22:24 ` Amery Hung
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox