* [PATCH 6.6.y 0/2] fbdev: backport CVE-2025-21976
@ 2026-10-08 19:13 Artem Dinaburg
2026-10-08 19:13 ` [PATCH 6.6.y 1/2] fbdev: hyperv_fb: Simplify hvfb_putmem Artem Dinaburg
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Artem Dinaburg @ 2026-10-08 19:13 UTC (permalink / raw)
To: stable
Cc: Artem Dinaburg, Greg Kroah-Hartman, Sasha Levin, Saurabh Sengar,
Michael Kelley, Wei Liu, K. Y. Srinivasan, Haiyang Zhang,
Dexuan Cui, Helge Deller, linux-hyperv, linux-fbdev, dri-devel,
linux-kernel, akpm
Hi Greg, Sasha, and maintainers,
I'm working through the smaller CVE backports still missing from 6.6.y.
These 2 upstream changes belong together for CVE-2025-21976. They must be
applied in this order because the later change depends on or completes the
earlier one.
The complete series is already present in 6.12.y, 6.18.y, and 7.2.y.
These fixes also affect 6.1.y, which will need a separate backport; this
series is only for 6.6.y.
Could you please consider this series for 6.6.y?
Thanks,
Artem Dinaburg
Series:
1. fbdev: hyperv_fb: Simplify hvfb_putmem
2. fbdev: hyperv_fb: Allow graceful removal of framebuffer
base: v6.6.157 (79643295eba17affbd16ca97f3ef04c90266b28c) plus stable-queue
revision 958ddf240a33ef26b1771be944f0ea6c3b597472
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 6.6.y 1/2] fbdev: hyperv_fb: Simplify hvfb_putmem
2026-10-08 19:13 [PATCH 6.6.y 0/2] fbdev: backport CVE-2025-21976 Artem Dinaburg
@ 2026-10-08 19:13 ` Artem Dinaburg
2026-10-08 19:24 ` sashiko-bot
2026-10-08 19:13 ` [PATCH 6.6.y 2/2] fbdev: hyperv_fb: Allow graceful removal of framebuffer Artem Dinaburg
2026-10-09 17:09 ` [PATCH 6.6.y 0/2] fbdev: backport CVE-2025-21976 Sasha Levin
2 siblings, 1 reply; 6+ messages in thread
From: Artem Dinaburg @ 2026-10-08 19:13 UTC (permalink / raw)
To: stable
Cc: Artem Dinaburg, Greg Kroah-Hartman, Sasha Levin, Saurabh Sengar,
Michael Kelley, Wei Liu, K. Y. Srinivasan, Haiyang Zhang,
Dexuan Cui, Helge Deller, linux-hyperv, linux-fbdev, dri-devel,
linux-kernel
From: Saurabh Sengar <ssengar@linux.microsoft.com>
[ Upstream commit f5e728a50bb17336a20803dde488515b833ecd1d ]
The device object required in 'hvfb_release_phymem' function
for 'dma_free_coherent' can also be obtained from the 'info'
pointer, making 'hdev' parameter in 'hvfb_putmem' redundant.
Remove the unnecessary 'hdev' argument from 'hvfb_putmem'.
[ Backport to 6.6.y: Pass info->device through the target's
hvfb_release_phymem() helper and remove the now-redundant hdev
argument from each hvfb_putmem() call. ]
Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Tested-by: Michael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/r/1740845791-19977-2-git-send-email-ssengar@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Message-ID: <1740845791-19977-2-git-send-email-ssengar@linux.microsoft.com>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
---
This is patch 1 of 2 in the ordered 6.6.y backport series.
This is the prerequisite needed for the CVE-2025-21976 backport. Makes
hvfb_putmem() derive the device from fb_info, which permits the following
fix to move framebuffer-memory release into fb_destroy() and honor
outstanding open references.
The fix is already present in 6.12.y, 6.18.y, and 7.2.y, but not in 6.6.y.
This fix also affects 6.1.y, which will need a separate backport; this
submission contains only the 6.6.y patch.
drivers/video/fbdev/hyperv_fb.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index 80e8ec36b7db..80e6d9682179 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -973,7 +973,7 @@ static phys_addr_t hvfb_get_phymem(struct hv_device *hdev,
}
/* Release contiguous physical memory */
-static void hvfb_release_phymem(struct hv_device *hdev,
+static void hvfb_release_phymem(struct device *device,
phys_addr_t paddr, unsigned int size)
{
unsigned int order = get_order(size);
@@ -981,7 +981,7 @@ static void hvfb_release_phymem(struct hv_device *hdev,
if (order <= MAX_ORDER)
__free_pages(pfn_to_page(paddr >> PAGE_SHIFT), order);
else
- dma_free_coherent(&hdev->device,
+ dma_free_coherent(device,
round_up(size, PAGE_SIZE),
phys_to_virt(paddr),
paddr);
@@ -1100,7 +1100,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
}
/* Release the framebuffer */
-static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
+static void hvfb_putmem(struct fb_info *info)
{
struct hvfb_par *par = info->par;
@@ -1109,7 +1109,7 @@ static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
iounmap(par->mmio_vp);
vmbus_free_mmio(par->mem->start, screen_fb_size);
} else {
- hvfb_release_phymem(hdev, info->fix.smem_start,
+ hvfb_release_phymem(info->device, info->fix.smem_start,
screen_fb_size);
}
@@ -1223,7 +1223,7 @@ static int hvfb_probe(struct hv_device *hdev,
error:
fb_deferred_io_cleanup(info);
- hvfb_putmem(hdev, info);
+ hvfb_putmem(info);
error2:
vmbus_close(hdev->channel);
error1:
@@ -1252,7 +1252,7 @@ static void hvfb_remove(struct hv_device *hdev)
vmbus_close(hdev->channel);
hv_set_drvdata(hdev, NULL);
- hvfb_putmem(hdev, info);
+ hvfb_putmem(info);
framebuffer_release(info);
}
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.6.y 2/2] fbdev: hyperv_fb: Allow graceful removal of framebuffer
2026-10-08 19:13 [PATCH 6.6.y 0/2] fbdev: backport CVE-2025-21976 Artem Dinaburg
2026-10-08 19:13 ` [PATCH 6.6.y 1/2] fbdev: hyperv_fb: Simplify hvfb_putmem Artem Dinaburg
@ 2026-10-08 19:13 ` Artem Dinaburg
2026-10-08 19:24 ` sashiko-bot
2026-10-09 17:09 ` [PATCH 6.6.y 0/2] fbdev: backport CVE-2025-21976 Sasha Levin
2 siblings, 1 reply; 6+ messages in thread
From: Artem Dinaburg @ 2026-10-08 19:13 UTC (permalink / raw)
To: stable
Cc: Artem Dinaburg, Greg Kroah-Hartman, Sasha Levin, Saurabh Sengar,
Michael Kelley, Wei Liu, K. Y. Srinivasan, Haiyang Zhang,
Dexuan Cui, Helge Deller, linux-hyperv, linux-fbdev, dri-devel,
linux-kernel, akpm
From: Saurabh Sengar <ssengar@linux.microsoft.com>
[ Upstream commit ea2f45ab0e53b255f72c85ccd99e2b394fc5fceb ]
When a Hyper-V framebuffer device is unbind, hyperv_fb driver tries to
release the framebuffer forcefully. If this framebuffer is in use it
produce the following WARN and hence this framebuffer is never released.
[ 44.111220] WARNING: CPU: 35 PID: 1882 at drivers/video/fbdev/core/fb_info.c:70 framebuffer_release+0x2c/0x40
< snip >
[ 44.111289] Call Trace:
[ 44.111290] <TASK>
[ 44.111291] ? show_regs+0x6c/0x80
[ 44.111295] ? __warn+0x8d/0x150
[ 44.111298] ? framebuffer_release+0x2c/0x40
[ 44.111300] ? report_bug+0x182/0x1b0
[ 44.111303] ? handle_bug+0x6e/0xb0
[ 44.111306] ? exc_invalid_op+0x18/0x80
[ 44.111308] ? asm_exc_invalid_op+0x1b/0x20
[ 44.111311] ? framebuffer_release+0x2c/0x40
[ 44.111313] ? hvfb_remove+0x86/0xa0 [hyperv_fb]
[ 44.111315] vmbus_remove+0x24/0x40 [hv_vmbus]
[ 44.111323] device_remove+0x40/0x80
[ 44.111325] device_release_driver_internal+0x20b/0x270
[ 44.111327] ? bus_find_device+0xb3/0xf0
Fix this by moving the release of framebuffer and assosiated memory
to fb_ops.fb_destroy function, so that framebuffer framework handles
it gracefully.
While we fix this, also replace manual registrations/unregistration of
framebuffer with devm_register_framebuffer.
[ Backport to 6.6.y: retain explicit unregister_framebuffer(), but call it
only after delayed work and the VMBus channel are shut down; defer
hvfb_putmem()/framebuffer_release() to fb_destroy. This preserves the
upstream teardown order without requiring devm_register_framebuffer(). ]
Fixes: 68a2d20b79b1 ("drivers/video: add Hyper-V Synthetic Video Frame Buffer Driver")
Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Tested-by: Michael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/r/1740845791-19977-3-git-send-email-ssengar@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Message-ID: <1740845791-19977-3-git-send-email-ssengar@linux.microsoft.com>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
---
This is patch 2 of 2 in the ordered 6.6.y backport series.
This change addresses CVE-2025-21976. The target remove path unregisters the
framebuffer before completing driver cleanup and then directly frees its
memory even when another open reference keeps the framebuffer alive.
This needed a target-specific adjustment; I called it out in the bracketed
backport note above.
The fix is already present in 6.12.y, 6.18.y, and 7.2.y, but not in 6.6.y.
This fix also affects 6.1.y, which will need a separate backport; this
submission contains only the 6.6.y patch.
drivers/video/fbdev/hyperv_fb.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index 80e6d9682179..e0d68953aa1a 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -283,6 +283,8 @@ static uint screen_depth;
static uint screen_fb_size;
static uint dio_fb_size; /* FB size for deferred IO */
+static void hvfb_putmem(struct fb_info *info);
+
/* Send message to Hyper-V host */
static inline int synthvid_send(struct hv_device *hdev,
struct synthvid_msg *msg)
@@ -887,6 +889,17 @@ static void hvfb_cfb_imageblit(struct fb_info *p,
image->width, image->height);
}
+/*
+ * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
+ * of unregister_framebuffer() or fb_release(). Do any cleanup related to
+ * framebuffer here.
+ */
+static void hvfb_destroy(struct fb_info *info)
+{
+ hvfb_putmem(info);
+ framebuffer_release(info);
+}
+
static const struct fb_ops hvfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = hvfb_check_var,
@@ -897,6 +910,7 @@ static const struct fb_ops hvfb_ops = {
.fb_imageblit = hvfb_cfb_imageblit,
.fb_blank = hvfb_blank,
.fb_mmap = fb_deferred_io_mmap,
+ .fb_destroy = hvfb_destroy,
};
@@ -1246,14 +1260,11 @@ static void hvfb_remove(struct hv_device *hdev)
fb_deferred_io_cleanup(info);
- unregister_framebuffer(info);
cancel_delayed_work_sync(&par->dwork);
vmbus_close(hdev->channel);
hv_set_drvdata(hdev, NULL);
-
- hvfb_putmem(info);
- framebuffer_release(info);
+ unregister_framebuffer(info);
}
static int hvfb_suspend(struct hv_device *hdev)
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 6.6.y 1/2] fbdev: hyperv_fb: Simplify hvfb_putmem
2026-10-08 19:13 ` [PATCH 6.6.y 1/2] fbdev: hyperv_fb: Simplify hvfb_putmem Artem Dinaburg
@ 2026-10-08 19:24 ` sashiko-bot
0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-10-08 19:24 UTC (permalink / raw)
To: Artem Dinaburg; +Cc: dri-devel, linux-hyperv
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] fbdev: hyperv_fb: Use-After-Free in dma_free_coherent via deferred fb_destroy
--
commit 5cd0184cceb2674876a9c7e3d72e937d61e3e2d8
Author: Saurabh Sengar <ssengar@linux.microsoft.com>
fbdev: hyperv_fb: Simplify hvfb_putmem
This commit simplifies hvfb_putmem() by removing its hdev parameter. It
derives the device from fb_info and passes it to hvfb_release_phymem()
instead.
Link: https://lore.kernel.org/r/1740845791-19977-2-git-send-email-ssengar@linux.microsoft.com
> diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
> index 80e8ec36b7db2..80e6d96821795 100644
> --- a/drivers/video/fbdev/hyperv_fb.c
> +++ b/drivers/video/fbdev/hyperv_fb.c
> @@ -973,7 +973,7 @@ static phys_addr_t hvfb_get_phymem(struct hv_device *hdev,
> }
>
> /* Release contiguous physical memory */
> -static void hvfb_release_phymem(struct hv_device *hdev,
> +static void hvfb_release_phymem(struct device *device,
> phys_addr_t paddr, unsigned int size)
> {
> unsigned int order = get_order(size);
> @@ -981,7 +981,7 @@ static void hvfb_release_phymem(struct hv_device *hdev,
> if (order <= MAX_ORDER)
> __free_pages(pfn_to_page(paddr >> PAGE_SHIFT), order);
> else
> - dma_free_coherent(&hdev->device,
> + dma_free_coherent(device,
> round_up(size, PAGE_SIZE),
> phys_to_virt(paddr),
> paddr);
[ ... ]
> @@ -1100,7 +1100,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
> }
>
> /* Release the framebuffer */
> -static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
> +static void hvfb_putmem(struct fb_info *info)
> {
> struct hvfb_par *par = info->par;
>
> @@ -1109,7 +1109,7 @@ static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
> iounmap(par->mmio_vp);
> vmbus_free_mmio(par->mem->start, screen_fb_size);
> } else {
> - hvfb_release_phymem(hdev, info->fix.smem_start,
> + hvfb_release_phymem(info->device, info->fix.smem_start,
> screen_fb_size);
> }
[Severity: High]
Can this change lead to dma_free_coherent() in drivers/video/fbdev/hyperv_fb.c
dereferencing a freed device pointer when executed from a deferred fb_destroy()
callback?
Moving framebuffer memory teardown, via hvfb_putmem(), to the asynchronous
fb_destroy() callback causes it to execute when the last userspace reference
is dropped.
If /dev/fb0 is held open by a user process when the Hyper-V device is removed
or unbound, the driver's remove() callback unregisters the framebuffer and
returns. At this point, the driver core drops the final reference to the
parent hv_device and frees it.
Later, when the user process closes the file descriptor, fb_destroy() invokes
hvfb_putmem(), which calls dma_free_coherent() using info->device. This points
to the now-freed &hdev->device.
Because dma_free_coherent() dereferences this device pointer to access dma_ops,
does this result in a concrete use-after-free and likely a kernel panic?
Checking the final state of the series reveals no get_device(&hdev->device)
was added to ensure the device outlives the fb_info.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261008191309.98263-1-artem@trailofbits.com?part=1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 6.6.y 2/2] fbdev: hyperv_fb: Allow graceful removal of framebuffer
2026-10-08 19:13 ` [PATCH 6.6.y 2/2] fbdev: hyperv_fb: Allow graceful removal of framebuffer Artem Dinaburg
@ 2026-10-08 19:24 ` sashiko-bot
0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-10-08 19:24 UTC (permalink / raw)
To: Artem Dinaburg; +Cc: dri-devel, linux-hyperv
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] workqueue: UAF of delayed work due to re-arming during teardown
- [High] vmbus: NULL pointer dereference on closed channel during fbdev ioctl
- [High] fbdev: UAF of parent device pointer in hvfb_destroy()
--
commit 0b97ae630048a0b4a041222965b966a2373daa70
Author: Saurabh Sengar <ssengar@linux.microsoft.com>
fbdev: hyperv_fb: Allow graceful removal of framebuffer
This commit defers the release of the framebuffer memory to the fb_ops
fb_destroy callback to prevent warnings when unbinding an in-use
framebuffer. It also moves the unregister_framebuffer call to the end of
hvfb_remove() and places it after vmbus_close().
Link: https://lore.kernel.org/r/1740845791-19977-3-git-send-email-ssengar@linux.microsoft.com
> diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
> index 80e6d96821795..e0d68953aa1ac 100644
> --- a/drivers/video/fbdev/hyperv_fb.c
> +++ b/drivers/video/fbdev/hyperv_fb.c
[ ... ]
> @@ -887,6 +889,17 @@ static void hvfb_cfb_imageblit(struct fb_info *p,
> image->width, image->height);
> }
>
> +/*
> + * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
> + * of unregister_framebuffer() or fb_release(). Do any cleanup related to
> + * framebuffer here.
> + */
> +static void hvfb_destroy(struct fb_info *info)
> +{
> + hvfb_putmem(info);
[Severity: High]
Is it safe to defer hvfb_putmem() to the fb_destroy callback?
hvfb_putmem() calls hvfb_release_phymem(info->device, ...), but info->device
points to the hdev->device. The VMBus core unregisters and frees the hv_device
(hdev) when hvfb_remove() completes.
If userspace keeps the framebuffer file descriptor open, hvfb_destroy() will
execute later. Does this mean info->device will be a dangling pointer when
passed to dma_free_coherent() in hvfb_release_phymem(), causing a
Use-After-Free?
> + framebuffer_release(info);
> +}
> +
> static const struct fb_ops hvfb_ops = {
> .owner = THIS_MODULE,
> .fb_check_var = hvfb_check_var,
[ ... ]
> @@ -1246,14 +1260,11 @@ static void hvfb_remove(struct hv_device *hdev)
>
> fb_deferred_io_cleanup(info);
>
> - unregister_framebuffer(info);
> cancel_delayed_work_sync(&par->dwork);
[Severity: High]
Since unregister_framebuffer() is called after this point, is it possible for
concurrent fbcon console updates or user operations to re-arm the work item?
For instance, could a call to hvfb_cfb_fillrect() ->
hvfb_ondemand_refresh_throttle() unconditionally re-arm the delayed work while
the device is shutting down, leading to a Use-After-Free of the par structure
when the delayed work eventually executes?
>
> vmbus_close(hdev->channel);
[Severity: High]
Does moving vmbus_close() before unregister_framebuffer() expose a race
condition where the VMBus channel and its ring buffers are freed while the
framebuffer interface is still fully active?
A concurrent user ioctl(FBIOPUT_VSCREENINFO) or active fbcon operation could
invoke synthvid_send() -> vmbus_sendpacket(). If vmbus_sendpacket() tries to
access the closed channel and its NULL ring_buffer structure, would this result
in a NULL pointer dereference?
> hv_set_drvdata(hdev, NULL);
> -
> - hvfb_putmem(info);
> - framebuffer_release(info);
> + unregister_framebuffer(info);
> }
>
> static int hvfb_suspend(struct hv_device *hdev)
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261008191309.98263-1-artem@trailofbits.com?part=2
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 6.6.y 0/2] fbdev: backport CVE-2025-21976
2026-10-08 19:13 [PATCH 6.6.y 0/2] fbdev: backport CVE-2025-21976 Artem Dinaburg
2026-10-08 19:13 ` [PATCH 6.6.y 1/2] fbdev: hyperv_fb: Simplify hvfb_putmem Artem Dinaburg
2026-10-08 19:13 ` [PATCH 6.6.y 2/2] fbdev: hyperv_fb: Allow graceful removal of framebuffer Artem Dinaburg
@ 2026-10-09 17:09 ` Sasha Levin
2 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-10-09 17:09 UTC (permalink / raw)
To: stable
Cc: Sasha Levin, Artem Dinaburg, Greg Kroah-Hartman, Saurabh Sengar,
Michael Kelley, Wei Liu, K. Y. Srinivasan, Haiyang Zhang,
Dexuan Cui, Helge Deller, linux-hyperv, linux-fbdev, dri-devel,
linux-kernel, akpm
> Could you please consider this series for 6.6.y?
Queued the series for 6.6, thanks.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-09 17:10 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-08 19:13 [PATCH 6.6.y 0/2] fbdev: backport CVE-2025-21976 Artem Dinaburg
2026-10-08 19:13 ` [PATCH 6.6.y 1/2] fbdev: hyperv_fb: Simplify hvfb_putmem Artem Dinaburg
2026-10-08 19:24 ` sashiko-bot
2026-10-08 19:13 ` [PATCH 6.6.y 2/2] fbdev: hyperv_fb: Allow graceful removal of framebuffer Artem Dinaburg
2026-10-08 19:24 ` sashiko-bot
2026-10-09 17:09 ` [PATCH 6.6.y 0/2] fbdev: backport CVE-2025-21976 Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox