Skip to content

[LTS 8.6] drm: CVE-2025-38449#987

Open
pvts-mat wants to merge 11 commits intoctrliq:ciqlts8_6from
pvts-mat:ciqlts8_6-CVE-2025-38449
Open

[LTS 8.6] drm: CVE-2025-38449#987
pvts-mat wants to merge 11 commits intoctrliq:ciqlts8_6from
pvts-mat:ciqlts8_6-CVE-2025-38449

Conversation

@pvts-mat
Copy link
Contributor

[LTS 8.6]

CVE-2025-38449 VULN-136703

Commits

drm/gem: Provide drm_gem_fb_{begin,end}_cpu_access() helpers

jira VULN-136703
cve-pre CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit 37408cd825a47b89c2302b88ad3c071f796a2ec0
drm: Define DRM_FORMAT_MAX_PLANES

jira VULN-136703
cve-pre CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit 279cc2e9543eb357c0ef299cf398b2e74a021f6b
drm/gem: Provide drm_gem_fb_{vmap,vunmap}()

jira VULN-136703
cve-pre CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit f6424ecdb3c8aba18997a6992f780ab9c27734bc
drm/gem: Clear mapping addresses for unused framebuffer planes

jira VULN-136703
cve-pre CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit 0ec77bd92b513aa4e556e5b92ccd993677d21cbc
drm/gud: Map framebuffer BOs with drm_gem_fb_vmap()

jira VULN-136703
cve-pre CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit 0029d3182969d8dc67e4fedb00d6cf50eee74670
upstream-diff Included drm/drm_gem_framebuffer_helper.h which was
  incorporated in 08b7ef0524f52cfd7f247270e0f95480709f210a 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()'
drm/vkms: Map output framebuffer BOs with drm_gem_fb_vmap()

jira VULN-136703
cve-pre CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit 50fff206c5e3a04fcb239ad58d89cad166711b7f
upstream-diff Included drm/drm_gem_atomic_helper.h in
  drivers/gpu/drm/vkms/vkms_drv.h, which was done on upstream in
  7602d4221842c12777363591df04672e2c8b6a61, not backported to LTS 8.6.
  It was needed for the definition of `dma_buf_map'.
drm/gem: Provide offset-adjusted framebuffer BO mappings

jira VULN-136703
cve-pre CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit 43b36232ded23ce943224df3d1451f981446ae23
drm/gem: Share code between drm_gem_fb_{begin,end}_cpu_access()

jira VULN-136703
cve-pre CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit f159b1b22c8a2d3d7c1fa877fafc8aacff0deeba
drm/gem: Ignore color planes that are unused by framebuffer format

jira VULN-136703
cve-pre CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit 746b9c62cc8614fa59c23f3332682b5e9e1d801c
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
        1ea28bc5542d607ff7c806e409a72862c5af8f5e ("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
        7938f4218168ae9fc4bdddb15976f9ebbae41999 ("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.
drm/gem: Acquire references on GEM handles for framebuffers

jira VULN-136703
cve CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit 5307dce878d4126e1b375587318955bd019c3741
upstream-diff In `drm_gem_object_handle_get_unlocked()' used
  `mutex_lock()' and `mutex_unlock()' instead of `guard()' - it was
  introduced in 54da6a0924311c7cf5015533991e44fb8eb12773 ("locking:
  Introduce __cleanup() based infrastructure"), not backported to LTS
  8.6.
drm/framebuffer: Acquire internal references on GEM handles

jira VULN-136703
cve-bf CVE-2025-38449
commit-author Thomas Zimmermann <tzimmermann@suse.de>
commit f6bfc9afc7510cb5e6fbe0a17c507917b0120280
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
  bce3dab7eb6ee596388699e8a052a7d58954c472.

Discussion

Comparison with other versions

CVE-2025-38449 is solved on upstream with 5307dce drm/gem: Acquire references on GEM handles for framebuffers and comes with a bugfix f6bfc9a drm/framebuffer: Acquire internal references on GEM handles. These two commits were the basis of CVE solution for a number of Linux versions:

  • ciqlts9_2
  • ciqlts9_4
  • ciqlts9_6
  • rocky8_10
  • rocky10_0
  • centos9
  • centos10
  • linux-6.6.y
    • cb4c956a15f8b7f870649454771fc3761f504b5f Fix
    • 2e2e9b3d708473040a08ab884f7dc2369752bb69 Bugfix
  • linux-6.12.y
  • linux-6.15.y
    • 3cf520d9860d4ec9f7f32068825da31f18dd3f25 Fix
    • b5cc8e1e1cba7377f22f85ad7aefbe8efdf4f2ea Bugfix

What 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: 7a3deb5
  • rocky8_10: 8fe840b
  • rocky10_0, centos10, linux-6.6.y, linux-6.12.y, linux-6.15.y: 746b9c6 (native)

Version ciqlts8_6 is 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) to fb->format->num_planes (exclusive), easily observable in the small drm_gem_fb_destroy() function:

void drm_gem_fb_destroy(struct drm_framebuffer *fb)
{
unsigned int i;
for (i = 0; i < fb->format->num_planes; i++)
drm_gem_object_handle_put_unlocked(fb->obj[i]);
drm_framebuffer_cleanup(fb);
kfree(fb);
}

The (dynamic) upper bound fb->format->num_planes is what was introduced by the prerequisite 746b9c6 drm/gem: Ignore color planes that are unused by framebuffer format. Previously the loops were always iterated a fixed number of times. See the drm_gem_fb_destroy() function at revision 746b9c6~1 = f159b1b:

void drm_gem_fb_destroy(struct drm_framebuffer *fb)
{
size_t i;
for (i = 0; i < ARRAY_SIZE(fb->obj); i++)
drm_gem_object_put(fb->obj[i]);
drm_framebuffer_cleanup(fb);
kfree(fb);
}

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 to 4:

void drm_gem_fb_destroy(struct drm_framebuffer *fb)
{
int i;
for (i = 0; i < 4; i++)
drm_gem_object_put(fb->obj[i]);
drm_framebuffer_cleanup(fb);
kfree(fb);
}

This version of the planes iterating loops is what can be found in ciqlts8_6.

While drm: Define DRM_FORMAT_MAX_PLANES was just a matter of code cohesion the drm/gem: Ignore color planes that are unused by framebuffer format introduced an actual, important behavior change. From the commit message:

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]

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_6 did not cause conflicts for the loop upper bound in the drm_gem_fb_init_with_funcs() function, and in the drm_gem_fb_destroy() they may have been treated as context conflicts only, prompting to leave hardcoded 4 as it was. The bugfix f6bfc9a, however, introduces new loops of this kind in the drm_framebuffer_init() function with the upper bound being fb->format->num_planes and not raising any conflicts whatsoever. This led to the consideration of four solutions:

  1. Leave ciqlts8_6-native upper bound 4 in the fix and fb->format->num_planes in the bugfix. This was very unlikely to result in correct code, introducing inconsistency in getting/putting object handles between the drm_framebuffer_init() function and all the rest.
  2. Change the upper bound in the bugfix to 4 to 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 the drm subsystem.
  3. Leave out the bugfix altogether based on its possibly low importance. However, it was too difficult to assess the severity of the bug introduced by the CVE-2025-38449 fix based on the only discussion about it found at https://lore.kernel.org/dri-devel/20250703115915.3096-1-spasswolf@web.de/#t.
  4. Align the planes iterating loops in the ciqlts8_6 codebase with the bugfix to use the fb->format->num_planes upper 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:

  1. drm/gem: Provide drm_gem_fb_{begin,end}_cpu_access() helpers
  2. drm: Define DRM_FORMAT_MAX_PLANES
  3. drm/gem: Provide drm_gem_fb_{vmap,vunmap}()
  4. drm/gem: Clear mapping addresses for unused framebuffer planes
  5. drm/gud: Map framebuffer BOs with drm_gem_fb_vmap()
  6. drm/vkms: Map output framebuffer BOs with drm_gem_fb_vmap()
  7. drm/gem: Provide offset-adjusted framebuffer BO mappings
  8. drm/gem: Share code between drm_gem_fb_{begin,end}_cpu_access()
  9. drm/gem: Ignore color planes that are unused by framebuffer format
  10. drm/gem: Acquire references on GEM handles for framebuffers
  11. drm/framebuffer: Acquire internal references on GEM handles

