Unverified Commit e65c0786 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11156 v3 Fix CVE-2024-43869

Merge Pull Request from: @ci-robot 
 
PR sync from: Li Huafei <lihuafei1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/RW6TUN2RANKIS5XQR4B72XX5BAB5QSNQ/ 
Frederic Weisbecker (1):
  perf: Fix event leak upon exec and file release

Li Huafei (1):
  perf: Fix kabi broken of struct perf_event


-- 
2.25.1
 
https://gitee.com/src-openeuler/kernel/issues/IALEPL 
 
Link:https://gitee.com/openeuler/kernel/pulls/11156

 

Reviewed-by: default avatarYe Weihua <yeweihua4@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents b6936487 cee27f61
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -851,7 +851,7 @@ struct perf_event {
	 */
	__u32				orig_type;

	KABI_RESERVE(1)
	KABI_USE(1, struct rcuwait pending_work_wait)
	KABI_RESERVE(2)
	KABI_RESERVE(3)
	KABI_RESERVE(4)
+34 −4
Original line number Diff line number Diff line
@@ -2288,7 +2288,6 @@ event_sched_out(struct perf_event *event, struct perf_event_context *ctx)
		if (state != PERF_EVENT_STATE_OFF &&
		    !event->pending_work &&
		    !task_work_add(current, &event->pending_task, TWA_RESUME)) {
			WARN_ON_ONCE(!atomic_long_inc_not_zero(&event->refcount));
			event->pending_work = 1;
		} else {
			local_dec(&event->ctx->nr_pending);
@@ -5172,9 +5171,35 @@ static bool exclusive_event_installable(struct perf_event *event,
static void perf_addr_filters_splice(struct perf_event *event,
				       struct list_head *head);

static void perf_pending_task_sync(struct perf_event *event)
{
	struct callback_head *head = &event->pending_task;

	if (!event->pending_work)
		return;
	/*
	 * If the task is queued to the current task's queue, we
	 * obviously can't wait for it to complete. Simply cancel it.
	 */
	if (task_work_cancel(current, head)) {
		event->pending_work = 0;
		local_dec(&event->ctx->nr_pending);
		return;
	}

	/*
	 * All accesses related to the event are within the same
	 * non-preemptible section in perf_pending_task(). The RCU
	 * grace period before the event is freed will make sure all
	 * those accesses are complete by then.
	 */
	rcuwait_wait_event(&event->pending_work_wait, !event->pending_work, TASK_UNINTERRUPTIBLE);
}

static void _free_event(struct perf_event *event)
{
	irq_work_sync(&event->pending_irq);
	perf_pending_task_sync(event);

	unaccount_event(event);

@@ -6807,24 +6832,28 @@ static void perf_pending_task(struct callback_head *head)
	struct perf_event *event = container_of(head, struct perf_event, pending_task);
	int rctx;

	/*
	 * All accesses to the event must belong to the same implicit RCU read-side
	 * critical section as the ->pending_work reset. See comment in
	 * perf_pending_task_sync().
	 */
	preempt_disable_notrace();
	/*
	 * If we 'fail' here, that's OK, it means recursion is already disabled
	 * and we won't recurse 'further'.
	 */
	preempt_disable_notrace();
	rctx = perf_swevent_get_recursion_context();

	if (event->pending_work) {
		event->pending_work = 0;
		perf_sigtrap(event);
		local_dec(&event->ctx->nr_pending);
		rcuwait_wake_up(&event->pending_work_wait);
	}

	if (rctx >= 0)
		perf_swevent_put_recursion_context(rctx);
	preempt_enable_notrace();

	put_event(event);
}

#ifdef CONFIG_GUEST_PERF_EVENTS
@@ -11934,6 +11963,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
	init_waitqueue_head(&event->waitq);
	init_irq_work(&event->pending_irq, perf_pending_irq);
	init_task_work(&event->pending_task, perf_pending_task);
	rcuwait_init(&event->pending_work_wait);

	mutex_init(&event->mmap_mutex);
	raw_spin_lock_init(&event->addr_filters.lock);