dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 0/2] perf: Add some null ptr checks
@ 2026-09-02 15:48 Vinay Belgaumkar
  2026-09-02 15:48 ` [PATCH v7 1/2] perf: Fix null pointer access in is_include_guest_event() Vinay Belgaumkar
  2026-09-02 15:48 ` [PATCH v7 2/2] perf: Add checks to prevent null ptr access Vinay Belgaumkar
  0 siblings, 2 replies; 5+ messages in thread
From: Vinay Belgaumkar @ 2026-09-02 15:48 UTC (permalink / raw)
  To: intel-xe; +Cc: dri-devel, Vinay Belgaumkar, Dapeng Mi

This series fixes a crash seen when the PMU ptr is freed while
there is an open perf connection.

v7: Minor fixes in commit message (Dapeng)

Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>

Vinay Belgaumkar (2):
  perf: Fix null pointer access in is_include_guest_event()
  perf: Add checks to prevent null ptr access

 kernel/events/core.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

-- 
2.38.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v7 1/2] perf: Fix null pointer access in is_include_guest_event()
  2026-09-02 15:48 [PATCH v7 0/2] perf: Add some null ptr checks Vinay Belgaumkar
@ 2026-09-02 15:48 ` Vinay Belgaumkar
  2026-09-03  1:50   ` Mi, Dapeng
  2026-09-02 15:48 ` [PATCH v7 2/2] perf: Add checks to prevent null ptr access Vinay Belgaumkar
  1 sibling, 1 reply; 5+ messages in thread
From: Vinay Belgaumkar @ 2026-09-02 15:48 UTC (permalink / raw)
  To: intel-xe; +Cc: dri-devel, Vinay Belgaumkar, Alexander Kanevskiy, Dapeng Mi

A typical module unload occurring event when there is an active perf
connection leads to freeing of the pmu pointer. The call log is something
like:
 ..
 __pmu_detach_event
 pmu_detach_event
 pmu_detach_events
 perf_pmu_unregister
 ..

__pmu_detach_event() sets event->pmu to null. When the perf connection
finally is closed, the following stack trace is observed:

 Oops: general protection fault, kernel NULL pointer dereference
 ...
 RIP: 0010:_free_event+0x3e/0x370
 ...
 Call Trace:
 ...
 perf_event_release_kernel+0x260/0x2d0
 perf_release+0x12/0x20

A call to mediated_pmu_unaccount_event() inside _free_event() is the root
cause of this crash. Adding a check inside is_include_guest_event() ensures
we don't accidentally access a null pmu ptr. In addition to this, we will
now call mediated_pmu_unaccount_event() before clearing the pmu ptr so that
nr_include_guest_events counts are maintained correctly.

v5: Improve commit message and split patch into 2 (Dapeng)

Fixes: eff95e170275 ("perf: Add APIs to create/release mediated guest vPMUs")
Cc: Alexander Kanevskiy <alexander.kanevskiy@intel.com>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Assisted-by: Claude:Claude-Sonnet-5
Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
---
 kernel/events/core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 94ca277e0819..f19d27ac411d 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6350,6 +6350,9 @@ static DEFINE_MUTEX(perf_mediated_pmu_mutex);
 /* !exclude_guest event of PMU with PERF_PMU_CAP_MEDIATED_VPMU */
 static inline bool is_include_guest_event(struct perf_event *event)
 {
+	if (!event->pmu)
+		return false;
+
 	if ((event->pmu->capabilities & PERF_PMU_CAP_MEDIATED_VPMU) &&
 	    !event->attr.exclude_guest)
 		return true;
@@ -12977,6 +12980,7 @@ static void __pmu_detach_event(struct pmu *pmu, struct perf_event *event,
 	exclusive_event_destroy(event);
 	module_put(pmu->module);
 
+	mediated_pmu_unaccount_event(event);
 	event->pmu = NULL; /* force fault instead of UAF */
 }
 
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v7 2/2] perf: Add checks to prevent null ptr access
  2026-09-02 15:48 [PATCH v7 0/2] perf: Add some null ptr checks Vinay Belgaumkar
  2026-09-02 15:48 ` [PATCH v7 1/2] perf: Fix null pointer access in is_include_guest_event() Vinay Belgaumkar
@ 2026-09-02 15:48 ` Vinay Belgaumkar
  2026-09-02 16:12   ` sashiko-bot
  1 sibling, 1 reply; 5+ messages in thread