Commits (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 to 4 to parameterized DRM_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-map is 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, from dma_buf_map to iosys_map. The proposed backport of (9) kept the original dma_buf_map name. Additionally the change in one of the functions was omitted, as the codepath it modified doesn't exist in ciqlts8_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_2 backport 11f7a1e was - by using older synchronization scheme based on explicit mutex_lock() / mutex_unlock() instead of upstream's guard() construct. The bugfix (11) followed suit and included mutex_unlock() in the newly added exit branch, again, like in the ciqlts9_2 bugfix 6d1b009.

Consistency with rocky8_10

Analyzing the history of rocky8_10 - closest version to ciqlts8_6 where CVE-2025-38449 was fixed outside of CIQ - it can be seen that all prerequisites (1) to (9) were included in that version in the Rebuild centos8 with kernel-4.18.0-448.el8 commit 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).

  1. drm/gem: Provide drm_gem_fb_{begin,end}_cpu_access() helpers: Changes present.
  2. drm: Define DRM_FORMAT_MAX_PLANES: Changes present, but altered by 746b9c6 (9).
  3. drm/gem: Provide drm_gem_fb_{vmap,vunmap}(): Changes present, altered by 0ec77bd (4) and 7938f42.
  4. drm/gem: Clear mapping addresses for unused framebuffer planes: Changes present, altered by 746b9c6 (9) and 7938f42.
  5. drm/gud: Map framebuffer BOs with drm_gem_fb_vmap(): Changes present, altered by 7938f42, 43b3623 (7), 6d463aa.
  6. drm/vkms: Map output framebuffer BOs with drm_gem_fb_vmap(): Changes present, altered by 2ca380e, 7938f42, 43b3623 (7), bbdf7b2.
  7. drm/gem: Provide offset-adjusted framebuffer BO mappings: Changes present.
  8. drm/gem: Share code between drm_gem_fb_{begin,end}_cpu_access(): Changes present.
  9. drm/gem: Ignore color planes that are unused by framebuffer format: Changes present.

CentOS 8 underwent drm subsystem update which is a superset of the prerequisites included in this solution for CVE-2025-38449.

kABI check: passed

[0/1] kabi_check_kernel	Check ABI of kernel [ciqlts8_6-CVE-2025-38449]	_kabi_check_kernel__x86_64--test--ciqlts8_6-CVE-2025-38449
ninja explain: output state/kernels/ciqlts8_6-CVE-2025-38449/x86_64/kabi_checked doesn't exist
ninja explain: state/kernels/ciqlts8_6-CVE-2025-38449/x86_64/kabi_checked is dirty
+ dist_git_version=el-8.6
+ local_version=ciqlts8_6-CVE-2025-38449
+ arch=x86_64
+ user=pvts
+ buildmachine=x86_64--build--ciqlts8_6
+ virsh_timeout=600
+ ssh_daemon_wait=20
+ src_dir=/mnt/code/kernel-dist-git-el-8.6
+ build_dir=/mnt/build_files/kernel-src-tree-ciqlts8_6-CVE-2025-38449
+ sudo chmod +x /data/src/ctrliq-github-haskell/kernel-dist-git-el-8.6/SOURCES/check-kabi
+ ninja-back/virssh.xsh --max 8 --shutdown-on-success --shutdown-on-failure --timeout 600 --ssh-daemon-wait 20 pvts x86_64--build--ciqlts8_6 ''\''/mnt/code/kernel-dist-git-el-8.6/SOURCES/check-kabi'\'' -k '\''/mnt/code/kernel-dist-git-el-8.6/SOURCES/Module.kabi_x86_64'\'' -s '\''/mnt/build_files/kernel-src-tree-ciqlts8_6-CVE-2025-38449/Module.symvers'\'''
kABI check passed
+ touch state/kernels/ciqlts8_6-CVE-2025-38449/x86_64/kabi_checked

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.

$ ktests.xsh diff  kselftests*.log

Column    File
--------  ----------------------------------------------
Status0   kselftests--ciqlts8_6--run1.log
Status1   kselftests--ciqlts8_6-CVE-2025-38449--run1.log
Status2   kselftests--ciqlts8_6-CVE-2025-38449--run2.log

