Conversation
jira VULN-136703 cve-pre CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit 37408cd Implement helpers drm_gem_fb_begin_cpu_access() and _end_cpu_access(), which call the rsp dma-buf functions for all GEM BOs of the given framebuffer. Calls to dma_buf_end_cpu_access() can return an error code on failure, while drm_gem_fb_end_cpu_access() does not. The latter runs during DRM's atomic commit or during cleanup. Both cases don't allow for errors, so leave out the return value. v2: * fix typo in docs (Daniel) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Noralf Trønnes <noralf@tronnes.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210716140801.1215-2-tzimmermann@suse.de (cherry picked from commit 37408cd) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-136703 cve-pre CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit 279cc2e DRM uses a magic number of 4 for the maximum number of planes per color format. Declare this constant via DRM_FORMAT_MAX_PLANES and update the related code. Some code depends on the length of arrays that are now declared with DRM_FORMAT_MAX_PLANES. Convert it from '4' to ARRAY_SIZE. v2: * mention usage of ARRAY_SIZE() in the commit message (Maxime) * also fix error handling in drm_gem_fb_init_with_funcs() (kernel test robot) * include <drm/drm_fourcc.h> for DRM_FORMAT_MAX_PLANES Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210730183511.20080-2-tzimmermann@suse.de (cherry picked from commit 279cc2e) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-136703 cve-pre CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit f6424ec Move framebuffer vmap code from shadow-buffered plane state into the new interfaces drm_gem_fb_vmap() and drm_gem_fb_vunmap(). These functions provide mappings of a framebuffer's BOs into kernel address space. No functional changes. v4: * remove duplicated blank line v2: * using [static N] for array parameters enables compile-time checks * include <drm/drm_fourcc.h> for DRM_FORMAT_MAX_PLANES (kernel test robot) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210730183511.20080-3-tzimmermann@suse.de (cherry picked from commit f6424ec) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-136703 cve-pre CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit 0ec77bd Set the returned mapping address to NULL if a framebuffer plane does not have a BO associated with it. Likewise, ignore mappings of NULL during framebuffer unmap operations. Allows users of the functions to perform unmap operations of certain BOs by themselfes. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210730183511.20080-4-tzimmermann@suse.de (cherry picked from commit 0ec77bd) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-136703 cve-pre CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit 0029d31 upstream-diff Included drm/drm_gem_framebuffer_helper.h which was incorporated in 08b7ef0 on upstream, not backported to LTS 8.6. It was needed for the newly used functions `drm_gem_fb_vmap()' and `drm_gem_fb_vunmap()' Abstract the framebuffer details by mapping its BOs with a call to drm_gem_fb_vmap(). Unmap with drm_gem_fb_vunmap(). The call to drm_gem_fb_vmap() ensures that all BOs are mapped correctly. Gud still only supports single-plane formats. No functional changes. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Noralf Trønnes <noralf@tronnes.org> Acked-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210730183511.20080-5-tzimmermann@suse.de (cherry picked from commit 0029d31) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-136703 cve-pre CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit 50fff20 upstream-diff Included drm/drm_gem_atomic_helper.h in drivers/gpu/drm/vkms/vkms_drv.h, which was done on upstream in 7602d42, not backported to LTS 8.6. It was needed for the definition of `dma_buf_map'. Abstract the framebuffer details by mappings its BOs with a call to drm_gem_fb_vmap(). Unmap with drm_gem_fb_vunamp(). Before, the output address with stored as raw pointer in the priv field of struct drm_writeback_job. Introduce the new type struct vkms_writeback_job, which holds the output mappings addresses while the writeback job is active. The patchset also cleans up some internal casting an setup of the output addresses. No functional changes. v3: * free instances of struct vkms_writeback_job on cleanup or errors Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Acked-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210730183511.20080-6-tzimmermann@suse.de (cherry picked from commit 50fff20) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-136703 cve-pre CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit 43b3623 Add an additional argument to drm_gem_fb_vmap() to return each BO's mapping adjusted by the respective offset. Update all callers. The newly returned values point to the first byite of the data stored in the framebuffer BOs. Drivers that access the BO data should use it. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210803125928.27780-2-tzimmermann@suse.de (cherry picked from commit 43b3623) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-136703 cve-pre CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit f159b1b The error-recovery code in drm_gem_fb_begin() is of the same pattern as drm_gem_fb_end(). Implement both of them using an internal helper. No functional changes. v2: * print additional information in error message (Javier) * fix commit description (Javier) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Tested-by: Noralf Trønnes <noralf@tronnes.org> Acked-by: Christian König <christian.koenig@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220517113327.26919-2-tzimmermann@suse.de (cherry picked from commit f159b1b) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-136703 cve-pre CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit 746b9c6 upstream-diff | drivers/gpu/drm/drm_gem_atomic_helper.c Ignored the change to `drm_gem_plane_helper_prepare_fb()' function. They are relevant to the functional change introduced in 1ea28bc ("drm: handle kernel fences in drm_gem_plane_helper_prepare_fb v2"), which is missing from LTS 8.6 drivers/gpu/drm/drm_gem_framebuffer_helper.c Used the existing `dma_buf_map' name of the struct instead of `iosys_map'. The struct renaming was done in 7938f42 ("dma-buf-map: Rename to iosys-map"), missing from LTS 8.6. It cannot be backported due to its scope, also the change it introduces is purely syntactic and can be corrected for easily. include/drm/drm_gem_framebuffer_helper.h Same as above. Only handle color planes that exist in a framebuffer's color format. Ignore non-existing planes. So far, several helpers assumed that all 4 planes are available and silently ignored non-existing planes. This lead to subtil bugs with uninitialized data in instances of struct iosys_map. [1] Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Tested-by: Noralf Trønnes <noralf@tronnes.org> Acked-by: Christian König <christian.koenig@amd.com> Link: https://lore.kernel.org/dri-devel/20210730183511.20080-1-tzimmermann@suse.de/T/#md0172b10bb588d8f20f4f456e304f08d2a4505f7 # 1 Link: https://patchwork.freedesktop.org/patch/msgid/20220517113327.26919-3-tzimmermann@suse.de (cherry picked from commit 746b9c6) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-136703 cve CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit 5307dce upstream-diff In `drm_gem_object_handle_get_unlocked()' used `mutex_lock()' and `mutex_unlock()' instead of `guard()' - it was introduced in 54da6a0 ("locking: Introduce __cleanup() based infrastructure"), not backported to LTS 8.6. A GEM handle can be released while the GEM buffer object is attached to a DRM framebuffer. This leads to the release of the dma-buf backing the buffer object, if any. [1] Trying to use the framebuffer in further mode-setting operations leads to a segmentation fault. Most easily happens with driver that use shadow planes for vmap-ing the dma-buf during a page flip. An example is shown below. [ 156.791968] ------------[ cut here ]------------ [ 156.796830] WARNING: CPU: 2 PID: 2255 at drivers/dma-buf/dma-buf.c:1527 dma_buf_vmap+0x224/0x430 [...] [ 156.942028] RIP: 0010:dma_buf_vmap+0x224/0x430 [ 157.043420] Call Trace: [ 157.045898] <TASK> [ 157.048030] ? show_trace_log_lvl+0x1af/0x2c0 [ 157.052436] ? show_trace_log_lvl+0x1af/0x2c0 [ 157.056836] ? show_trace_log_lvl+0x1af/0x2c0 [ 157.061253] ? drm_gem_shmem_vmap+0x74/0x710 [ 157.065567] ? dma_buf_vmap+0x224/0x430 [ 157.069446] ? __warn.cold+0x58/0xe4 [ 157.073061] ? dma_buf_vmap+0x224/0x430 [ 157.077111] ? report_bug+0x1dd/0x390 [ 157.080842] ? handle_bug+0x5e/0xa0 [ 157.084389] ? exc_invalid_op+0x14/0x50 [ 157.088291] ? asm_exc_invalid_op+0x16/0x20 [ 157.092548] ? dma_buf_vmap+0x224/0x430 [ 157.096663] ? dma_resv_get_singleton+0x6d/0x230 [ 157.101341] ? __pfx_dma_buf_vmap+0x10/0x10 [ 157.105588] ? __pfx_dma_resv_get_singleton+0x10/0x10 [ 157.110697] drm_gem_shmem_vmap+0x74/0x710 [ 157.114866] drm_gem_vmap+0xa9/0x1b0 [ 157.118763] drm_gem_vmap_unlocked+0x46/0xa0 [ 157.123086] drm_gem_fb_vmap+0xab/0x300 [ 157.126979] drm_atomic_helper_prepare_planes.part.0+0x487/0xb10 [ 157.133032] ? lockdep_init_map_type+0x19d/0x880 [ 157.137701] drm_atomic_helper_commit+0x13d/0x2e0 [ 157.142671] ? drm_atomic_nonblocking_commit+0xa0/0x180 [ 157.147988] drm_mode_atomic_ioctl+0x766/0xe40 [...] [ 157.346424] ---[ end trace 0000000000000000 ]--- Acquiring GEM handles for the framebuffer's GEM buffer objects prevents this from happening. The framebuffer's cleanup later puts the handle references. Commit 1a148af ("drm/gem-shmem: Use dma_buf from GEM object instance") triggers the segmentation fault easily by using the dma-buf field more widely. The underlying issue with reference counting has been present before. v2: - acquire the handle instead of the BO (Christian) - fix comment style (Christian) - drop the Fixes tag (Christian) - rename err_ gotos - add missing Link tag Suggested-by: Christian König <christian.koenig@amd.com> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://elixir.bootlin.com/linux/v6.15/source/drivers/gpu/drm/drm_gem.c#L241 # [1] Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Anusha Srivatsa <asrivats@redhat.com> Cc: Christian König <christian.koenig@amd.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Maxime Ripard <mripard@kernel.org> Cc: Sumit Semwal <sumit.semwal@linaro.org> Cc: "Christian König" <christian.koenig@amd.com> Cc: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linaro-mm-sig@lists.linaro.org Cc: <stable@vger.kernel.org> Reviewed-by: Christian König <christian.koenig@amd.com> Link: https://lore.kernel.org/r/20250630084001.293053-1-tzimmermann@suse.de (cherry picked from commit 5307dce) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-136703 cve-bf CVE-2025-38449 commit-author Thomas Zimmermann <tzimmermann@suse.de> commit f6bfc9a upstream-diff Adapted `drm_gem_object_handle_get_unlocked()' (now `drm_gem_object_handle_get_if_exists_unlocked()') to use mutex_lock / mutex_unlock instead of guard(mutex). Resolved context conflicts in include/drm/drm_framebuffer.h due to missing bce3dab. Acquire GEM handles in drm_framebuffer_init() and release them in the corresponding drm_framebuffer_cleanup(). Ties the handle's lifetime to the framebuffer. Not all GEM buffer objects have GEM handles. If not set, no refcounting takes place. This is the case for some fbdev emulation. This is not a problem as these GEM objects do not use dma-bufs and drivers will not release them while fbdev emulation is running. Framebuffer flags keep a bit per color plane of which the framebuffer holds a GEM handle reference. As all drivers use drm_framebuffer_init(), they will now all hold dma-buf references as fixed in commit 5307dce ("drm/gem: Acquire references on GEM handles for framebuffers"). In the GEM framebuffer helpers, restore the original ref counting on buffer objects. As the helpers for handle refcounting are now no longer called from outside the DRM core, unexport the symbols. v3: - don't mix internal flags with mode flags (Christian) v2: - track framebuffer handle refs by flag - drop gma500 cleanup (Christian) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Fixes: 5307dce ("drm/gem: Acquire references on GEM handles for framebuffers") Reported-by: Bert Karwatzki <spasswolf@web.de> Closes: https://lore.kernel.org/dri-devel/20250703115915.3096-1-spasswolf@web.de/ Tested-by: Bert Karwatzki <spasswolf@web.de> Tested-by: Mario Limonciello <superm1@kernel.org> Tested-by: Borislav Petkov (AMD) <bp@alien8.de> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Anusha Srivatsa <asrivats@redhat.com> Cc: Christian König <christian.koenig@amd.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Maxime Ripard <mripard@kernel.org> Cc: Sumit Semwal <sumit.semwal@linaro.org> Cc: "Christian König" <christian.koenig@amd.com> Cc: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linaro-mm-sig@lists.linaro.org Cc: <stable@vger.kernel.org> Reviewed-by: Christian König <christian.koenig@amd.com> Link: https://lore.kernel.org/r/20250707131224.249496-1-tzimmermann@suse.de (cherry picked from commit f6bfc9a) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
d7da957 to
5d4458e
Compare
|
^ Rebased to the recent |
|
🤖 Validation Checks In Progress Workflow run: https://github.com/ctrliq/kernel-src-tree/actions/runs/23318778679 |
🔍 Interdiff Analysis
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -15,8 +15,7 @@
#include <drm/drm_format_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
-#include <drm/drm_gem.h>
-#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_rect.h>
#include <drm/drm_simple_kms_helper.h>
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -14,6 +14,7 @@
#include <drm/drm_format_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_print.h>
@@ -15,7 +16,6 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_rect.h>
#include <drm/drm_simple_kms_helper.h>
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -11,6 +11,7 @@
#include <drm/drm_format_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_rect.h>
@@ -155,5 +165,5 @@
vaddr = map.vaddr + fb->offsets[0];
- if (import_attach) {
- ret = dma_buf_begin_cpu_access(import_attach->dmabuf, DMA_FROM_DEVICE);
+ ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
+ if (ret)
@@ -212,5 +222,5 @@
- if (import_attach)
- dma_buf_end_cpu_access(import_attach->dmabuf, DMA_FROM_DEVICE);
+end_cpu_access:
+ drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
vunmap:
drm_gem_shmem_vunmap(fb->obj[0], &map);
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -7,7 +7,6 @@
#include <drm/drm.h>
#include <drm/drm_gem.h>
-#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_encoder.h>
#include <drm/drm_writeback.h>
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -334,8 +334,9 @@
* Returns:
* 0 on success, or a negative errno code otherwise.
*/
-int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct dma_buf_map *map,
- struct dma_buf_map *data)
+int drm_gem_fb_vmap(struct drm_framebuffer *fb,
+ struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES],
+ struct dma_buf_map data[DRM_FORMAT_MAX_PLANES])
{
struct drm_gem_object *obj;
unsigned int i;
@@ -344,8 +345,8 @@
for (i = 0; i < fb->format->num_planes; ++i) {
obj = drm_gem_fb_get_obj(fb, i);
if (!obj) {
- ret = -EINVAL;
- goto err_drm_gem_vunmap;
+ dma_buf_map_clear(&map[i]);
+ continue;
}
ret = drm_gem_vmap(obj, &map[i]);
if (ret)
@@ -384,7 +385,8 @@
*
* See drm_gem_fb_vmap() for more information.
*/
-void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct dma_buf_map *map)
+void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
+ struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES])
{
unsigned int i = fb->format->num_planes;
struct drm_gem_object *obj;
--- b/include/drm/drm_gem_framebuffer_helper.h
+++ b/include/drm/drm_gem_framebuffer_helper.h
@@ -37,9 +37,11 @@
drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
const struct drm_mode_fb_cmd2 *mode_cmd);
-int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct dma_buf_map *map,
- struct dma_buf_map *data);
-void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct dma_buf_map *map);
+int drm_gem_fb_vmap(struct drm_framebuffer *fb,
+ struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES],
+ struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]);
+void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
+ struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]);
int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);
void drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -335,9 +338,8 @@
* Returns:
* 0 on success, or a negative errno code otherwise.
*/
-int drm_gem_fb_vmap(struct drm_framebuffer *fb,
- struct iosys_map map[static DRM_FORMAT_MAX_PLANES],
- struct iosys_map data[DRM_FORMAT_MAX_PLANES])
+int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map,
+ struct iosys_map *data)
{
struct drm_gem_object *obj;
unsigned int i;
@@ -344,8 +346,8 @@
for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
obj = drm_gem_fb_get_obj(fb, i);
if (!obj) {
- iosys_map_clear(&map[i]);
- continue;
+ ret = -EINVAL;
+ goto err_drm_gem_vunmap;
}
ret = drm_gem_vmap(obj, &map[i]);
if (ret)
@@ -388,8 +390,7 @@
*
* See drm_gem_fb_vmap() for more information.
*/
-void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
- struct iosys_map map[static DRM_FORMAT_MAX_PLANES])
+void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct iosys_map *map)
{
unsigned int i = DRM_FORMAT_MAX_PLANES;
struct drm_gem_object *obj;
--- b/include/drm/drm_gem_framebuffer_helper.h
+++ b/include/drm/drm_gem_framebuffer_helper.h
@@ -37,11 +35,9 @@
drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
const struct drm_mode_fb_cmd2 *mode_cmd);
-int drm_gem_fb_vmap(struct drm_framebuffer *fb,
- struct iosys_map map[static DRM_FORMAT_MAX_PLANES],
- struct iosys_map data[DRM_FORMAT_MAX_PLANES]);
-void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
- struct iosys_map map[static DRM_FORMAT_MAX_PLANES]);
+int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map,
+ struct iosys_map *data);
+void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct iosys_map *map);
int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);
void drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -332,8 +335,8 @@
* 0 on success, or a negative errno code otherwise.
*/
int drm_gem_fb_vmap(struct drm_framebuffer *fb,
- struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES],
- struct dma_buf_map data[DRM_FORMAT_MAX_PLANES])
+ struct iosys_map map[static DRM_FORMAT_MAX_PLANES],
+ struct iosys_map data[DRM_FORMAT_MAX_PLANES])
{
struct drm_gem_object *obj;
unsigned int i;
@@ -342,8 +345,8 @@
for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
obj = drm_gem_fb_get_obj(fb, i);
if (!obj) {
- dma_buf_map_clear(&map[i]);
+ iosys_map_clear(&map[i]);
continue;
}
ret = drm_gem_vmap(obj, &map[i]);
if (ret)
@@ -354,3 +357,3 @@
memcpy(&data[i], &map[i], sizeof(data[i]));
- if (dma_buf_map_is_null(&data[i]))
+ if (iosys_map_is_null(&data[i]))
continue;
@@ -380,7 +382,7 @@
* See drm_gem_fb_vmap() for more information.
*/
void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
- struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES])
+ struct iosys_map map[static DRM_FORMAT_MAX_PLANES])
{
unsigned int i = DRM_FORMAT_MAX_PLANES;
struct drm_gem_object *obj;
--- b/include/drm/drm_gem_framebuffer_helper.h
+++ b/include/drm/drm_gem_framebuffer_helper.h
@@ -2,5 +2,5 @@
#include <linux/dma-buf.h>
-#include <linux/dma-buf-map.h>
+#include <linux/iosys-map.h>
#include <drm/drm_fourcc.h>
@@ -40,10 +40,10 @@
const struct drm_mode_fb_cmd2 *mode_cmd);
int drm_gem_fb_vmap(struct drm_framebuffer *fb,
- struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES],
- struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]);
+ struct iosys_map map[static DRM_FORMAT_MAX_PLANES],
+ struct iosys_map data[DRM_FORMAT_MAX_PLANES]);
void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
- struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]);
+ struct iosys_map map[static DRM_FORMAT_MAX_PLANES]);
int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);
void drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir);
================================================================================
* ONLY IN PATCH2 - files not modified by patch1 *
================================================================================
--- a/drivers/gpu/drm/drm_gem_atomic_helper.c
+++ b/drivers/gpu/drm/drm_gem_atomic_helper.c
@@ -169,8 +169,10 @@ int drm_gem_plane_helper_prepare_fb(struct drm_plane *plane,
struct drm_gem_object *obj = drm_gem_fb_get_obj(state->fb, i);
struct dma_fence *new;
- if (WARN_ON_ONCE(!obj))
- continue;
+ if (!obj) {
+ ret = -EINVAL;
+ goto error;
+ }
ret = dma_resv_get_singleton(obj->resv, usage, &new);
if (ret)
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -204,12 +204,10 @@
{
struct drm_device *dev = obj->dev;
- mutex_lock(&dev->object_name_lock);
+ guard(mutex)(&dev->object_name_lock);
drm_WARN_ON(dev, !obj->handle_count); /* first ref taken in create-tail helper */
drm_gem_object_handle_get(obj);
-
- mutex_unlock(&dev->object_name_lock);
}
EXPORT_SYMBOL(drm_gem_object_handle_get_unlocked);
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -179,4 +179,5 @@
}
+EXPORT_SYMBOL(drm_gem_private_object_fini);
/**
* drm_gem_object_handle_free - release resources bound to userspace handles
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -215,17 +215,12 @@
* do not have a GEM handle. Hence, this counter can be zero.
*/
- if (!obj->handle_count) {
- mutex_unlock(&dev->object_name_lock);
+ if (!obj->handle_count)
return false;
- }
drm_gem_object_handle_get(obj);
mutex_unlock(&dev->object_name_lock);
-
- return true;
}
-
/**
* drm_gem_object_handle_free - release resources bound to userspace handles
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -246,6 +256,8 @@
drm_WARN_ON(dev, !obj->handle_count); /* first ref taken in create-tail helper */
drm_gem_object_handle_get(obj);
+
+ return true;
}
EXPORT_SYMBOL(drm_gem_object_handle_get_unlocked);
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -190,5 +190,6 @@
}
+
/**
* drm_gem_object_handle_get_unlocked - acquire reference on user-space handles
* @obj: GEM object
@@ -204,12 +226,10 @@
{
struct drm_device *dev = obj->dev;
- mutex_lock(&dev->object_name_lock);
+ guard(mutex)(&dev->object_name_lock);
drm_WARN_ON(dev, !obj->handle_count); /* first ref taken in create-tail helper */
drm_gem_object_handle_get(obj);
-
- mutex_unlock(&dev->object_name_lock);
}
EXPORT_SYMBOL(drm_gem_object_handle_get_unlocked);
--- b/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -189,5 +189,5 @@
*/
int flags;
/**
- * @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor
- * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
+ * @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock.
+ */This is an automated interdiff check for backported commits. |
JIRA PR Check Results11 commit(s) with issues found: Commit
|
|
❌ Validation checks completed with issues View full results: https://github.com/ctrliq/kernel-src-tree/actions/runs/23318778679 |
PlaidCat
left a comment
There was a problem hiding this comment.
![]()
@kerneltoast did you want to look at anything here?
[LTS 8.6]
Commits
Discussion
Comparison with other versions
CVE-2025-38449 is solved on upstream with 5307dce
drm/gem: Acquire references on GEM handles for framebuffersand comes with a bugfix f6bfc9adrm/framebuffer: Acquire internal references on GEM handles. These two commits were the basis of CVE solution for a number of Linux versions:ciqlts9_2ciqlts9_4ciqlts9_6rocky8_10rocky10_0centos9centos10linux-6.6.ycb4c956a15f8b7f870649454771fc3761f504b5fFix2e2e9b3d708473040a08ab884f7dc2369752bb69Bugfixlinux-6.12.ylinux-6.15.y3cf520d9860d4ec9f7f32068825da31f18dd3f25Fixb5cc8e1e1cba7377f22f85ad7aefbe8efdf4f2eaBugfixWhat all these versions have in common is the backported commit 746b9c6
drm/gem: Ignore color planes that are unused by framebuffer format(directly or embedded in a larger update):ciqlts9_2,ciqlts9_4,ciqlts9_6,centos9: 7a3deb5rocky8_10: 8fe840brocky10_0,centos10,linux-6.6.y,linux-6.12.y,linux-6.15.y: 746b9c6 (native)Version
ciqlts8_6is missing this prerequisite.Prerequisite meaning
Both the CVE-2025-38449 fix 5307dce and its bugfix f6bfc9a modify (or introduce) code operating on frame buffer planes iterated in loops, which all follow the same pattern of indexing from
0(inclusive) tofb->format->num_planes(exclusive), easily observable in the smalldrm_gem_fb_destroy()function:kernel-src-tree/drivers/gpu/drm/drm_gem_framebuffer_helper.c
Lines 97 to 106 in 5307dce
The (dynamic) upper bound
fb->format->num_planesis what was introduced by the prerequisite 746b9c6drm/gem: Ignore color planes that are unused by framebuffer format. Previously the loops were always iterated a fixed number of times. See thedrm_gem_fb_destroy()function at revision 746b9c6~1 = f159b1b:kernel-src-tree/drivers/gpu/drm/drm_gem_framebuffer_helper.c
Lines 93 to 102 in f159b1b
The compile-time upper bound parameterization wasn't even present until 279cc2e
drm: Define DRM_FORMAT_MAX_PLANES. See the same function at revision 279cc2e~1 = 6e5b47a where the upper bound is hardcoded to4:kernel-src-tree/drivers/gpu/drm/drm_gem_framebuffer_helper.c
Lines 87 to 96 in 6e5b47a
This version of the planes iterating loops is what can be found in
ciqlts8_6.While
drm: Define DRM_FORMAT_MAX_PLANESwas just a matter of code cohesion thedrm/gem: Ignore color planes that are unused by framebuffer formatintroduced an actual, important behavior change. From the commit message:See https://lore.kernel.org/dri-devel/20210730183511.20080-1-tzimmermann@suse.de/T/#md0172b10bb588d8f20f4f456e304f08d2a4505f7.
Necessity of the prerequisite backport
Cherry-picking the CVE-2025-38449 fix 5307dce directly onto
ciqlts8_6did not cause conflicts for the loop upper bound in thedrm_gem_fb_init_with_funcs()function, and in thedrm_gem_fb_destroy()they may have been treated as context conflicts only, prompting to leave hardcoded4as it was. The bugfix f6bfc9a, however, introduces new loops of this kind in thedrm_framebuffer_init()function with the upper bound beingfb->format->num_planesand not raising any conflicts whatsoever. This led to the consideration of four solutions:ciqlts8_6-native upper bound4in the fix andfb->format->num_planesin the bugfix. This was very unlikely to result in correct code, introducing inconsistency in getting/putting object handles between thedrm_framebuffer_init()function and all the rest.4to match the existing codebase. This also seemed risky, given that this bound was already problematic before the bugfix, and the bugfix itself was not prepared with the wider span of planes in mind - merely changing the number of iterations may not have been sufficient to obtain correct code. More involved fix altereation, in turn, was not possible due to lack of expertise in thedrmsubsystem.ciqlts8_6codebase with the bugfix to use thefb->format->num_planesupper bound. This required sizable backporting, but seemed to be the least risky approach of all four, and was ultimately chosen as the proposed solution for CVE-2025-38449 on LTS 8.6.Changes overview
Let the commits be numbered as follows, starting from the oldest:
drm/gem: Provide drm_gem_fb_{begin,end}_cpu_access() helpersdrm: Define DRM_FORMAT_MAX_PLANESdrm/gem: Provide drm_gem_fb_{vmap,vunmap}()drm/gem: Clear mapping addresses for unused framebuffer planesdrm/gud: Map framebuffer BOs with drm_gem_fb_vmap()drm/vkms: Map output framebuffer BOs with drm_gem_fb_vmap()drm/gem: Provide offset-adjusted framebuffer BO mappingsdrm/gem: Share code between drm_gem_fb_{begin,end}_cpu_access()drm/gem: Ignore color planes that are unused by framebuffer formatdrm/gem: Acquire references on GEM handles for framebuffersdrm/framebuffer: Acquire internal references on GEM handlesCommits (10) and (11) are the fix for CVE-2025-38449 and its bugfix, as the typical solutions in other versions. Commit (9) introduces the key change of setting the upper bound of the planes iterating loop to
fb->format->num_planes. Commits (1) to (8) exist for the sole purpose of painless inclusion of (9) in the solution. In particular commit (2) provides the intermediary transition from the the number of planes hardcoded to4to parameterizedDRM_FORMAT_MAX_PLANES.For the commits (1) to (8) there are essentially no differences from the upstream. Technically (5) and (6) were modified, but the adaptations are functionally neutral, reduced to the inclusion of necessary headers, which were already in place for the upstream code, required by some previous changes, so the upstream commits didn't include them.
Upstream commit (9) assumes that 7938f42
dma-buf-map: Rename to iosys-mapis in place. It is a very voluminous commit which would be difficult to backport and probably shouldn't be. Fortunately it's just a structure renaming, fromdma_buf_maptoiosys_map. The proposed backport of (9) kept the originaldma_buf_mapname. Additionally the change in one of the functions was omitted, as the codepath it modified doesn't exist inciqlts8_6. It was decided not to backport it to keep the growing size of the solution under control.The CVE fix (10) was modified compared to the upstream in the same way as the
ciqlts9_2backport 11f7a1e was - by using older synchronization scheme based on explicitmutex_lock()/mutex_unlock()instead of upstream'sguard()construct. The bugfix (11) followed suit and includedmutex_unlock()in the newly added exit branch, again, like in theciqlts9_2bugfix 6d1b009.Consistency with
rocky8_10Analyzing the history of
rocky8_10- closest version tociqlts8_6where CVE-2025-38449 was fixed outside of CIQ - it can be seen that all prerequisites (1) to (9) were included in that version in theRebuild centos8 with kernel-4.18.0-448.el8commit 8fe840b. Even if some of them are not immediately visible in the changes it's only because they were altered / overriden by other mixed-in commits, often from the same batch of (1)-(9).drm/gem: Provide drm_gem_fb_{begin,end}_cpu_access() helpers: Changes present.drm: Define DRM_FORMAT_MAX_PLANES: Changes present, but altered by 746b9c6 (9).drm/gem: Provide drm_gem_fb_{vmap,vunmap}(): Changes present, altered by 0ec77bd (4) and 7938f42.drm/gem: Clear mapping addresses for unused framebuffer planes: Changes present, altered by 746b9c6 (9) and 7938f42.drm/gud: Map framebuffer BOs with drm_gem_fb_vmap(): Changes present, altered by 7938f42, 43b3623 (7), 6d463aa.drm/vkms: Map output framebuffer BOs with drm_gem_fb_vmap(): Changes present, altered by 2ca380e, 7938f42, 43b3623 (7), bbdf7b2.drm/gem: Provide offset-adjusted framebuffer BO mappings: Changes present.drm/gem: Share code between drm_gem_fb_{begin,end}_cpu_access(): Changes present.drm/gem: Ignore color planes that are unused by framebuffer format: Changes present.CentOS 8 underwent
drmsubsystem update which is a superset of the prerequisites included in this solution for CVE-2025-38449.kABI check: passed
Boot test: passed
boot-test.log
Kselftests: passed relative
Reference
kselftests–ciqlts8_6–run1.log
Patch
kselftests–ciqlts8_6-CVE-2025-38449–run1.log
kselftests–ciqlts8_6-CVE-2025-38449–run2.log
Comparison
The tests results for the reference and the patch are the same.