Re: [PATCH v2 1/2] mm/page_reporting: use system_freezable_wq to fix UAF during suspend

"Michael S. Tsirkin" <[email protected]>
Newsgroups dev.linux.lists.virtualization,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
On Fri, Jul 17, 2026 at 12:22:20AM +0000, Link Lin wrote:
> During PM freeze (e.g. S3 suspend or S4 hibernation), device drivers like
> virtio_balloon reset their underlying virtio devices and delete their
> virtqueues via vdev->config->del_vqs().
> 
> However, page reporting work (page_reporting_process) was scheduled on
> the global system_wq. Because system_wq lacks the WQ_FREEZABLE flag, the
> PM freezer skips it, leaving page_reporting_process active during
> suspend. If pages are freed into the buddy allocator while suspending,
> page reporting invokes virtballoon_free_page_report() on deleted
> virtqueues:
> 
>     [  196.795226] general protection fault, probably for non-canonical address 0xaa1436fe70dae6df: 0000 [#1] SMP NOPTI
>     [  196.825967] Workqueue: events page_reporting_process
>     [  196.831038] RIP: 0010:virtqueue_add_split+0x233/0x4c0 [virtio_ring]
>     [  196.927073] virtballoon_free_page_report+0x3a/0xe0 [virtio_balloon]
>     [  196.946943] page_reporting_process+0x370/0x4f0
> 
> Fix this by switching page reporting work to system_freezable_wq. This
> ensures that the PM freezer pauses page_reporting_process before device
> drivers destroy their reporting virtqueues.
> 
> This aligns with the driver's existing design. The comment in
> virtballoon_freeze() states:
>     /*
>      * The workqueue is already frozen by the PM core before this
>      * function is called.
>      */
> 
> Suggested-by: David Hildenbrand <[email protected]>
> Suggested-by: Michael S. Tsirkin <[email protected]>
> Acked-by: David Rientjes <[email protected]>
> Fixes: 924a663f75e2 ("virtio-balloon: Reporting free page reservations")
> Cc: [email protected]
> Signed-off-by: Link Lin <[email protected]>

Acked-by: Michael S. Tsirkin <[email protected]>

> ---
>  mm/page_reporting.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/mm/page_reporting.c b/mm/page_reporting.c
> index 7418f2e500..4dc6f4b852 100644
> --- a/mm/page_reporting.c
> +++ b/mm/page_reporting.c
> @@ -80,7 +80,8 @@ __page_reporting_request(struct page_reporting_dev_info *prdev)
>  	 * now we are limiting this to running no more than once every
>  	 * couple of seconds.
>  	 */
> -	schedule_delayed_work(&prdev->work, PAGE_REPORTING_DELAY);
> +	queue_delayed_work(system_freezable_wq, &prdev->work,
> +			   PAGE_REPORTING_DELAY);
>  }
>  
>  /* notify prdev of free page reporting request */
> @@ -343,7 +344,8 @@ static void page_reporting_process(struct work_struct *work)
>  	 */
>  	state = atomic_cmpxchg(&prdev->state, state, PAGE_REPORTING_IDLE);
>  	if (state == PAGE_REPORTING_REQUESTED)
> -		schedule_delayed_work(&prdev->work, PAGE_REPORTING_DELAY);
> +		queue_delayed_work(system_freezable_wq, &prdev->work,
> +				   PAGE_REPORTING_DELAY);
>  }
>  
>  static DEFINE_MUTEX(page_reporting_mutex);
> -- 
> 2.55.0.229.g6434b31f56-goog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.