TestCase                                     Status0  Status1  Status2  Summary
android:run.sh                               skip     skip     skip     same
bpf:get_cgroup_id_user                       pass     pass     pass     same
bpf:test_bpftool.sh                          pass     pass     pass     same
bpf:test_bpftool_build.sh                    pass     pass     pass     same
bpf:test_bpftool_metadata.sh                 pass     pass     pass     same
bpf:test_cgroup_storage                      pass     pass     pass     same
bpf:test_dev_cgroup                          pass     pass     pass     same
bpf:test_doc_build.sh                        pass     pass     pass     same
bpf:test_flow_dissector.sh                   pass     pass     pass     same
bpf:test_lirc_mode2.sh                       pass     pass     pass     same
bpf:test_lpm_map                             pass     pass     pass     same
bpf:test_lru_map                             pass     pass     pass     same
bpf:test_lwt_ip_encap.sh                     pass     pass     pass     same
bpf:test_lwt_seg6local.sh                    pass     pass     pass     same
bpf:test_netcnt                              pass     pass     pass     same
bpf:test_offload.py                          fail     fail     fail     same
bpf:test_skb_cgroup_id.sh                    pass     pass     pass     same
bpf:test_sock                                pass     pass     pass     same
bpf:test_sock_addr.sh                        pass     pass     pass     same
bpf:test_sysctl                              pass     pass     pass     same
bpf:test_tag                                 pass     pass     pass     same
bpf:test_tc_edt.sh                           pass     pass     pass     same
bpf:test_tc_tunnel.sh                        pass     pass     pass     same
bpf:test_tcp_check_syncookie.sh              pass     pass     pass     same
bpf:test_tcpnotify_user                      pass     pass     pass     same
bpf:test_tunnel.sh                           pass     pass     pass     same
bpf:test_verifier                            pass     pass     pass     same
bpf:test_verifier_log                        pass     pass     pass     same
bpf:test_xdp_meta.sh                         pass     pass     pass     same
bpf:test_xdp_redirect.sh                     pass     pass     pass     same
bpf:test_xdp_veth.sh                         pass     pass     pass     same
bpf:test_xdp_vlan_mode_generic.sh            pass     pass     pass     same
bpf:test_xdp_vlan_mode_native.sh             pass     pass     pass     same
bpf:test_xdping.sh                           pass     pass     pass     same
bpf:urandom_read                             pass     pass     pass     same
breakpoints:breakpoint_test                  pass     pass     pass     same
capabilities:test_execve                     pass     pass     pass     same
core:close_range_test                        pass     pass     pass     same
cpu-hotplug:cpu-on-off-test.sh               pass     pass     pass     same
cpufreq:main.sh                              fail     fail     fail     same
exec:execveat                                pass     pass     pass     same
firmware:fw_run_tests.sh                     skip     skip     skip     same
fpu:run_test_fpu.sh                          skip     skip     skip     same
fpu:test_fpu                                 pass     pass     pass     same
ftrace:ftracetest                            fail     fail     fail     same
futex:run.sh                                 pass     pass     pass     same
gpio:gpio-mockup.sh                          fail     fail     fail     same
intel_pstate:run.sh                          pass     pass     pass     same
ipc:msgque                                   pass     pass     pass     same
kcmp:kcmp_test                               pass     pass     pass     same
kexec:test_kexec_file_load.sh                skip     skip     skip     same
kexec:test_kexec_load.sh                     skip     skip     skip     same
kvm:access_tracking_perf_test                fail     fail     fail     same
kvm:amx_test                                 fail     fail     fail     same
kvm:cr4_cpuid_sync_test                      fail     fail     fail     same
kvm:debug_regs                               fail     fail     fail     same
kvm:demand_paging_test                       pass     pass     pass     same
kvm:dirty_log_perf_test                      pass     pass     pass     same
kvm:dirty_log_test                           fail     fail     fail     same
kvm:emulator_error_test                      fail     fail     fail     same
kvm:evmcs_test                               fail     fail     fail     same
kvm:get_cpuid_test                           fail     fail     fail     same
kvm:get_msr_index_features                   fail     fail     fail     same
kvm:hardware_disable_test                    pass     pass     pass     same
kvm:hyperv_clock                             fail     fail     fail     same
kvm:hyperv_cpuid                             fail     fail     fail     same
kvm:hyperv_features                          fail     fail     fail     same
kvm:kvm_binary_stats_test                    pass     pass     pass     same
kvm:kvm_create_max_vcpus                     skip     skip     skip     same
kvm:kvm_page_table_test                      pass     pass     pass     same
kvm:kvm_pv_test                              fail     fail     fail     same
kvm:memslot_modification_stress_test         pass     pass     pass     same
kvm:memslot_perf_test                        fail     fail     fail     same
kvm:mmio_warning_test                        fail     fail     fail     same
kvm:mmu_role_test                            fail     fail     fail     same
kvm:platform_info_test                       fail     fail     fail     same
kvm:rseq_test                                fail     fail     fail     same
kvm:set_boot_cpu_id                          fail     fail     fail     same
kvm:set_memory_region_test                   pass     pass     pass     same
kvm:set_sregs_test                           fail     fail     fail     same
kvm:smm_test                                 fail     fail     fail     same
kvm:state_test                               fail     fail     fail     same
kvm:steal_time                               pass     pass     pass     same
kvm:svm_int_ctl_test                         fail     fail     fail     same
kvm:svm_vmcall_test                          fail     fail     fail     same
kvm:sync_regs_test                           fail     fail     fail     same
kvm:tsc_msrs_test                            fail     fail     fail     same
kvm:userspace_msr_exit_test                  fail     fail     fail     same
kvm:vmx_apic_access_test                     fail     fail     fail     same
kvm:vmx_close_while_nested_test              fail     fail     fail     same
kvm:vmx_dirty_log_test                       fail     fail     fail     same
kvm:vmx_nested_tsc_scaling_test              fail     fail     fail     same
kvm:vmx_pmu_msrs_test                        fail     fail     fail     same
kvm:vmx_preemption_timer_test                fail     fail     fail     same
kvm:vmx_set_nested_state_test                fail     fail     fail     same
kvm:vmx_tsc_adjust_test                      fail     fail     fail     same
kvm:xapic_ipi_test                           fail     fail     fail     same
kvm:xen_shinfo_test                          fail     fail     fail     same
kvm:xen_vmcall_test                          fail     fail     fail     same
kvm:xss_msr_test                             fail     fail     fail     same
lib:bitmap.sh                                skip     skip     skip     same
lib:prime_numbers.sh                         skip     skip     skip     same
lib:printf.sh                                skip     skip     skip     same
lib:scanf.sh                                 fail     fail     fail     same
livepatch:test-callbacks.sh                  pass     pass     pass     same
livepatch:test-ftrace.sh                     pass     pass     pass     same
livepatch:test-livepatch.sh                  pass     pass     pass     same
livepatch:test-shadow-vars.sh                pass     pass     pass     same
livepatch:test-state.sh                      pass     pass     pass     same
membarrier:membarrier_test_multi_thread      pass     pass     pass     same
membarrier:membarrier_test_single_thread     pass     pass     pass     same
memfd:memfd_test                             pass     pass     pass     same
memfd:run_fuse_test.sh                       fail     fail     fail     same
memfd:run_hugetlbfs_test.sh                  pass     pass     pass     same
memory-hotplug:mem-on-off-test.sh            pass     pass     pass     same
mount:run_tests.sh                           pass     pass     pass     same
net/forwarding:bridge_port_isolation.sh      pass     pass     pass     same
net/forwarding:bridge_sticky_fdb.sh          pass     pass     pass     same
net/forwarding:bridge_vlan_aware.sh          fail     fail     fail     same
net/forwarding:bridge_vlan_unaware.sh        pass     pass     pass     same
net/forwarding:ethtool.sh                    fail     fail     fail     same
net/forwarding:gre_multipath.sh              fail     fail     fail     same
net/forwarding:ip6_forward_instats_vrf.sh    fail     fail     fail     same
net/forwarding:ipip_flat_gre.sh              pass     pass     pass     same
net/forwarding:ipip_flat_gre_key.sh          pass     pass     pass     same
net/forwarding:ipip_flat_gre_keys.sh         pass     pass     pass     same
net/forwarding:ipip_hier_gre.sh              pass     pass     pass     same
net/forwarding:ipip_hier_gre_key.sh          pass     pass     pass     same
net/forwarding:loopback.sh                   skip     skip     skip     same
net/forwarding:mirror_gre.sh                 fail     fail     fail     same
net/forwarding:mirror_gre_bound.sh           pass     pass     pass     same
net/forwarding:mirror_gre_bridge_1d.sh       pass     pass     pass     same
net/forwarding:mirror_gre_bridge_1q.sh       pass     pass     pass     same
net/forwarding:mirror_gre_bridge_1q_lag.sh   pass     pass     pass     same
net/forwarding:mirror_gre_changes.sh         fail     fail     fail     same
net/forwarding:mirror_gre_flower.sh          fail     fail     fail     same
net/forwarding:mirror_gre_lag_lacp.sh        pass     pass     pass     same
net/forwarding:mirror_gre_neigh.sh           pass     pass     pass     same
net/forwarding:mirror_gre_nh.sh              pass     pass     pass     same
net/forwarding:mirror_gre_vlan.sh            pass     pass     pass     same
net/forwarding:mirror_vlan.sh                pass     pass     pass     same
net/forwarding:router.sh                     fail     fail     fail     same
net/forwarding:router_bridge.sh              pass     pass     pass     same
net/forwarding:router_bridge_vlan.sh         pass     pass     pass     same
net/forwarding:router_broadcast.sh           fail     fail     fail     same
net/forwarding:router_multicast.sh           fail     fail     fail     same
net/forwarding:router_multipath.sh           fail     fail     fail     same
net/forwarding:router_vid_1.sh               pass     pass     pass     same
net/forwarding:tc_chains.sh                  pass     pass     pass     same
net/forwarding:tc_flower.sh                  pass     pass     pass     same
net/forwarding:tc_flower_router.sh           pass     pass     pass     same
net/forwarding:tc_mpls_l2vpn.sh              pass     pass     pass     same
net/forwarding:tc_shblocks.sh                pass     pass     pass     same
net/forwarding:tc_vlan_modify.sh             pass     pass     pass     same
net/forwarding:vxlan_asymmetric.sh           pass     pass     pass     same
net/forwarding:vxlan_bridge_1d.sh            fail     fail     fail     same
net/forwarding:vxlan_bridge_1d_port_8472.sh  pass     pass     pass     same
net/forwarding:vxlan_bridge_1q.sh            fail     fail     fail     same
net/forwarding:vxlan_bridge_1q_port_8472.sh  pass     pass     pass     same
net/forwarding:vxlan_symmetric.sh            pass     pass     pass     same
net/mptcp:diag.sh                            pass     pass     pass     same
net/mptcp:mptcp_connect.sh                   pass     pass     pass     same
net/mptcp:mptcp_sockopt.sh                   pass     pass     pass     same
net/mptcp:pm_netlink.sh                      pass     pass     pass     same
net:bareudp.sh                               pass     pass     pass     same
net:devlink_port_split.py                    pass     pass     pass     same
net:drop_monitor_tests.sh                    skip     skip     skip     same
net:fcnal-test.sh                            pass     pass     pass     same
net:fib-onlink-tests.sh                      pass     pass     pass     same
net:fib_rule_tests.sh                        fail     fail     fail     same
net:fib_tests.sh                             pass     pass     pass     same
net:gre_gso.sh                               pass     pass     pass     same
net:icmp_redirect.sh                         pass     pass     pass     same
net:ip6_gre_headroom.sh                      pass     pass     pass     same
net:ipv6_flowlabel.sh                        pass     pass     pass     same
net:l2tp.sh                                  pass     pass     pass     same
net:msg_zerocopy.sh                          fail     fail     fail     same
net:netdevice.sh                             pass     pass     pass     same
net:pmtu.sh                                  pass     pass     pass     same
net:psock_snd.sh                             fail     fail     fail     same
net:reuseaddr_conflict                       pass     pass     pass     same
net:reuseport_bpf                            pass     pass     pass     same
net:reuseport_bpf_cpu                        pass     pass     pass     same
net:reuseport_bpf_numa                       pass     pass     pass     same
net:reuseport_dualstack                      pass     pass     pass     same
net:rtnetlink.sh                             skip     skip     skip     same
net:run_afpackettests                        pass     pass     pass     same
net:run_netsocktests                         pass     pass     pass     same
net:rxtimestamp.sh                           pass     pass     pass     same
net:so_txtime.sh                             fail     fail     fail     same
net:test_bpf.sh                              pass     pass     pass     same
net:test_vxlan_fdb_changelink.sh             pass     pass     pass     same
net:tls                                      pass     pass     pass     same
net:traceroute.sh                            pass     pass     pass     same
net:udpgro.sh                                fail     fail     fail     same
net:udpgro_bench.sh                          fail     fail     fail     same
net:udpgso.sh                                pass     pass     pass     same
net:veth.sh                                  fail     fail     fail     same
net:vrf-xfrm-tests.sh                        pass     pass     pass     same
netfilter:conntrack_icmp_related.sh          fail     fail     fail     same
netfilter:conntrack_tcp_unreplied.sh         fail     fail     fail     same
netfilter:ipvs.sh                            skip     skip     skip     same
netfilter:nft_flowtable.sh                   fail     fail     fail     same
netfilter:nft_meta.sh                        pass     pass     pass     same
netfilter:nft_nat.sh                         skip     skip     skip     same
netfilter:nft_queue.sh                       skip     skip     skip     same
nsfs:owner                                   pass     pass     pass     same
nsfs:pidns                                   pass     pass     pass     same
proc:fd-001-lookup                           pass     pass     pass     same
proc:fd-002-posix-eq                         pass     pass     pass     same
proc:fd-003-kthread                          pass     pass     pass     same
proc:proc-loadavg-001                        pass     pass     pass     same
proc:proc-self-map-files-001                 pass     pass     pass     same
proc:proc-self-map-files-002                 fail     fail     fail     same
proc:proc-self-syscall                       pass     pass     pass     same
proc:proc-self-wchan                         pass     pass     pass     same
proc:proc-uptime-001                         pass     pass     pass     same
proc:proc-uptime-002                         pass     pass     pass     same
proc:read                                    pass     pass     pass     same
proc:setns-dcache                            fail     fail     fail     same
pstore:pstore_post_reboot_tests              skip     skip     skip     same
pstore:pstore_tests                          fail     fail     fail     same
ptrace:peeksiginfo                           pass     pass     pass     same
ptrace:vmaccess                              fail     fail     fail     same
rseq:basic_percpu_ops_test                   pass     pass     pass     same
rseq:basic_test                              pass     pass     pass     same
rseq:param_test                              pass     pass     pass     same
rseq:param_test_benchmark                    pass     pass     pass     same
rseq:param_test_compare_twice                pass     pass     pass     same
rseq:run_param_test.sh                       fail     fail     fail     same
sgx:test_sgx                                 fail     fail     fail     same
sigaltstack:sas                              pass     pass     pass     same
size:get_size                                pass     pass     pass     same
splice:default_file_splice_read.sh           pass     pass     pass     same
static_keys:test_static_keys.sh              skip     skip     skip     same
tc-testing:tdc.sh                            pass     pass     pass     same
timens:clock_nanosleep                       pass     pass     pass     same
timens:exec                                  pass     pass     pass     same
timens:procfs                                pass     pass     pass     same
timens:timens                                pass     pass     pass     same
timens:timer                                 pass     pass     pass     same
timens:timerfd                               pass     pass     pass     same
timers:inconsistency-check                   fail     fail     fail     same
timers:mqueue-lat                            pass     pass     pass     same
timers:nanosleep                             pass     pass     pass     same
timers:nsleep-lat                            fail     fail     fail     same
timers:posix_timers                          pass     pass     pass     same
timers:rtcpie                                pass     pass     pass     same
timers:set-timer-lat                         fail     fail     fail     same
timers:threadtest                            pass     pass     pass     same
tpm2:test_smoke.sh                           fail     fail     fail     same
tpm2:test_space.sh                           fail     fail     fail     same
vm:run_vmtests                               fail     fail     fail     same
x86:amx_64                                   fail     fail     fail     same
x86:check_initial_reg_state_64               pass     pass     pass     same
x86:corrupt_xstate_header_64                 pass     pass     pass     same
x86:fsgsbase_64                              pass     pass     pass     same
x86:fsgsbase_restore_64                      pass     pass     pass     same
x86:ioperm_64                                pass     pass     pass     same
x86:iopl_64                                  pass     pass     pass     same
x86:mov_ss_trap_64                           pass     pass     pass     same
x86:mpx-mini-test_64                         fail     fail     fail     same
x86:protection_keys_64                       pass     pass     pass     same
x86:sigaltstack_64                           pass     pass     pass     same
x86:sigreturn_64                             pass     pass     pass     same
x86:single_step_syscall_64                   pass     pass     pass     same
x86:syscall_nt_64                            pass     pass     pass     same
x86:sysret_rip_64                            pass     pass     pass     same
x86:sysret_ss_attrs_64                       pass     pass     pass     same
x86:test_mremap_vdso_64                      pass     pass     pass     same
x86:test_vdso_64                             pass     pass     pass     same
x86:test_vsyscall_64                         pass     pass     pass     same
zram:zram.sh                                 pass     pass     pass     same