From: Vinay Belgaumkar @ 2026-09-02 15:48 UTC (permalink / raw)
  To: intel-xe; +Cc: dri-devel, Vinay Belgaumkar, Dapeng Mi

Sashiko recommended some additional checks to prevent null pointer
access. Check for revoked states inside perf_event_read_local(), as
the pmu event may have already been freed at this point. Add a null
check inside __perf_event_read_cpu() as well before accessing the pmu
ptr.

Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
---
 kernel/events/core.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index f19d27ac411d..bb90034a2054 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4788,14 +4788,19 @@ static inline const struct cpumask *perf_scope_cpu_topology_cpumask(unsigned int
 
 static int __perf_event_read_cpu(struct perf_event *event, int event_cpu)
 {
+	struct pmu *pmu = READ_ONCE(event->pmu);
 	int local_cpu = smp_processor_id();
 	u16 local_pkg, event_pkg;
 
 	if ((unsigned)event_cpu >= nr_cpu_ids)
 		return event_cpu;
 
+	if (!pmu)
+		return -ENODEV;
+
 	if (event->group_caps & PERF_EV_CAP_READ_SCOPE) {
-		const struct cpumask *cpumask = perf_scope_cpu_topology_cpumask(event->pmu->scope, event_cpu);
+		const struct cpumask *cpumask = perf_scope_cpu_topology_cpumask(pmu->scope,
+										event_cpu);
 
 		if (cpumask && cpumask_test_cpu(local_cpu, cpumask))
 			return local_cpu;
@@ -4917,6 +4922,11 @@ int perf_event_read_local(struct perf_event *event, u64 *value,
 		goto out;
 	}
 
+	if (READ_ONCE(event->state) <= PERF_EVENT_STATE_REVOKED) {
+		ret = -ENODEV;
+		goto out;
+	}
+
 	/*
 	 * Get the event CPU numbers, and adjust them to local if the event is
 	 * a per-package event that can be read locally
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v7 2/2] perf: Add checks to prevent null ptr access
  2026-09-02 15:48 ` [PATCH v7 2/2] perf: Add checks to prevent null ptr access Vinay Belgaumkar
@ 2026-09-02 16:12   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-09-02 16:12 UTC (permalink / raw)
  To: Vinay Belgaumkar; +Cc: intel-xe, dri-devel

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [Critical] The added NULL and state checks do not fully resolve the Time-of-Check to Time-of-Use (TOCTOU) race condition against PMU unregistration, leaving NULL pointer dereference and Use-After-Free (UAF) vulnerabilities.
--

commit 63da6f63d2cf2058c6cbd31229c510f17f749641
Author: Vinay Belgaumkar <vinay.belgaumkar@intel.com>

perf: Add checks to prevent null ptr access

This patch attempts to prevent null pointer accesses by adding revoked
state checks in perf_event_read_local() and null checks in
__perf_event_read_cpu().

> diff --git a/kernel/events/core.c b/kernel/events/core.c
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c

[ ... ]

> @@ -4788,14 +4788,19 @@ static inline const struct cpumask *perf_scope_cpu_topology_cpumask(unsigned int
>  
>  static int __perf_event_read_cpu(struct perf_event *event, int event_cpu)
>  {
> +	struct pmu *pmu = READ_ONCE(event->pmu);
>  	int local_cpu = smp_processor_id();
>  	u16 local_pkg, event_pkg;
>  
>  	if ((unsigned)event_cpu >= nr_cpu_ids)
>  		return event_cpu;
>  
> +	if (!pmu)
> +		return -ENODEV;
> +
>  	if (event->group_caps & PERF_EV_CAP_READ_SCOPE) {
> -		const struct cpumask *cpumask = perf_scope_cpu_topology_cpumask(event->pmu->scope, event_cpu);
> +		const struct cpumask *cpumask = perf_scope_cpu_topology_cpumask(pmu->scope,
> +										event_cpu);

[Severity: Critical]
This is a pre-existing issue, but does reading pmu->scope here leave us
vulnerable to a use-after-free if the PMU object is concurrently freed?

Since we only read the pointer with READ_ONCE() and do not appear to be
holding RCU or a lock protecting the PMU's lifetime against unregistration,
could the PMU be detached and freed right before we access it?

[ ... ]

> @@ -4917,6 +4922,11 @@ int perf_event_read_local(struct perf_event *event, u64 *value,
>  		goto out;
>  	}
>  
> +	if (READ_ONCE(event->state) <= PERF_EVENT_STATE_REVOKED) {
> +		ret = -ENODEV;
> +		goto out;
> +	}
> +

[Severity: Critical]
This isn't a bug introduced by this patch, but does this state check fully
resolve the time-of-check to time-of-use race condition against PMU
unregistration?

If a userspace program triggers a BPF map update on a perf event array, it
calls perf_event_read_local() without holding rcu_read_lock(). If a concurrent
hardware hot-unplug calls perf_pmu_unregister(), it might issue an IPI to a
remote CPU to detach the event while this local CPU passes the revoked state
check.

If that race occurs, the PMU can be freed immediately after this check, but
further down in perf_event_read_local() we still directly dereference
event->pmu:

    if (event_oncpu == smp_processor_id())
        event->pmu->read(event);

Could this lead to a NULL pointer dereference or use-after-free since the
local IRQ disable doesn't serialize against the remote IPI during PMU
unregistration?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902154852.742844-1-vinay.belgaumkar@intel.com?part=2

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v7 1/2] perf: Fix null pointer access in is_include_guest_event()
  2026-09-02 15:48 ` [PATCH v7 1/2] perf: Fix null pointer access in is_include_guest_event() Vinay Belgaumkar
@ 2026-09-03  1:50   ` Mi, Dapeng
  0 siblings, 0 replies; 5+ messages in thread
From: Mi, Dapeng @ 2026-09-03  1:50 UTC (permalink / raw)
  To: Vinay Belgaumkar, intel-xe; +Cc: dri-devel, Alexander Kanevskiy


On 9/2/2026 11:48 PM, Vinay Belgaumkar wrote:
> A typical module unload occurring event when there is an active perf
> connection leads to freeing of the pmu pointer. The call log is something
> like:
>  ..
>  __pmu_detach_event
>  pmu_detach_event
>  pmu_detach_events
>  perf_pmu_unregister
>  ..
>
> __pmu_detach_event() sets event->pmu to null. When the perf connection
> finally is closed, the following stack trace is observed:
>
>  Oops: general protection fault, kernel NULL pointer dereference
>  ...
>  RIP: 0010:_free_event+0x3e/0x370
>  ...
>  Call Trace:
>  ...
>  perf_event_release_kernel+0x260/0x2d0
>  perf_release+0x12/0x20
>
> A call to mediated_pmu_unaccount_event() inside _free_event() is the root
> cause of this crash. Adding a check inside is_include_guest_event() ensures
> we don't accidentally access a null pmu ptr. In addition to this, we will
> now call mediated_pmu_unaccount_event() before clearing the pmu ptr so that
> nr_include_guest_events counts are maintained correctly.
>
> v5: Improve commit message and split patch into 2 (Dapeng)

Please remove this history info when you send to the patches to upstream
community.

Others look good to me.


>
> Fixes: eff95e170275 ("perf: Add APIs to create/release mediated guest vPMUs")
> Cc: Alexander Kanevskiy <alexander.kanevskiy@intel.com>
> Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
> Assisted-by: Claude:Claude-Sonnet-5
> Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
> ---
>  kernel/events/core.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 94ca277e0819..f19d27ac411d 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -6350,6 +6350,9 @@ static DEFINE_MUTEX(perf_mediated_pmu_mutex);
>  /* !exclude_guest event of PMU with PERF_PMU_CAP_MEDIATED_VPMU */
>  static inline bool is_include_guest_event(struct perf_event *event)
>  {
> +	if (!event->pmu)
> +		return false;
> +
>  	if ((event->pmu->capabilities & PERF_PMU_CAP_MEDIATED_VPMU) &&
>  	    !event->attr.exclude_guest)
>  		return true;
> @@ -12977,6 +12980,7 @@ static void __pmu_detach_event(struct pmu *pmu, struct perf_event *event,
>  	exclusive_event_destroy(event);
>  	module_put(pmu->module);
>  
> +	mediated_pmu_unaccount_event(event);
>  	event->pmu = NULL; /* force fault instead of UAF */
>  }
>  

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-09-03  1:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 15:48 [PATCH v7 0/2] perf: Add some null ptr checks Vinay Belgaumkar
2026-09-02 15:48 ` [PATCH v7 1/2] perf: Fix null pointer access in is_include_guest_event() Vinay Belgaumkar
2026-09-03  1:50   ` Mi, Dapeng
2026-09-02 15:48 ` [PATCH v7 2/2] perf: Add checks to prevent null ptr access Vinay Belgaumkar
2026-09-02 16:12   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox