FAILED: patch "[PATCH] perf: Require kernel access for text poke events" failed to apply to 6.12-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 357e8a77a501d96c9517f01f4a211eed5e9c9184
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026100517-flask-antiviral-2fbf@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 357e8a77a501d96c9517f01f4a211eed5e9c9184 Mon Sep 17 00:00:00 2001
From: Zhengchuan Liang <[email protected]>
Date: Mon, 28 Sep 2026 10:59:35 -0700
Subject: [PATCH] perf: Require kernel access for text poke events
Perf events with exclude_kernel=1 can be opened without kernel perf access. However, exclude_kernel does not suppress text-poke sideband records. Every PERF_RECORD_TEXT_POKE is marked PERF_RECORD_MISC_KERNEL and contains a raw kernel instruction address.
An unprivileged task can therefore open and mmap a task-local software event with text_poke=1. Both opening a count-only tracepoint event and configuring UDP GRO for ESP-in-UDP cause updates to inline static calls; the observer receives the relocated addresses of the modified instructions. For a known kernel image, any such address reveals the runtime kernel text base despite KASLR.
Call perf_allow_kernel() whenever attr.text_poke is set, regardless of exclude_kernel. Events that neither monitor kernel execution nor request text-poke records retain their existing permissions.
kernel/events/core.c +1 -1
@@ -13906,7 +13906,7 @@ SYSCALL_DEFINE5(perf_event_open,if (err)return err; -if (!attr.exclude_kernel || +if (!attr.exclude_kernel || attr.text_poke || ((attr.sample_type &PERF_SAMPLE_CALLCHAIN ) && !attr.exclude_callchain_kernel)) { err =perf_allow_kernel ();
Sasha Levin
maintainerPATCH 1/3 perf: Remove unnecessary parameter of security check
From: Luo Gengkun <[email protected]>
[ Upstream commit 9ec84f79c5a7a65cd69b5b705a203759665160cd ]
It seems that the attr parameter was never been used in security checks since it was first introduced by:
commit da97e18458fb ("perf_event: Add support for LSM and SELinux checks")
so remove it.
Stable-dep-of: 357e8a77a501 ("perf: Require kernel access for text poke events")
--- arch/x86/events/intel/bts.c | 2 +- arch/x86/events/intel/core.c | 2 +- arch/x86/events/intel/p4.c | 2 +- drivers/perf/arm_spe_pmu.c | 4 ++-- include/linux/lsm_hook_defs.h | 2 +- include/linux/perf_event.h | 10 +++++----- include/linux/security.h | 5 ++--- kernel/events/core.c | 14 +++++++------- kernel/trace/trace_event_perf.c | 4 ++-- security/security.c | 5 ++--- security/selinux/hooks.c | 2 +- 11 files changed, 25 insertions(+), 27 deletions(-)
arch/x86/events/intel/bts.c +1 -1
@@ -559,7 +559,7 @@ static int bts_event_init(struct perf_event *event)* to the user in a zero-copy fashion. */ if (event->attr.exclude_kernel) { - ret =perf_allow_kernel (&event->attr); + ret =perf_allow_kernel ();if (ret)return ret; }
arch/x86/events/intel/core.c +1 -1
@@ -4256,7 +4256,7 @@ static int intel_pmu_hw_config(struct perf_event *event)if (x86_pmu.version <3 )return -EINVAL ; - ret =perf_allow_cpu (&event->attr); + ret =perf_allow_cpu ();if (ret)return ret;
arch/x86/events/intel/p4.c +1 -1
@@ -776,7 +776,7 @@ static int p4_validate_raw_event(struct perf_event *event)* the user needs special permissions to be able to use it */ if (p4_ht_active () && p4_event_bind_map[v].shared) { - v =perf_allow_cpu (&event->attr); + v =perf_allow_cpu ();if (v)return v; }
drivers/perf/arm_spe_pmu.c +2 -2
@@ -50,7 +50,7 @@ static_assert((PERF_EVENT_FLAG_ARCH & SPE_PMU_HW_FLAGS_CX) == SPE_PMU_HW_FLAGS_Cstatic void set_spe_event_has_cx (struct perf_event *event) { -if (IS_ENABLED (CONFIG_PID_IN_CONTEXTIDR ) && !perf_allow_kernel (&event->attr)) +if (IS_ENABLED (CONFIG_PID_IN_CONTEXTIDR ) && !perf_allow_kernel ()) event->hw.flags |=SPE_PMU_HW_FLAGS_CX ; }
@@ -752,7 +752,7 @@ static int arm_spe_pmu_event_init(struct perf_event *event)set_spe_event_has_cx (event); reg =arm_spe_event_to_pmscr (event);if (reg & (PMSCR_EL1_PA |PMSCR_EL1_PCT )) -return perf_allow_kernel (&event->attr); +return perf_allow_kernel ();return 0 ; }
include/linux/lsm_hook_defs.h +1 -1
@@ -445,7 +445,7 @@ LSM_HOOK(int, 0, bpf_token_capable, const struct bpf_token *token, int cap) LSM_HOOK(int, 0, locked_down, enum lockdown_reason what)#ifdef CONFIG_PERF_EVENTS -LSM_HOOK(int, 0, perf_event_open, struct perf_event_attr *attr, int type) +LSM_HOOK(int, 0, perf_event_open, int type) LSM_HOOK(int, 0, perf_event_alloc, struct perf_event *event) LSM_HOOK(int, 0, perf_event_read, struct perf_event *event) LSM_HOOK(int, 0, perf_event_write, struct perf_event *event)
include/linux/perf_event.h +5 -5
@@ -1670,22 +1670,22 @@ static inline int perf_is_paranoid(void)return sysctl_perf_event_paranoid >-1 ; } -int perf_allow_kernel (struct perf_event_attr *attr); +int perf_allow_kernel (void ); -static inline int perf_allow_cpu (struct perf_event_attr *attr) +static inline int perf_allow_cpu (void ) {if (sysctl_perf_event_paranoid >0 && !perfmon_capable ())return -EACCES ; -return security_perf_event_open (attr,PERF_SECURITY_CPU ); +return security_perf_event_open (PERF_SECURITY_CPU ); } -static inline int perf_allow_tracepoint (struct perf_event_attr *attr) +static inline int perf_allow_tracepoint (void ) {if (sysctl_perf_event_paranoid >-1 && !perfmon_capable ())return -EPERM ; -return security_perf_event_open (attr,PERF_SECURITY_TRACEPOINT ); +return security_perf_event_open (PERF_SECURITY_TRACEPOINT ); }extern void perf_event_init (void );
include/linux/security.h +2 -3
@@ -2270,14 +2270,13 @@ struct perf_event_attr;struct perf_event ;#ifdef CONFIG_SECURITY -extern int security_perf_event_open (struct perf_event_attr *attr,int type); +extern int security_perf_event_open (int type);extern int security_perf_event_alloc (struct perf_event *event);extern void security_perf_event_free (struct perf_event *event);extern int security_perf_event_read (struct perf_event *event);extern int security_perf_event_write (struct perf_event *event);#else -static inline int security_perf_event_open (struct perf_event_attr *attr, -int type) +static inline int security_perf_event_open (int type) {return 0 ; }
kernel/events/core.c +7 -7
@@ -4924,7 +4924,7 @@ find_get_context(struct task_struct *task, struct perf_event *event)if (!task) {/* Must be root to operate on a CPU event: */ - err =perf_allow_cpu (&event->attr); + err =perf_allow_cpu ();if (err)return ERR_PTR (err);
@@ -12631,7 +12631,7 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, }/* privileged levels capture (kernel, hv): check permissions */ if (mask &PERF_SAMPLE_BRANCH_PERM_PLM ) { - ret =perf_allow_kernel (attr); + ret =perf_allow_kernel ();if (ret)return ret; }
@@ -12889,12 +12889,12 @@ SYSCALL_DEFINE5(perf_event_open,return err;/* Do we allow access to perf_event_open(2) ? */ - err =security_perf_event_open (&attr,PERF_SECURITY_OPEN ); + err =security_perf_event_open (PERF_SECURITY_OPEN );if (err)return err;if (!attr.exclude_kernel) { - err =perf_allow_kernel (&attr); + err =perf_allow_kernel ();if (err)return err; }
@@ -12914,7 +12914,7 @@ SYSCALL_DEFINE5(perf_event_open,/* Only privileged users can get physical addresses */ if ((attr.sample_type &PERF_SAMPLE_PHYS_ADDR )) { - err =perf_allow_kernel (&attr); + err =perf_allow_kernel ();if (err)return err; }
@@ -13708,12 +13708,12 @@ const struct perf_event_attr *perf_event_attrs(struct perf_event *event)return &event->attr; } -int perf_allow_kernel (struct perf_event_attr *attr) +int perf_allow_kernel (void ) {if (sysctl_perf_event_paranoid >1 && !perfmon_capable ())return -EACCES ; -return security_perf_event_open (attr,PERF_SECURITY_KERNEL ); +return security_perf_event_open (PERF_SECURITY_KERNEL ); }EXPORT_SYMBOL_GPL (perf_allow_kernel);
kernel/trace/trace_event_perf.c +2 -2
@@ -49,7 +49,7 @@ static int perf_trace_event_perm(struct trace_event_call *tp_event,/* The ftrace function trace is allowed only for root. */ if (ftrace_event_is_function (tp_event)) { - ret =perf_allow_tracepoint (&p_event->attr); + ret =perf_allow_tracepoint ();if (ret)return ret;
@@ -86,7 +86,7 @@ static int perf_trace_event_perm(struct trace_event_call *tp_event,* ...otherwise raw tracepoint data can be a severe data leak, * only allow root to have these. */ - ret =perf_allow_tracepoint (&p_event->attr); + ret =perf_allow_tracepoint ();if (ret)return ret;
security/security.c +2 -3
@@ -5954,16 +5954,15 @@ EXPORT_SYMBOL(security_bdev_setintegrity);#ifdef CONFIG_PERF_EVENTS /** * security_perf_event_open() - Check if a perf event open is allowed -* @attr: perf event attribute * @type: type of event * * Check whether the @type of perf_event_open syscall is allowed. * * Return: Returns 0 if permission is granted. */ -int security_perf_event_open (struct perf_event_attr *attr,int type) +int security_perf_event_open (int type) { -return call_int_hook (perf_event_open, attr, type); +return call_int_hook (perf_event_open, type); }/**
security/selinux/hooks.c +1 -1
@@ -7226,7 +7226,7 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = { };#ifdef CONFIG_PERF_EVENTS -static int selinux_perf_event_open (struct perf_event_attr *attr,int type) +static int selinux_perf_event_open (int type) {u32 requested, sid =current_sid ();
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/3 perf/core: Check kernel access when kernel callchains are requested
From: Dapeng Mi <[email protected]>
[ Upstream commit a4573a3838ae4fc73b70019cfa1dac9aaea7cc2f ]
perf_event_open() currently gates perf_allow_kernel() only on !attr.exclude_kernel.
However, users can still request kernel callchain collection with attr.exclude_callchain_kernel == 0 even when attr.exclude_kernel == 1. That still requires kernel profiling privilege, but the existing check does not enforce it.
Update the permission check to call perf_allow_kernel() when either kernel sampling is requested or kernel callchains are requested.
This keeps permission checks aligned with requested data and prevents unprivileged use of kernel callchain capture.
Stable-dep-of: 357e8a77a501 ("perf: Require kernel access for text poke events")
--- kernel/events/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/events/core.c +3 -1
@@ -12893,7 +12893,9 @@ SYSCALL_DEFINE5(perf_event_open,if (err)return err; -if (!attr.exclude_kernel) { +if (!attr.exclude_kernel || + ((attr.sample_type &PERF_SAMPLE_CALLCHAIN ) && + !attr.exclude_callchain_kernel)) { err =perf_allow_kernel ();if (err)return err;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/3 perf: Require kernel access for text poke events
In reply to Sasha LevinFrom: Zhengchuan Liang <[email protected]>
[ Upstream commit 357e8a77a501d96c9517f01f4a211eed5e9c9184 ]
Perf events with exclude_kernel=1 can be opened without kernel perf access. However, exclude_kernel does not suppress text-poke sideband records. Every PERF_RECORD_TEXT_POKE is marked PERF_RECORD_MISC_KERNEL and contains a raw kernel instruction address.
An unprivileged task can therefore open and mmap a task-local software event with text_poke=1. Both opening a count-only tracepoint event and configuring UDP GRO for ESP-in-UDP cause updates to inline static calls; the observer receives the relocated addresses of the modified instructions. For a known kernel image, any such address reveals the runtime kernel text base despite KASLR.
Call perf_allow_kernel() whenever attr.text_poke is set, regardless of exclude_kernel. Events that neither monitor kernel execution nor request text-poke records retain their existing permissions.
--- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/core.c +1 -1
@@ -12893,7 +12893,7 @@ SYSCALL_DEFINE5(perf_event_open,if (err)return err; -if (!attr.exclude_kernel || +if (!attr.exclude_kernel || attr.text_poke || ((attr.sample_type &PERF_SAMPLE_CALLCHAIN ) && !attr.exclude_callchain_kernel)) { err =perf_allow_kernel ();
Signature · 1 line
2.53.0