pvts-mat added 11 commits March 19, 2026 14:35
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>
@pvts-mat pvts-mat force-pushed the ciqlts8_6-CVE-2025-38449 branch from d7da957 to 5d4458e Compare March 19, 2026 13:35
@pvts-mat
Copy link
Contributor Author

^ Rebased to the recent ciqlts8_6 ^

@github-actions
Copy link

🤖 Validation Checks In Progress Workflow run: https://github.com/ctrliq/kernel-src-tree/actions/runs/23318778679

@github-actions
Copy link

🔍 Interdiff Analysis

  • ⚠️ PR commit 733fd3030f0f (drm/gud: Map framebuffer BOs with drm_gem_fb_vmap()) → upstream 0029d3182969
    Differences found:
================================================================================
*    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);
  • ⚠️ PR commit 6a05bd2d3cbc (drm/vkms: Map output framebuffer BOs with drm_gem_fb_vmap()) → upstream 50fff206c5e3
    Differences found:
================================================================================
*    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>
  • ⚠️ PR commit d043e5821128 (drm/gem: Ignore color planes that are unused by framebuffer format) → upstream 746b9c62cc86
    Differences found:
================================================================================
*    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)
  • ⚠️ PR commit e1936c8fc440 (drm/gem: Acquire references on GEM handles for framebuffers) → upstream 5307dce878d4
    Differences found:
