This patch series addresses a class of Use-After-Free vulnerabilities in the virtio_balloon driver that can occur during system power management freeze (e.g., suspend or hibernation).
The core issue is a lifecycle mismatch: when the system enters freeze, virtballoon_freeze() resets the virtio device and deletes its virtqueues. However, several asynchronous or event-driven components of the driver and related subsystems (Free Page Reporting and Shrinker) remain registered and active. If they trigger during the freeze/suspend process, they attempt to access the now-deleted virtqueues, causing kernel crashes (General Protection Faults or UAF). To fix this: 1. Migrate Free Page Reporting to use the system_freezable_wq, ensuring its worker is frozen before driver freeze callbacks run. (Suggested by David Hildenbrand). 2. Avoid shrinker execution while the device is suspended by adding a suspended flag to struct virtio_balloon. Wrap lockless reads of this flag in READ_ONCE() and writes in WRITE_ONCE() to prevent data races and KCSAN warnings. Note: The OOM notifier (virtio_balloon_oom_notify) is also registered, but since the PM core disables the OOM killer (via oom_killer_disable()) during freeze_processes() before device drivers are frozen, it cannot trigger while the device is frozen. Thus, it does not require a fix. Testing: I have verified these fixes using Google’s virtualization infrastructure by running continuous suspend/resume iterations (40+ cycles) while churning memory using stress-ng (stress-ng --vm 4 --vm-bytes 60% --timeout 1) to constantly create free pages for the buddy allocator. We also set the page_reporting_order parameter to 0 to make the page reporting worker highly sensitive, forcing it to pick up any 4K free pages. This confirmed that the UAF crashes are no longer reproducible. RFC: https://lore.kernel.org/r/[email protected] --- RFC -> v2: - Switched page reporting fix from unregister/re-register in driver to using system_freezable_wq in mm/page_reporting.c, which avoids complex restore rollback logic for that component. - Switched shrinker fix from unregister/re-register to using a simple suspended boolean flag to avoid complex rollback logic. Wrap its reads and writes with READ_ONCE()/WRITE_ONCE() to prevent KCSAN data race warnings. - Dropped OOM notifier fix since it's already protected by the PM core's oom_killer_disable(). Link Lin (2): mm/page_reporting: use system_freezable_wq to fix UAF during suspend virtio_balloon: avoid shrinker execution during PM suspend drivers/virtio/virtio_balloon.c | 49 +++++++++++++++++++++++++++------ mm/page_reporting.c | 6 ++-- 2 files changed, 45 insertions(+), 10 deletions(-) -- 2.55.0.229.g6434b31f56-goog

