summaryrefslogtreecommitdiff
path: root/kernel
AgeCommit message (Collapse)Author
2026-09-12ftrace: Use rcu_assign_pointer() for tmp_ops filter hashLeon Hwang
tmp_ops.func_hash->filter_hash is annotated __rcu, but update_ftrace_direct_mod() assigns hash to it directly. Sparse reports an address-space mismatch. Use rcu_assign_pointer() for the assignment. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260911142512.19344-1-leon.hwang@linux.dev Fixes: 50b35c9e50a8 ("ftrace: Use hash argument for tmp_ops in update_ftrace_direct_mod") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202609110704.Q3M5vCDV-lkp@intel.com/ Signed-off-by: Leon Hwang <leon.hwang@linux.dev> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-12bpf: Allow terminal gotox instructionsSiddharth Chintamaneni
check_subprogs() treats gotox as a direct jump and validates its reserved zero offset. When gotox is the final instruction, this produces a synthetic successor one instruction past the end of the subprogram and rejects an otherwise valid program. Skip direct-offset validation for gotox and accept it as a non-fallthrough terminal instruction. Its actual targets remain validated from the instruction-array jump table during CFG construction. Fixes: 493d9e0d6083 ("bpf, x86: add support for indirect jumps") Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@gmail.com> Reviewed-by: Anton Protopopov <a.s.protopopov@gmail.com> Link: https://lore.kernel.org/r/20260902171414.96165-1-sidchintamaneni@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Check helper and kfunc arguments in one pathAmery Hung
Generated kfunc prototypes now carry the argument kinds and metadata needed by the helper argument checker, but kfunc calls still duplicate the per-argument loop and switch. Add check_func_args() to determine the argument count, validate outgoing kfunc stack arguments, and drive check_func_arg() for both call kinds. Move the remaining kfunc-only argument handlers, including the dynptr clone runtime refinement, into check_func_arg(), derive each kfunc BTF referent there once, and skip check_reg_arg() for stack-passed arguments that check_outgoing_stack_args() already validated. Keep special-kfunc ID checks behind small helpers so their table can remain in place. Keep the intentional differences selected by call metadata: helpers retain their privileged ARG_ANYTHING pointer-leak behavior, while kfunc scalars use strict ARG_SCALAR register admission. The shared ARG_PTR_TO_BTF_ID case retains helper-only compatible-ID and bpf_kptr_xchg() handling, performs kfunc trusted/RCU provenance checks, and selects the expected BTF based on call kind. Helper and kfunc memory arguments likewise retain their access modes and share fixed-memory and memory/size diagnostics. Treat an accepted nullable NULL as a completed argument check, matching the former kfunc continue path. The skipped helper-specific processing is either a no-op for NULL or deferred to the paired size argument. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-24-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Consolidate release argument validationAmery Hung
Helper and kfunc argument verification both require a live owning reference for non-dynptr release arguments. Whether that reference may be NULL is expressed by PTR_MAYBE_NULL in helper prototypes and the __nullable BTF suffix for kfuncs. Factor the shared ownership policy into check_func_arg_release(). Drop the helper-only rejection of maybe-null owning references. This allows bpf_kptr_xchg() to accept its explicitly nullable source directly, matching nullable kfunc release arguments. The verifier consumes the reference regardless of its runtime nullness. Update the tests so an owned nullable source succeeds while a nullable non-owning source remains rejected for lacking ownership. Preserve the identity of a nullable per-CPU allocation when bpf_kptr_xchg() transfers its ownership inside an RCU critical section. The converted MEM_RCU aliases no longer own a reference, but still need a non-zero ID so a NULL check on one allocation cannot refine another unrelated allocation. Use common legacy and structured diagnostic text for both call kinds. Tailor the structured suggestion to describe a pointer for helpers and include the expected BTF type for kfuncs. Resolve that type lazily from the kfunc BTF parameter only when reporting an ownership failure. The kfunc path now keys the check directly on the cached OBJ_RELEASE argument flag instead of comparing the argument register against meta->release_regno, and uses the cached argument kind for the dynptr exemption. This is another prerequisite for routing both call types through check_func_arg(). Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-22-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Consolidate function call pkt_access validationAmery Hung
check_func_arg() checks whether a helper permits packet pointers before dispatching argument-specific memory validation. check_kfunc_args() has no equivalent check, even though kfunc memory arguments may be backed by packet data. Move packet-access validation to check_helper_mem_access(), where the access direction is known and helper, kfunc, and global-subprogram memory arguments converge. Pass call metadata there so helpers continue to require bpf_func_proto::pkt_access, while writes through kfunc and global subprogram arguments use the program-type policy and set env->seen_direct_write. Keep call metadata when variable-size memory disables raw mode by clearing arg_raw_mem.regno instead, and pass it through the map-key path as well. This also makes kfunc and global-subprogram packet writes request the required writable-packet prologue and rejects them for program types that only support direct packet reads. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-20-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Admit kfunc argument registers through check_reg_type()Amery Hung
check_kfunc_args() open-codes exact register-type tests in most of its per-argument cases, duplicating what compatible_reg_types[] already expresses for helpers. This leaves two admission paths and prevents the helper and kfunc loops from converging. Runtime argument resolution now converts a scalar-struct BTF argument to fixed-size memory before register admission. Give the remaining kfunc-only argument kinds compatibility entries and run check_reg_type() once before the per-kind switch. Kfunc memory arguments already accept BPF-allocated objects. Normalize only the local comparison type to PTR_TO_MEM; subsequent memory checks still inspect the original register type. Keep allocated-object forms out of mem_types so helper calls continue through the existing type-mismatch path and retain its diagnostic. For ARG_PTR_TO_BTF_ID, let check_reg_type() admit BTF-backed register types and reject incompatible register classes with its standard diagnostic. Remove the now-unused lookup_reg2btf_ids(). Exact BTF identity and trust requirements remain checked later by process_arg_ptr_to_btf_id(). ARG_IGNORE and ARG_PTR_TO_PROG_AUX remain skipped because the verifier does not read those arguments from the program. Iterator arguments use the stack-pointer table. Graph nodes and ARG_PTR_TO_REFCOUNTED_KPTR share an allocated-object table. It admits owning and borrowed objects, including RCU-protected forms. Their switch cases retain API-specific ownership and BTF-record validation. ARG_PTR_TO_ALLOC_BTF_ID uses a separate table for object-drop arguments. Rename timer_types to map_value_types now that ARG_PTR_TO_WORKQUEUE and ARG_PTR_TO_TASK_WORK share it. Similarly, rename spin_lock_types to map_value_or_alloc_obj_types because graph roots and resource spin locks share its map-value-or-allocated-object admission. Moving admission checks into check_reg_type() must not discard the structured call-argument diagnostics emitted by the individual cases. Add bpf_diag_arg_type_plain() alongside bpf_diag_reg_type_plain() and use it to preserve the existing per-kind Pass suggestions where available. Other argument kinds retain the generic suggestion. The reason continues to report the actual register type and all accepted register types. Two behavior changes fall out of running admission first: - ARG_CONST_MEM_SIZE reaches process_const_arg(), and through it mark_chain_precision(), only after the register is known to be a scalar. Passing a pointer as a __szk argument used to reach backtrack_insn() with a non-scalar and trip the backtracking-misuse verifier bug. - ARG_CONST_MAP_PTR no longer needs its own type_may_be_null() test, because check_reg_type() compares whole register types. Every kfunc argument that is not explicitly ignored now passes through check_reg_type(), followed by the common register-offset check in the same order as a helper argument. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-19-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Consolidate helper and kfunc PTR_TO_BTF_ID argument matchingAmery Hung
Keep check_reg_type() focused on register admission. Helpers currently match BTF-ID arguments there, while kfuncs use process_kf_arg_ptr_to_btf_id(). Both paths ultimately call btf_struct_ids_match(). Introduce process_arg_ptr_to_btf_id() for helpers, kfuncs, and global subprograms. Callers provide the expected BTF and ID and retain their call-specific metadata handling. Group the helper compatible-ID, poison, and bpf_kptr_xchg() handling in a helper-only block in the ARG_PTR_TO_BTF_ID case, leaving the common matcher outside it. Derive strict matching from the generated argument type. This limits KF_RELEASE strictness to the argument marked OBJ_RELEASE while preserving the bpf_sk_release() exception and kfunc no-cast-alias rule. Remove the post-admission BTF and nullability switch from check_reg_type(), leaving it responsible for register admission. The compatibility tables already limit helper MEM_ALLOC inputs to ARG_PTR_TO_SPIN_LOCK and ARG_KPTR_XCHG_DEST, while the kptr source is admitted only for bpf_kptr_xchg(). Drop the redundant helper-ID whitelist, pointer-offset check, and constant-offset assertion. The bpf_kptr_xchg() source match now follows offset validation, so a source within a referenced object reports the release zero-offset error before the kptr type error. Update the affected selftests and use call-neutral wording for BTF mismatch diagnostics. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-18-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Drop redundant BTF pointer helper write rejectionAmery Hung
check_reg_type() rejects a trusted PTR_TO_BTF_ID admitted by mem_types unless the argument carries MEM_RDONLY. This duplicates argument-specific memory access validation and is too conservative for map keys and input map values, whose read direction is not represented by MEM_RDONLY. Since commit fa75b7c85b0d ("bpf: Enforce write checks for BTF pointer helper access"), check_helper_mem_access() forwards the requested access type to check_ptr_to_btf_access(). Map keys always request read access. Map values request write access only when tagged with MEM_WRITE. ARG_PTR_TO_MEM prototypes must carry either MEM_RDONLY or MEM_WRITE, and size arguments use the direction of their associated memory argument. check_ptr_to_btf_access() therefore checks the effective access direction in every case. Drop the early rejection and keep check_reg_type() limited to register admission. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-17-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Consolidate nullable argument validationAmery Hung
check_kfunc_args() rejects a NULL or possibly-NULL register passed to a non-nullable pointer argument up front. Helpers only do so inside check_reg_type() for PTR_TO_BTF_ID arguments, leaving other pointer kinds to fail indirectly through compatible_reg_types[]. Give both paths the same policy and factor it into check_func_arg_nullability(). Gate it on arg_type_is_scalar() rather than on the BTF shape of the kfunc parameter. This keeps a zero passed to a size argument from being interpreted as a NULL pointer. Taking nullability from the argument classification also avoids an is_kfunc_arg_nullable() lookup for every kfunc argument on every verification. Keep release-argument nullability separate from ownership checking. A possibly-NULL release argument must be rejected even if it is otherwise nullable, while the ownership check must still permit a literal NULL for bpf_kptr_xchg(). Use call-neutral structured diagnostics and retain the expected BTF type when it is available for a kfunc argument. Resolve that type lazily from the call metadata only when reporting an error. Helpers now report NULL-ness rather than a register-type mismatch for non-BTF-ID pointer arguments and literal NULL passed to a non-nullable pointer argument. Update the affected selftest expectations. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-16-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Consolidate runtime argument type resolutionAmery Hung
A function argument type can require call-site refinement before register admission. Helpers refine map-value arguments according to the recorded map type, while kfuncs reinterpret a pointer to a scalar-only BTF struct as fixed-size memory when the register does not carry a BTF ID. Add resolve_func_arg_type() as the common entry point. It delegates helper map-value refinement to the existing resolve_map_arg_type(), then handles the kfunc BTF-to-memory fallback. It updates the effective argument type and size consumed by the subsequent checks. Preserve PTR_MAYBE_NULL when changing the base type so later nullability validation observes the BTF contract. Keep OBJ_RELEASE arguments in their original pointer class. The latter is not a bug fix: existing kfunc checking already validates ownership before this resolver. It preserves release metadata for the later shared checking order, where ownership validation follows register admission. Moving the kfunc fallback before admission lets the resulting fixed-size memory argument enter the compatibility check directly. This is another step toward routing both call types through check_func_arg(). Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-15-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Resolve ARG_PTR_TO_MEM | MEM_FIXED_SIZE size in kfunc bpf_func_protoAmery Hung
A generated kfunc prototype classifies a pointer to scalar memory without an adjacent size argument as ARG_PTR_TO_MEM | MEM_FIXED_SIZE. The kfunc path currently walks BTF and resolves the pointee size each time it verifies a call. The common check_func_arg() path instead expects that size in bpf_func_proto::arg_size[]. Resolve the size when generating the prototype and teach the existing kfunc path to consume the cached value. This prepares fixed-size memory arguments to move to the common checker. arg_size[] shares storage with arg_btf_id[]. An ARG_PTR_TO_BTF_ID argument that falls back to scalar-struct memory therefore keeps its BTF ID pointer and continues resolving the size when that fallback is taken. No functional change. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-14-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Resolve BTF ID of ARG_PTR_TO_BTF_ID in kfunc bpf_func_protoAmery Hung
check_kfunc_args() walks the kfunc's BTF on every verification of a call to work out which BTF ID an ARG_PTR_TO_BTF_ID argument expects. Helpers name theirs in bpf_func_proto::arg_btf_id[], as a pointer to a BTF ID that resolve_btfids fills in at build time. The ID of a kfunc argument's referent is already stored in the immutable BTF records that describe its pointer and modifier chain. Make arg_btf_id[] point to the BTF field containing the resolved ID. A __map argument instead uses the existing vmlinux BTF ID pointer. Produce this metadata alongside the argument classification in get_kfunc_arg_type(). Declare the argument BTF ID pointers const, since the verifier only reads through them. The BTF object owns their storage and remains alive while the generated prototype is used, so the pointers remain valid when the kfunc descriptor array is reallocated or sorted. Both helper and kfunc callers can now read the expected BTF ID through the same bpf_func_proto field, which lets check_func_arg() take over the ARG_PTR_TO_BTF_ID case. arg_btf_id[] shares a union with arg_size[], so an argument cannot store both. The scalar-struct memory fallback keeps resolving its byte size at verification time, as it does today. No functional change. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-13-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Set MEM_RCU when generating kfunc argument typesAmery Hung
The BTF ID argument of a kfunc has to be referenced or trusted unless the kfunc is KF_RCU, in which case an RCU-protected pointer is accepted too. check_kfunc_args() reads that off meta->kfunc_flags on every verification of the call, which is the last thing keeping the argument policy of ARG_PTR_TO_BTF_ID out of the generated prototype. Set MEM_RCU in get_kfunc_arg_type() for ARG_PTR_TO_BTF_ID arguments of KF_RCU kfuncs, the way it already sets OBJ_RELEASE for release arguments, and test the generated flag instead. MEM_RCU represents the KF_RCU relaxation applied by the ARG_PTR_TO_BTF_ID trust check; other argument kinds have their own provenance requirements. No functional change intended. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-12-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Set MEM_UNINIT and dynptr subtypes when generating kfunc arg typesAmery Hung
The dynptr flavour a kfunc argument expects is rebuilt on every verification of the call: check_kfunc_args() starts from ARG_PTR_TO_DYNPTR, adds MEM_UNINIT from the __uninit suffix, and then walks a chain of func_id comparisons to add DYNPTR_TYPE_SKB, _XDP, _SKB_META or _FILE. All of that is fixed by the kfunc identity and BTF, so move it into get_kfunc_arg_type() and let the generated prototype carry it. Inheriting the classification also means PTR_MAYBE_NULL reaches process_dynptr_func() for a __nullable dynptr argument, where it did not before, and is_dynptr_type_expected() tested for any type of dynptr with an exact arg_type == ARG_PTR_TO_DYNPTR comparison. Test the DYNPTR_TYPE_FLAG_MASK bits instead, which is what the comment there already claims to mean and does not care about unrelated flags. What cannot move is the KF_bpf_dynptr_clone arm, which takes its type from meta->dynptr.type, recorded while verifying the parent dynptr argument earlier in the same call. That stays at the call site, applied on top of the cached classification. No functional change. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-11-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Set OBJ_RELEASE when generating kfunc argument typesAmery Hung
check_kfunc_args() ORs OBJ_RELEASE into arg_type on every verification of every argument of every call, from a comparison against meta->release_regno. Neither side of that comparison depends on the call site. bpf_fetch_kfunc_arg_meta() sets release_regno to BPF_REG_1 when the kfunc is KF_RELEASE and leaves it zero otherwise, and regno is derived from the argument index, so the test is true exactly for argument 0 of a KF_RELEASE kfunc. Set the flag in get_kfunc_arg_type() instead, where the rest of the classification is built, and drop the comparison. The release handling in check_func_proto() is helper-only, so an OBJ_RELEASE in a generated kfunc prototype does not feed back into meta->release_regno. meta->release_regno itself stays: it is still what tells the referenced PTR_TO_BTF_ID check and release_reg() which register to act on. No functional change. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-10-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Align helper and kfunc ARG_PTR_TO_PROG_AUX handlingAmery Hung
The verifier supplies a bpf_prog_aux argument to both bpf_timer_set_callback() and kfuncs rather than reading it from the BPF program. The helper prototype leaves its third argument unused, while the kfunc path identifies the argument from BTF at every call. Add ARG_PTR_TO_PROG_AUX, record it in the helper prototype, and classify the kfunc argument when its prototype is generated. Because other ignored and implicit arguments are already represented by ARG_IGNORE, the generated prototype has no internal ARG_UNUSED gaps. Validate in one place that it contains at most one prog-aux argument and that the argument is register-passed, as required by the BPF_LD_IMM64 fixup. Record the argument register in the per-instruction metadata for both call kinds. Drive the helper fixup from that metadata instead of the helper ID and its hard-coded R3, matching the existing kfunc fixup. bpf_call_arg_meta::arg_prog is then no longer needed. No functional change beyond reporting invalid kfunc signatures when the call is added rather than when it is verified. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-9-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Classify kfunc arguments the verifier ignoresAmery Hung
The verifier does not inspect __ign arguments or implicit arguments, except that bpf_prog_aux is handled specially. get_kfunc_arg_type() leaves the ignored arguments unclassified, so gen_kfunc_arg_proto() skips them and check_kfunc_args() repeats the same BTF predicates for every call. Add ARG_IGNORE and classify ignored arguments in get_kfunc_arg_type(). The generated prototype can then record them, and the call site can consume the recorded type without deriving the classification again. Keep bpf_prog_aux on its existing BTF-based path for now. No functional change. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-8-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Unify kfunc argument kinds with enum bpf_arg_typeAmery Hung
check_kfunc_args() classifies arguments with enum kfunc_ptr_arg_type while check_func_arg() uses enum bpf_arg_type, yet both classifications are stored in bpf_func_proto::arg_type. The overlapping namespaces force the kfunc path to translate argument kinds before calling shared checks. Fold the kfunc kinds into enum bpf_arg_type. Reuse ARG_SCALAR and the existing pointer and memory kinds where their semantics match, map kfunc callbacks to ARG_PTR_TO_FUNC, and add enumerators for the remaining kfunc-only kinds. check_kfunc_args() can then carry one classification throughout verification. Preserving the original argument kind also lets check_func_arg_reg_off() derive the zero-offset requirement for ARG_PTR_TO_REFCOUNTED_KPTR directly. Remove its separate btf_id_fixed_off_ok parameter and wrapper, along with the now-empty translation switch in check_kfunc_args(). Keep the PTR_TO_CTX offset decision based on the base argument kind. The generated kind may carry flags such as PTR_MAYBE_NULL, while the removed translation discarded them. This retains the zero-offset requirement for context arguments regardless of such flags. No functional change. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-7-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Clarify unused and scalar function argument typesAmery Hung
ARG_DONTCARE is the zero-valued terminator for the fixed-size helper argument array rather than an argument whose value is ignored. Rename it to ARG_UNUSED and stop helper argument iteration explicitly when it is encountered. Commit c3fd8e5fd100 ("bpf: Reject non-scalar bpf_loop iteration counts") introduced ARG_SCALAR for arguments that must be scalars. Reuse it for integer and enum global subprogram arguments, which already require SCALAR_VALUE despite being classified as ARG_ANYTHING, and for exception callback arguments. This leaves ARG_ANYTHING with its legacy helper behavior of accepting pointers when pointer leaks are allowed. Also pass ARG_PTR_TO_MEM when checking a global subprogram memory argument instead of using the prototype terminator as a placeholder. No functional change. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-6-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Only compare func_id against kfunc BTF IDs for kfunc callsAmery Hung
Helpers are identified by enum bpf_func_id, while kfuncs are identified by a BTF ID. Both values are stored in bpf_call_arg_meta::func_id, and a helper ID can have the same numeric value as a kfunc BTF ID. Introduce is_kfunc_call(), which first confirms that the metadata is for a kfunc through meta->btf, and use it for comparisons against the special kfunc BTF ID list. This complements is_helper_call() before later patches move these checks into paths shared by helpers and kfuncs. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-5-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Only compare func_id against BPF_FUNC_* for helper callsAmery Hung
Helpers are identified by enum bpf_func_id, while kfuncs are identified by a BTF ID. Both values are stored in bpf_call_arg_meta::func_id, and a kfunc BTF ID can have the same numeric value as a BPF_FUNC_* constant. Later patches extend check_reg_type() and check_func_arg() to kfuncs. A bare func_id comparison in those common paths could then mistake a kfunc for a helper. Introduce is_helper_call(), which first excludes kfunc metadata through meta->btf, and use it for every BPF_FUNC_* comparison. This keeps helper-specific behavior out of the shared path from the start. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-4-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Address check_func_arg() arguments by argnoAmery Hung
check_func_arg() derives every argument from BPF_REG_1 + arg. That works for helpers, which have at most five arguments, but kfunc arguments beyond the fifth are passed on the stack. Switch to the argno_t addressing used by check_kfunc_args(): obtain argument state with get_func_arg_reg(), use argno for diagnostics, and call check_reg_arg() only when the argument is held in a register. This prepares check_func_arg() to be shared with kfunc verification. There is no functional change for helpers. reg_arg_name() renders their register arguments as R%d, so the updated diagnostics remain unchanged. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-3-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11bpf: Pass call metadata through shared argument checksAmery Hung
Helper, kfunc, and global subprogram argument paths supply callee identity and state differently. check_reg_type() receives the call name separately from bpf_call_arg_meta, while process_dynptr_func() receives the call name, referenced-object state, and dynptr state as separate arguments. Populate meta->func_name for helper and global subprogram calls, keep one metadata object for the entire global subprogram argument check, and have both shared checking functions obtain their name and state from the metadata. This gives dynptr validation one interface for every call kind in preparation for unifying their argument-checking paths. No functional change. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260911220415.1396439-2-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-11ring-buffer: Acquire the lock with irqsave in rb_wake_up_waiters()Sebastian Andrzej Siewior
rb_wake_up_waiters() is a irq_work callback which is initialized with init_irq_work(). As such it will be invoked in thread context on PREEMPT_RT. Invoking the callback in IRQ context on PREEMPT_RT is not an option due its usage of wake_up_all(). Since this callback may run in thread context, it needs to acquire ring_buffer_per_cpu::reader_lock with disabling interrupts and may not assume that they are disabled. Use raw_spinlock_irqsave() to acquire ring_buffer_per_cpu::reader_lock. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260911102152.YEtwkBj9@linutronix.de Fixes: 68282dd930ea3 ("ring-buffer: Fix resetting of shortest_full") Reviewed-by: Vincent Donnefort <vdonnefort@google.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Take trace_array reference when opening a tracer options fileSteven Rostedt
When a tracer option file is opened, it is passed a descriptor that points to an element on the trace_array's topts array. This element has information to find the trace array and other information. It uses this element to take a reference of the trace_array so that the trace_array does not get removed while this file is opened. Unfortunately, there's a race condition where the element itself could be freed by the removal of the instance the trace_array represents causing a use-after-free as this element that is used to find the trace_array to increment its reference counter is also freed when the instance is removed. To solve this, add a trace_array_tracer_options_get() helper function that will take the address of the element that is passed to the open function by the inode->i_private pointer and search all the trace_arrays under a lock to find the one that the element's address is in the range of the trace_arrays topts array elements. When a match happens, that trace_array's reference would be increased. Note, there's a race where if an admin was deleting and creating trace instances at the same time and the memory of the old trace_array's array matched the memory of the new trace_array that it could in theory open the option from the wrong trace array. But we do not care because it would be stupid to perform that kind of action. As long as the only thing that can happen is that the option from the wrong trace array is used and doesn't crash the kernel it will only make the user confused. But if they are doing something stupid like this, they are already confused, so no harm done. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260910221209.62dad8d3@robin Fixes: 7e2cfbd2d3c86 ("tracing: Have option files inc the trace array ref count") Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/linux-trace-kernel/20260902121918.5a9e9d1b@gandalf.local.home/ Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Fix ring_buffer_read_page_size() kernel-docKarl Mehltretter
ring_buffer_read_page_size() takes a parameter named rpage, but its kernel-doc describes page. As a result, kernel-doc reports rpage as undescribed and page as an excess parameter description. Rename the documentation entry to match the function. Link: https://patch.msgid.link/20260909062917.89482-1-kmehltretter@gmail.com Fixes: dae8dda341d2 ("tracing: Fix subbuf resize races with trace_pipe_raw readers") Assisted-by: LLM Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> Reviewed-by: Vincent Donnefort <vdonnefort@google.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Restore :mod: trailer after parsing in ftrace_set_clr_event()Thomas Weißschuh
While ftrace_set_clr_event() modifies its input buffer during parsing, before returning to the caller the buffer is supposed to be restored to its original state. This works correctly for the colon between the subsystem and event but not the colon at the beginning of :mod:. Restore the colon, so the :mod: trailer is not stripped after ftrace_set_clr_event(). Cc: stable@vger.kernel.org Fixes: 4c86bc531e60 ("tracing: Add :mod: command to enabled module events") Link: https://patch.msgid.link/20260908-tracing-cli-event-filter-v2-1-05396a3fb663@linutronix.de Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Fix memory corruption from a "STACKTRACE" histogram keyDonggeun Yoo
"cpu", "CPU", "stacktrace" and "STACKTRACE" are generic fields, defined with an offset and a size of zero so that the filter code can match them by name. parse_field() maps them onto their common_* equivalents for backward compatibility, but unlike the common_* names it hands the placeholder back to the caller instead of NULL. create_hist_field() takes a non-NULL field as a promise that the record carries a stacktrace and picks HIST_FIELD_FN_STACK, so the __data_loc word is read from offset 0, that is from common_type, and its low 16 bits are followed as an offset into the record. What is found there becomes the length of an unbounded memcpy. Pick an event whose id is small enough that the offset stays inside its own record and the length is a kernel text address: # cd /sys/kernel/tracing # echo 'hist:keys=STACKTRACE' > events/ftrace/print/trigger # echo hello > trace_marker Oops: general protection fault, probably for non-canonical address RIP: 0010:rb_next+0x23/0x60 </IRQ> RIP: 0010:memcpy+0xc/0x30 event_hist_trigger+0x2e7/0x12c0 Kernel panic - not syncing: Fatal exception in interrupt Leave the field NULL, which is what the comment above the branch says the code does and what common_stacktrace already does. FILTER_CPU and FILTER_COMM are left alone, their create_hist_field() branches never look at the field. Cc: stable@vger.kernel.org Fixes: 4b512860bdbd ("tracing: Rename stacktrace field to common_stacktrace") Link: https://patch.msgid.link/20260907155045.692664-3-donggeunyoo.kernel@gmail.com Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Fix memory corruption from the histogram stacktrace modifierDonggeun Yoo
parse_field() sets HIST_FIELD_FL_STACKTRACE from the ".stacktrace" modifier before it looks the field name up, and nothing afterwards checks that the name resolved to a field which holds a stacktrace. create_hist_field() picks HIST_FIELD_FN_STACK on the strength of the field pointer alone, which reads a __data_loc word from the record and follows its low 16 bits as an offset into the same record. event_hist_trigger() takes the first word there as an entry count and copies that many longs into a 31 entry array: n_entries = *stack; memcpy(entries, ++stack, n_entries * sizeof(unsigned long)); Neither end of that copy is bounded, and the count is whatever the event holds at the offset, so any field will do: # cd /sys/kernel/tracing/events/sched/sched_process_fork # echo 'hist:keys=parent_pid.stacktrace' > trigger # (true) BUG: kernel NULL pointer dereference, address: 0000000000000008 RIP: 0010:rb_insert_color+0x18/0x130 timerqueue_linked_add+0x7e/0xd0 enqueue_hrtimer+0x39/0xb0 __hrtimer_run_queues+0x10f/0x1f0 </IRQ> RIP: 0010:memcpy+0xc/0x30 event_hist_trigger+0x165/0x690 The timer interrupt landed on the rbtree the copy had already run over. No debug options are needed for this; KASAN reports the same write as an out-of-bounds read of 13835058055416381440 bytes. Documentation/trace/histogram.rst already states the rule, "must be a long[] type", so enforce it once the name has been resolved. Names which resolve to no field at all, "hitcount.stacktrace" and the common_* pseudo-fields, are refused for the same reason: they hold no stacktrace to read. Cc: stable@vger.kernel.org Fixes: cc5fc8bfc961 ("tracing/histogram: Add stacktrace type") Link: https://patch.msgid.link/20260907155045.692664-2-donggeunyoo.kernel@gmail.com Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Undo the registration when enabling the histogram trigger failsDonggeun Yoo
Commit 6f86bdeab633 ("tracing: Fix bad hist from corrupting named_triggers list") described how a trigger that is registered but not on file->triggers ends up freed while still on the global named_triggers list, and moved the registration down so that hist_trigger_enable() follows it immediately. One path still gets there. hist_trigger_enable() adds the trigger and takes it straight back out when the event cannot be enabled: list_add_tail_rcu(&data->list, &file->triggers); update_cond_flag(file); if (trace_event_trigger_enable_disable(file, 1) < 0) { list_del_rcu(&data->list); update_cond_flag(file); ret--; } so the list walk in hist_unregister_trigger() matches nothing, test stays NULL, and the ->free() that would call del_named_trigger() is skipped. out_unreg falls through to out_free, which frees the trigger anyway: BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0 Read of size 8 at addr ffff8880091d3160 by task init/1 find_named_trigger+0xac/0xc0 hist_register_trigger+0xc1/0xa00 event_hist_trigger_parse+0x3146/0x6af0 event_trigger_write+0xce/0x160 Freed by task 69: kfree+0x154/0x420 trigger_kthread_fn+0xfd/0x160 Leave the trigger where hist_unregister_trigger() can find it and let that undo the registration, which is the only code that knows all of what cmd_ops->init() took: the named list entry, the hist_pad reference, the reference on the trigger a named histogram is shared with, and the copied cmd_ops. It also pairs the failed trace_event_trigger_enable_disable(), whose sm_ref and buffered event reference are otherwise left behind. Since ->free() releases trigger_data and, for a trigger that does not share its histogram, hist_data with it, out_unreg can no longer fall through to out_free. For a trigger that does share, hist_register_trigger() has already destroyed the caller's hist_data, so the fall-through was reading freed memory there as well. Move the enable_timestamps check in hist_unregister_trigger() above the ->free() call for the same reason: hist_data does not outlive it once the trigger being removed is the one that owns it. Cc: stable@vger.kernel.org Fixes: 067fe038e70f ("tracing: Add variable reference handling to hist triggers") Reported-by: Sashiko AI <sashiko-bot@kernel.org> Closes: https://lore.kernel.org/linux-trace-kernel/20260907092944.3950E1F00A3D@smtp.kernel.org/ Link: https://patch.msgid.link/20260907124420.607097-3-donggeunyoo.kernel@gmail.com Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Take the reference before publishing the named histogram triggerDonggeun Yoo
event_hist_trigger_named_init() puts the trigger on the global named_triggers list and only then takes the reference on the trigger it shares its histogram with: data->ref++; save_named_trigger(data->named_data->name, data); ret = event_hist_trigger_init(data->named_data); if (ret < 0) { kfree(data->cmd_ops); data->cmd_ops = &trigger_hist_cmd; } return ret; event_hist_trigger_init() fails when alloc_hist_pad() cannot allocate, and nothing takes the trigger back off the list on the way out. event_hist_trigger_parse() frees it, and the next lookup by name reads the freed object: BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0 Read of size 8 at addr ffff888009346860 by task init/1 find_named_trigger+0xac/0xc0 hist_register_trigger+0xc1/0xa00 event_hist_trigger_parse+0x3146/0x6af0 event_trigger_write+0xce/0x160 Freed by task 67: kfree+0x154/0x420 trigger_kthread_fn+0xfd/0x160 Do the reference first and publish once it has succeeded, so that nothing which can fail runs after the trigger becomes findable. Cc: stable@vger.kernel.org Fixes: 7ab0fc61ce73 ("tracing: Move histogram trigger variables from stack to per CPU structure") Reported-by: Sashiko AI <sashiko-bot@kernel.org> Closes: https://lore.kernel.org/linux-trace-kernel/20260907092944.3950E1F00A3D@smtp.kernel.org/ Link: https://patch.msgid.link/20260907124420.607097-2-donggeunyoo.kernel@gmail.com Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Acked-by: Tom Zanussi <zanussi@kernel.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Set the trace clock before registering the histogram triggerDonggeun Yoo
hist_register_trigger() puts the trigger on the global named_triggers list in cmd_ops->init(), and only then sets the trace clock: if (data->cmd_ops->init) { ret = data->cmd_ops->init(data); if (ret < 0) goto out; } if (hist_data->enable_timestamps) { ret = tracing_set_clock(file->tr, hist_data->attrs->clock); if (ret) { hist_err(tr, HIST_ERR_SET_CLOCK_FAIL, errpos(clock)); goto out; } The clock string is not checked anywhere before that call, so a named trigger using common_timestamp with an unknown clock fails after it has already become findable. event_hist_trigger_parse() then frees it without taking it off the list, and the next lookup by name reads the freed object: ~# cd /sys/kernel/tracing/events/sched/sched_switch ~# echo 'hist:name=foo:keys=common_pid:ts=common_timestamp:clock=bogus' > trigger bash: echo: write error: Invalid argument ~# echo 'hist:name=foo:keys=common_pid' > trigger BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0 Read of size 8 at addr ffff88800915d760 by task init/1 find_named_trigger+0xac/0xc0 hist_register_trigger+0xc1/0x900 event_hist_trigger_parse+0x3146/0x6af0 event_trigger_write+0xce/0x160 Freed by task 63: kfree+0x154/0x420 trigger_kthread_fn+0xfd/0x160 Set the clock before the trigger is registered, so that nothing which can fail runs after it is published, the way commit 6f86bdeab633 ("tracing: Fix bad hist from corrupting named_triggers list") moved the registration below the rest of the setup. tracing_set_filter_buffering() is reference counted, so the init failure path has to drop the reference that the clock block now takes first. Cc: stable@vger.kernel.org Fixes: a4072fe85ba3 ("tracing: Add a clock attribute for hist triggers") Link: https://patch.msgid.link/20260907091415.554535-1-donggeunyoo.kernel@gmail.com Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Fix typo "availabe" in commentHemanth Selam
Correct "availabe" to "available", reported by scripts/checkpatch.pl using the misspelling list in scripts/spelling.txt. Only touches comments, no code changes. Link: https://patch.msgid.link/20260907062608.13924-1-hemanth.selam@gmail.com Assisted-by: Cursor:claude-opus-5 Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Let histogram values keep the percent and graph modifiersDonggeun Yoo
The .percent and .graph modifiers exist only for histogram values, but a value carrying either of them has been rejected since v6.3. The example in Documentation/trace/histogram.rst, # echo 'hist:keys=prev_comm:vals=hitcount.percent:nohitcount' > \ events/sched/sched_switch/trigger returns -EINVAL. parse_field() sets the two flags only when the field is neither a key nor a variable, that is, only on a value: } else if (strncmp(modifier, "percent", 7) == 0) { if (*flags & (HIST_FIELD_FL_VAR | HIST_FIELD_FL_KEY)) goto error; *flags |= HIST_FIELD_FL_PERCENT; __create_val_field() then rejects a value for carrying them, so no field can reach hist_trigger_print_val(), where both are implemented. commit e0213434fe3e ("tracing: Do not let histogram values have some modifiers") added the check after a value with .buckets oopsed in hist_field_name(). That happens because .buckets and .log2 make create_hist_field() build a nested field in operands[0] which hist_field_name() then walks into. The percent and graph flags do not create an operand and are not read by hist_field_name(); they are only used when printing a value. Stop rejecting the two flags on a value. The check for variables is left alone, where they are unreachable anyway because parse_field() rejects a variable carrying them first. With the two flags removed, the trigger above installs and prints as documented: { prev_comm: rcu_preempt } hitcount (%): 0.00 { prev_comm: init } hitcount (%): 99.98 Totals: Hits: 237896 Cc: stable@vger.kernel.org Fixes: e0213434fe3e ("tracing: Do not let histogram values have some modifiers") Link: https://patch.msgid.link/20260907052113.430818-1-donggeunyoo.kernel@gmail.com Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Keep the entry count when the histogram stats allocation failsDonggeun Yoo
print_entries() uses n_entries both as the number of sort entries and as its own return value, so the -ENOMEM it stores when the stats allocation fails overwrites the count that the cleanup still needs: n_entries = tracing_map_sort_entries(map, ...); if (n_entries < 0) return n_entries; ... if (!stats) { n_entries = -ENOMEM; goto out; } ... out: tracing_map_destroy_sort_entries(sort_entries, n_entries); tracing_map_destroy_sort_entries() takes an unsigned int and loops up to it, so -ENOMEM arrives as 4294967284. It walks an array of at most map->max_elts pointers and calls destroy_sort_entry(), which dereferences and frees, on whatever lies past the end. Reading the hist file of a trigger with a .percent value, with that allocation forced to fail: BUG: KASAN: vmalloc-out-of-bounds in tracing_map_destroy_sort_entries+0xa0/0xb0 Read of size 8 at addr ffffc90000045000 by task init/1 tracing_map_destroy_sort_entries+0xa0/0xb0 hist_show+0x6f7/0x1df0 seq_read_iter+0x2b8/0x1190 vfs_read+0x176/0xa40 The buggy address belongs to a 4-page vmalloc region starting at ffffc90000041000 allocated at tracing_map_sort_entries+0x5c/0xd50 A few pages further the fault is fatal. The registers at the oops confirm the bound: the loop's end pointer less the array start, over the pointer size, is 4294967284. Return the error in a separate variable and leave n_entries holding the count, the way tracing_map_sort_entries() does on its own error path. The stats block is only entered for a value carrying .percent or .graph, which __create_val_field() has rejected since v6.3, so this cannot be reached in mainline as it stands. It becomes reachable again with "tracing: hist: let values keep the percent and graph modifiers", so it should be applied first. Cc: stable@vger.kernel.org Fixes: abaa5258ce5e ("tracing: Add .percent suffix option to histogram values") Link: https://patch.msgid.link/20260907060323.480728-1-donggeunyoo.kernel@gmail.com Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/all/20260907053113.1CED91F00A3A@smtp.kernel.org/ Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Free histogram the field rejected for a bad modifierDonggeun Yoo
Writing a hist trigger whose value or variable carries a modifier that is not allowed there leaks the fields that were built for it. __create_val_field() takes the field from parse_expr() and stores it in hist_data->fields[] only after the modifier checks have run: hist_field = parse_expr(hist_data, file, field_str, flags, var_name, &n_subexprs); ... if (hist_field->flags & HIST_FIELD_FL_VAR) { if (hist_field->flags & (...)) goto err; } else { if (hist_field->flags & (...)) goto err; } hist_data->fields[val_idx] = hist_field; Both checks jump past that store, and the err label returns without freeing anything. The error unwinds to create_hist_data(), which calls destroy_hist_data() -> destroy_hist_fields(), and that reaches a field only by walking fields[]. A field that never got there is unreachable. commit e0213434fe3e ("tracing: Do not let histogram values have some modifiers") set ret to -EINVAL and fell through to the store, which left the field owned by fields[] and freed along with the rest of hist_data. Splitting the check into a value case and a variable case replaced that fall-through with a goto that skips it. With CONFIG_DEBUG_KMEMLEAK, 200 writes of # echo 'hist:keys=prev_pid:vals=next_pid.log2' > \ events/sched/sched_switch/trigger each correctly rejected with -EINVAL, leave 332 unreferenced objects (63744 bytes) reported at create_hist_field(); 200 install and remove cycles of a valid trigger leave none. A '.log2' field is two allocations, since create_hist_field() puts the plain field in operands[0] of the log2 field, and both are reported. Use destroy_hist_field() rather than __destroy_hist_field() so that operands[0] is freed as well. It returns early for HIST_FIELD_FL_VAR_REF, which is what an operand owned by hist_data->var_refs[] needs; the rejected field itself is never a var ref, because a var ref never carries a modifier flag. Cc: stable@vger.kernel.org Fixes: e30fbc618e97 ("tracing/histograms: Allow variables to have some modifiers") Link: https://patch.msgid.link/20260907034948.240387-1-donggeunyoo.kernel@gmail.com Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Free histogram the var ref when its initialization failsDonggeun Yoo
create_var_ref() allocates a VAR_REF hist_field and then calls init_var_ref() to fill it in. When that fails the field is leaked. commit 656fe2ba85e8 ("tracing: Use hist trigger's var_ref array to destroy var_refs") made destroy_hist_field() return early for HIST_FIELD_FL_VAR_REF, since var refs are freed by walking the trigger's var_refs[] array instead. create_var_ref() adds the field to that array only after init_var_ref() has succeeded, so on this path the field is in neither place and nothing frees it. The call was correct when it was written, before var refs were taken out of destroy_hist_field(). init_var_ref() cannot free it either. The caller owns the field, so init_var_ref() undoes only its own string allocations and leaves the field alone. Freeing it there would leave create_var_ref() passing freed memory to destroy_hist_field(), which reads its flags. Call __destroy_hist_field(), which frees the field without consulting the flag. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260906133352.3815019-1-donggeunyoo.kernel@gmail.com Fixes: 656fe2ba85e8 ("tracing: Use hist trigger's var_ref array to destroy var_refs") Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11tracing: Free histogram var refs regardless of how often they are referencedDonggeun Yoo
Using the same variable three or more times in one hist trigger leaks the variable reference and its strings when the trigger is removed. commit 656fe2ba85e8 ("tracing: Use hist trigger's var_ref array to destroy var_refs") made a trigger's var_refs[] array the only owner of a var ref: destroy_hist_field() returns early for HIST_FIELD_FL_VAR_REF, so the field expressions never destroy one. One entry, freed once, no count needed. commit 8bcebc77e85f ("tracing: Fix histogram code when expression has same var as value") then made repeated references share one object and added a count of them. Only the increment side exists, since those expressions still return early and never drop a reference, so __destroy_hist_field() sees how many references were created rather than how many are left. It frees when the decremented count is 0 or 1, so two references work and three or more leak. Sharing kept one array entry per object, and create_var_ref() searches and appends within a single trigger, so nothing outside it holds the object. Removing a trigger whose variables are still referenced is already refused by check_var_refs() with -EBUSY. Drop the count and free unconditionally. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260906124025.3550596-1-donggeunyoo.kernel@gmail.com Fixes: 8bcebc77e85f ("tracing: Fix histogram code when expression has same var as value") Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11function_graph: Use the saved entry's size when reprinting itDonggeun Yoo
When a graph entry does not fit in the trace_seq, print_graph_entry() saves it in the iterator's fgraph_data and reprints it on the next read. The entry has already been consumed from the ring buffer by then, so the copy is all that is left of it. The copy is sized with iter->ent_size, which no longer describes the saved entry but whatever entry the iterator has moved on to. The argument count is derived from the same field, so a 72 byte entry saved and then reprinted ahead of a 48 byte return entry loses its arguments. Record the size next to the failure flag, so that the two are always set together, and restore it before reprinting. Cc: stable@vger.kernel.org Fixes: ff5c9c576e75 ("ftrace: Add support for function argument to graph tracer") Link: https://patch.msgid.link/20260906034406.1335316-1-donggeunyoo.kernel@gmail.com Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11fgraph: Remove unused FGRAPH_MAX_INDEXDonggeun Yoo
FGRAPH_MAX_INDEX has no user, and it expands to FGRAPH_INDEX_SIZE and FGRAPH_RET_INDEX, neither of which is defined anywhere in the tree. It was added in that form by commit 91c46b0aa917 ("function_graph: Implement fgraph_reserve_data() and fgraph_retrieve_data()"), which introduced the current data word layout under new names, so anything referencing it would have failed to build ever since. Remove it. Link: https://patch.msgid.link/20260905211922.1196366-1-donggeunyoo.kernel@gmail.com Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11bpf: btf: Make alloc_obj_fields array constBradley Morgan
The alloc_obj_fields array is never modified. Make the array itself const, not just the strings it points to. Signed-off-by: Bradley Morgan <brads@mainlining.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260906223358.25717-1-brads@mainlining.org
2026-09-11ftrace: fork: Initialize function graph state before copy_exec_state()Jérémy Jean
dup_task_struct() copies the parent's task_struct, including ret_stack. ftrace_graph_init_task() clears the copied function graph state, but it currently runs after copy_exec_state(). For non-CLONE_VM forks, copy_exec_state() allocates a new task_exec_state. If that allocation fails, copy_process() reaches bad_fork_free and free_task() calls ftrace_graph_exit_task(). Since the child still carries the parent's ret_stack pointer, the unwind frees the parent's active function graph return stack. The parent subsequently accesses freed memory from function_graph_enter_regs(). KASAN reports: [ 22.190920] ================================================================== [ 22.195899] BUG: KASAN: slab-use-after-free in function_graph_enter_regs+0xa76/0xb90 [ 22.200747] Write of size 8 at addr ff110000054dc0a8 by task repro/1 [ 22.205134] [ 22.210770] CPU: 0 UID: 0 PID: 1 Comm: repro Not tainted 7.2.0-07732-g9328b3b03bdc-dirty #3 PREEMPT(lazy) [ 22.212576] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 22.213750] Call Trace: [ 22.215271] <TASK> [ 22.216242] ? ftrace_stub_direct_tramp+0x10/0x10 [ 22.217774] dump_stack_lvl+0x4e/0x70 [ 22.220531] print_report+0x157/0x4b4 [ 22.223202] ? fixup_red_left+0x9/0x30 [ 22.224407] ? complete_report_info+0x83/0x110 [ 22.226679] ? function_graph_enter_regs+0xa76/0xb90 [ 22.228084] kasan_report+0xce/0x100 [ 22.230109] ? function_graph_enter_regs+0xa76/0xb90 [ 22.232860] ? stack_trace_save+0x4/0xd0 [ 22.234156] function_graph_enter_regs+0xa76/0xb90 [ 22.236090] ? kasan_save_stack+0x30/0x50 [ 22.237752] ? __pfx_function_graph_enter_regs+0x10/0x10 [ 22.238694] ? ring_buffer_lock_reserve+0x345/0xf80 [ 22.239628] ? stack_trace_save+0x4/0xd0 [ 22.242121] ? stack_trace_save+0x4/0xd0 [ 22.243588] ftrace_graph_func+0xda/0x160 [ 22.245362] ? ftrace_stub_direct_tramp+0x10/0x10 [ 22.246520] 0xffffffffa0000095 [ 22.250528] ? stack_trace_save+0x9/0xd0 [ 22.251757] ? ring_buffer_unlock_commit+0x11d/0x5c0 [ 22.253152] stack_trace_save+0x9/0xd0 [ 22.254264] kasan_save_stack+0x30/0x50 [ 22.273631] kasan_save_track+0x14/0x30 [ 22.276763] kasan_save_free_info+0x3b/0x70 [ 22.278296] __kasan_slab_free+0x43/0x70 [ 22.280157] kmem_cache_free+0xbf/0x3b0 [ 22.282963] ? ftrace_stub_direct_tramp+0x10/0x10 [ 22.284001] free_task+0xa2/0x160 [ 22.285699] ? ftrace_stub_direct_tramp+0x10/0x10 [ 22.286752] copy_process+0x2aae/0x7bc0 Initialize the child function graph state immediately after dup_task_struct(), before the first fallible operation. Cc: stable@vger.kernel.org Fixes: 6b1c66c9cca9 ("exec_state: relocate dumpable information") Reviewed-by: Bradley Morgan <include@grrlz.net> Link: https://patch.msgid.link/20260822195321.962383-2-Jeremy.Jean@oss.cyber.gouv.fr Assisted-by: Codex:gpt-5 Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11bpf: Fix program BTF use-after-free in sleepable programsSanghyun Park
Object kfunc calls embed metadata owned by the program BTF. A sleepable program can remain active under Tasks Trace RCU after its last reference is dropped, while program teardown releases the BTF through ordinary RCU. The invocation can then dereference freed metadata in bpf_obj_new(). Move btf_put() into __bpf_prog_put_rcu(), the callback that frees the program. When teardown is deferred, that callback runs after the program's own grace period (Tasks Trace RCU for sleepable programs and ordinary RCU otherwise), so the BTF outlives every active invocation. The non-deferred path invokes the callback synchronously, so load-error cleanup stays direct. Fixes: 958cf2e273f0 ("bpf: Introduce bpf_obj_new") Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Reviewed-by: Sun Jian <sun.jian.kdev@gmail.com> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/bpf/20260901014829.3504342-2-sanghyun.park.cnu@gmail.com
2026-09-11tracing/user_events: Don't destroy fields when event removal failsHenry Martin
destroy_user_event() destroys the event's fields before attempting to remove the trace event call. If user_event_set_call_visible() fails, e.g. because the event is still enabled and trace_remove_event_call() returns -EBUSY, the event is left registered with an irreversibly destroyed field list. Any subsequent interaction with the event then operates on an empty field list while it is still fully visible in tracefs. Move the field destruction after the call removal, and splice the field list back onto the event when the removal fails so the event remains in a consistent state. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260904115223.2976446-1-bsdhenrymartin@gmail.com Fixes: 7f5a08c79df35 ("user_events: Add minimal support for trace_event into ftrace") Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com> Reviewed-by: Beau Belgrave <beaub@linux.microsoft.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2026-09-11workqueue: BUG_ON() a pwq release before workqueue_init()Breno Leitao
put_pwq() bounces the release to pwq_release_worker to get out from under pool->lock. workqueue_init() creates that kthread_worker well after workqueue_init_early() has built the system workqueues, so a pwq allocation failing partway through apply_wqattrs_prepare() unwinds through apply_wqattrs_cleanup() and dereferences a NULL worker. There is no way back from that. Running the release inline is not an option, that is what the bounce exists for, and workqueue_init_early() already BUG_ON()s a system workqueue it failed to allocate. BUG_ON() the missing worker instead of oopsing inside kthread_queue_work(). Suggested-by: Tejun Heo <tj@kernel.org> Link: https://lore.kernel.org/all/144b3dc986135ebe34f671cdd02bd8aa@kernel.org/ Signed-off-by: Breno Leitao <leitao@debian.org> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-11cgroup: Move cgrp_dead_ task+iwork into its own structSebastian Andrzej Siewior
cgrp_dead_tasks and cgrp_dead_tasks_iwork are independent per-CPU variables and are independently accessed via a this_cpu_ptr(). Having a custom struct with those two members makes it possible to have only one per-CPU accessor and access the second member via an offset. This makes the code a bit more compact and is a micro-optimization. Besides that, it allows cgrp_dead_tasks_iwork_fn() to access the list pointer via the passed iwork pointer. This not only eliminates the this_cpu_ptr() but also makes it possible to be invoked on a different CPU. This does not happen as of today but might if I can flush the irq_work items from another CPU during CPU-hotplug events. Create struct cgroup_dead with the per-CPU variables as members. Access the struct with a per-CPU accessor and use container_of() in the irq_work callback. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Acked-by: Michal Koutný <mkoutny@suse.com> Signed-off-by: Tejun Heo <tj@kernel.org>
2026-09-11PM: CPU: Restore synchronize_rcu() to cpu_pm_unregister_notifier()Bradley Morgan
cpu_pm_notify() walks the notifier chain lockless under only rcu_read_lock(). That only works if a removed notifier block is not freed until every concurrent walker is done with it. The chain used to be an atomic_notifier, whose unregister ends in synchronize_rcu(). Commit b2f6662ac08d ("PM: cpu: Make notifier chain use a raw_spinlock_t") switched it over to a raw_notifier, and in doing so replaced that with raw_notifier_chain_unregister(), which does not synchronize. The grace period quietly went away, so a driver that frees the memory holding its notifier block right after cpu_pm_unregister_notifier() returns can race with a concurrent walker: cpu1 (idle exit) cpu2 (driver remove) ---------------- -------------------- cpu_pm_notify(CPU_PM_EXIT) rcu_read_lock() nb = rcu_dereference_raw(*nl) cpu_pm_unregister_notifier(&od->nb) unlink, no grace period remove() frees od (devm) nb->notifier_call(nb, ...) /* use after free */ The rcu_read_lock() on cpu1 does not stop cpu2 from freeing the block, and nothing else does. The read side is the idle exit path, so this can hit on any system where a driver with a cpu_pm notifier gets unbound. Add the grace period back. It is only needed when a notifier was actually removed, so wait on success and return -ENOENT without waiting otherwise. The kerneldoc gets back the "may sleep" note that the same commit dropped. Fixes: b2f6662ac08d ("PM: cpu: Make notifier chain use a raw_spinlock_t") Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Bradley Morgan <include@grrlz.net> [ rjw: Subject tweak ] Link: https://patch.msgid.link/20260813074343.26460-3-include@grrlz.net Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2026-09-11userns: rename insert_extent() and sort_idmaps()Christian Brauner
The KUnit test suite turned insert_extent() and sort_idmaps() into global symbols and declared them in include/linux/user_namespace.h. That header is pulled in nearly everywhere through linux/cgroup.h and the btrfs self-tests carry a static insert_extent() of their own, so any config with both test suites enabled fails to build: fs/btrfs/tests/inode-tests.c:16:13: error: conflicting types for 'insert_extent' include/linux/user_namespace.h:212:12: note: previous declaration of 'insert_extent' A global symbol needs a prefix. Rename them to uid_gid_map_insert_extent() and uid_gid_map_sort(). It's the better name anyway. No functional changes. Fixes: f6f1a2496ba5 ("userns: Add KUnit test suite for uid_gid_map") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202609110843.okbPe7GM-lkp@intel.com/ Closes: https://lore.kernel.org/oe-kbuild-all/202609110937.zHKPPXJk-lkp@intel.com/ Link: https://patch.msgid.link/20260911-suggerieren-suchaktion-fliehen-87b9cdf1d169@brauner Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-11hrtimer: Use hard expiry when updating timers on the same baseAndrea Parri
Rearming a queued timer with nonzero slack can leave the timerqueue out of order. remove_and_enqueue_same_base() checks the new soft expiry against its neighbours' hard expiries, then stores the new hard expiry in the node without requeueing it. For example, with A at 10 and B at 20, rearming A at 11 with slack 30 passes the neighbour check but leaves A's hard expiry of 41 before B's 20. The same function also caches the soft expiry in base->expires_next when updating or inserting the first timer, giving next-event selection an earlier deadline than the queue head's hard expiry. Set the timer expiry before handling the queue. Use its stored hard expiry for the in-place ordering check and both updates to base->expires_next. The early update is safe because remove_and_enqueue_same_base() runs with base->cpu_base->lock held. The lock keeps the queue stable while hrtimer_can_update_in_place() checks the new expiry against both neighbours. If the check fails, timerqueue_linked_del() removes the node without comparing expiry values before it is reinserted. Fixes: eddffab8282e3 ("hrtimer: Keep track of first expiring timer per clock base") Fixes: 343f2f4dc5425 ("hrtimer: Try to modify timers in place") Signed-off-by: Andrea Parri <parri.andrea@gmail.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Assisted-by: LLM Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260910143442.2018-1-parri.andrea@gmail.com
2026-09-10bpf: Fix divide-by-zero in btf_struct_walk()Jiayuan Chen
When an access goes past the struct and the last member is a flexible array, btf_struct_walk() folds the offset back into a single element with (off - moff) % t->size, but never checks that the element type has a size. BTF takes an empty struct, so this in program BTF /* event could be empty */ struct event { #ifdef HAVE_TIMESTAMP __u64 ts; #endif }; struct batch { int nr; struct event events[]; }; divides by zero at prog load time. Getting there needs a PTR_TO_BTF_ID that is not MEM_ALLOC, e.g. a plain read of a local kptr stashed in a map from a sleepable program. Oops: divide error: 0000 [#1] SMP KASAN PTI RIP: 0010:btf_struct_walk+0x53f/0x1570 Call Trace: <TASK> btf_struct_access+0x42a/0xcd0 check_ptr_to_btf_access+0x4dc/0x1160 check_mem_access+0x3a45/0x8740 check_load_mem+0x36a/0xd10 do_check_common+0x3ef0/0xb210 bpf_check+0x6d3b/0x8580 bpf_prog_load+0xf7c/0x2720 __sys_bpf+0xa83/0x3690 __x64_sys_bpf+0xc7/0x150 x64_sys_call+0x1f3f/0x27e0 do_syscall_64+0xe5/0x610 entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK> Reject a zero-sized element type. The fixed array path in the same function already bails out on the same thing: btf_struct_walk() ... /* skip empty array */ if (moff == mtrue_end) continue; msize /= total_nelems; Fixes: 9c5f8a1008a1 ("bpf: Support variable length array in tracing programs") Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20260910122316.186384-1-jiayuan.chen@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>