================================================================================
*    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
  • ⚠️ PR commit 5d4458e59bc1 (drm/framebuffer: Acquire internal references on GEM handles) → upstream f6bfc9afc751
    Differences found:
================================================================================
*    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.

@github-actions
Copy link

JIRA PR Check Results

11 commit(s) with issues found:

Commit 5d4458e59bc1

Summary: drm/framebuffer: Acquire internal references on GEM handles

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Commit e1936c8fc440

Summary: drm/gem: Acquire references on GEM handles for framebuffers

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Commit d043e5821128

Summary: drm/gem: Ignore color planes that are unused by framebuffer format

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Commit 9ae54e78080e

Summary: drm/gem: Share code between drm_gem_fb_{begin,end}_cpu_access()

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Commit 2c9e7c72aedc

Summary: drm/gem: Provide offset-adjusted framebuffer BO mappings

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Commit 6a05bd2d3cbc

Summary: drm/vkms: Map output framebuffer BOs with drm_gem_fb_vmap()

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Commit 733fd3030f0f

Summary: drm/gud: Map framebuffer BOs with drm_gem_fb_vmap()

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Commit 6793cbe278ed

Summary: drm/gem: Clear mapping addresses for unused framebuffer planes

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Commit 2a208f402126

Summary: drm/gem: Provide drm_gem_fb_{vmap,vunmap}()

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Commit d36175441711

Summary: drm: Define DRM_FORMAT_MAX_PLANES

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Commit 8328cd7213db

Summary: drm/gem: Provide drm_gem_fb_{begin,end}_cpu_access() helpers

❌ Errors:

  • VULN-136703: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-136703: No time logged - please log time manually

Summary: Checked 11 commit(s) total.

@github-actions
Copy link

Validation checks completed with issues View full results: https://github.com/ctrliq/kernel-src-tree/actions/runs/23318778679

@PlaidCat PlaidCat requested review from a team March 20, 2026 19:42
Copy link
Collaborator

@bmastbergen bmastbergen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥌

Copy link
Collaborator

@PlaidCat PlaidCat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@kerneltoast did you want to look at anything here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants