{"id":"CVE-2026-93121","state":"PUBLISHED","title":"usb: gadget: f_fs: Fix fence cleanup in ffs_dmabuf_transfer() error paths","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nusb: gadget: f_fs: Fix fence cleanup in ffs_dmabuf_transfer() error paths\n\nThe error paths for endpoint-disabled (ESHUTDOWN) and request-allocation\nfailure (ENOMEM) in ffs_dmabuf_transfer() jump to err_fence_put which\ncalls dma_fence_put() on the fence. However, at that point the fence has\nonly been kmalloc'd — dma_fence_init() has not been called yet, so the\nrefcount and the fence ops are uninitialized. Calling dma_fence_put() on\nsuch an object leads to undefined behavior.\n\nUse kfree() instead, since the fence is just a plain allocation at this\nstage, and rename the label to err_fence_free to reflect the actual\ncleanup action.","publishedAt":"2026-09-17T16:11:27.220Z","updatedAt":"2026-10-19T09:05:54.766Z","severity":{"score":7,"label":"High","version":"3.1","vector":"CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H","source":"Linux"},"assigner":"Linux","products":["Linux Linux"],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"7b07a2a7ca02a20124b552be96c5a56910795488","status":"affected","lessThan":"be539138d9a187af3b884525a395db10797c64f1","versionType":"git"},{"version":"7b07a2a7ca02a20124b552be96c5a56910795488","status":"affected","lessThan":"5fd8baacc7dc477df9cac61b45491840247a9b1e","versionType":"git"},{"version":"7b07a2a7ca02a20124b552be96c5a56910795488","status":"affected","lessThan":"58952c83dfe6ea3294a74734d2d1018c1120779a","versionType":"git"},{"version":"7b07a2a7ca02a20124b552be96c5a56910795488","status":"affected","lessThan":"621707dc67c9846fd876d7579ec951d92aa033f1","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/usb/gadget/function/f_fs.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"6.9","status":"affected"},{"version":"0","status":"unaffected","lessThan":"6.9","versionType":"semver"},{"version":"6.12.110","status":"unaffected","lessThanOrEqual":"6.12.*","versionType":"semver"},{"version":"6.18.52","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.2.6","status":"unaffected","lessThanOrEqual":"7.2.*","versionType":"semver"},{"version":"7.3","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/usb/gadget/function/f_fs.c"]}],"references":["https://git.kernel.org/stable/c/be539138d9a187af3b884525a395db10797c64f1","https://git.kernel.org/stable/c/5fd8baacc7dc477df9cac61b45491840247a9b1e","https://git.kernel.org/stable/c/58952c83dfe6ea3294a74734d2d1018c1120779a","https://git.kernel.org/stable/c/621707dc67c9846fd876d7579ec951d92aa033f1"],"weaknesses":[],"ingestedAt":"2026-10-29T20:13:34.582Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2026/93xxx/CVE-2026-93121.json","commit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-93121","state":"PUBLISHED","datePublished":"2026-09-17T16:11:27.220Z","dateUpdated":"2026-10-19T09:05:54.766Z","assignerShortName":"Linux","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateReserved":"2026-09-17T16:02:15.086Z"},"containers":{"cna":{"title":"usb: gadget: f_fs: Fix fence cleanup in ffs_dmabuf_transfer() error paths","descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nusb: gadget: f_fs: Fix fence cleanup in ffs_dmabuf_transfer() error paths\n\nThe error paths for endpoint-disabled (ESHUTDOWN) and request-allocation\nfailure (ENOMEM) in ffs_dmabuf_transfer() jump to err_fence_put which\ncalls dma_fence_put() on the fence. However, at that point the fence has\nonly been kmalloc'd — dma_fence_init() has not been called yet, so the\nrefcount and the fence ops are uninitialized. Calling dma_fence_put() on\nsuch an object leads to undefined behavior.\n\nUse kfree() instead, since the fence is just a plain allocation at this\nstage, and rename the label to err_fence_free to reflect the actual\ncleanup action."}],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"7b07a2a7ca02a20124b552be96c5a56910795488","status":"affected","lessThan":"be539138d9a187af3b884525a395db10797c64f1","versionType":"git"},{"version":"7b07a2a7ca02a20124b552be96c5a56910795488","status":"affected","lessThan":"5fd8baacc7dc477df9cac61b45491840247a9b1e","versionType":"git"},{"version":"7b07a2a7ca02a20124b552be96c5a56910795488","status":"affected","lessThan":"58952c83dfe6ea3294a74734d2d1018c1120779a","versionType":"git"},{"version":"7b07a2a7ca02a20124b552be96c5a56910795488","status":"affected","lessThan":"621707dc67c9846fd876d7579ec951d92aa033f1","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/usb/gadget/function/f_fs.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"6.9","status":"affected"},{"version":"0","status":"unaffected","lessThan":"6.9","versionType":"semver"},{"version":"6.12.110","status":"unaffected","lessThanOrEqual":"6.12.*","versionType":"semver"},{"version":"6.18.52","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.2.6","status":"unaffected","lessThanOrEqual":"7.2.*","versionType":"semver"},{"version":"7.3","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/usb/gadget/function/f_fs.c"]}],"references":[{"url":"https://git.kernel.org/stable/c/be539138d9a187af3b884525a395db10797c64f1"},{"url":"https://git.kernel.org/stable/c/5fd8baacc7dc477df9cac61b45491840247a9b1e"},{"url":"https://git.kernel.org/stable/c/58952c83dfe6ea3294a74734d2d1018c1120779a"},{"url":"https://git.kernel.org/stable/c/621707dc67c9846fd876d7579ec951d92aa033f1"}],"metrics":[{"cvssV3_1":{"version":"3.1","vectorString":"CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H","baseScore":7,"baseSeverity":"HIGH"},"scenarios":[{"lang":"en","value":"AV:L - The uninitialized fence is kmalloc'd and then dma_fence_put() in ffs_dmabuf_transfer(), reached only from ffs_epfile_ioctl()'s FUNCTIONFS_DMABUF_TRANSFER case after copy_from_user of usb_ffs_dmabuf_transfer_req; USB host traffic never supplies that ioctl or the fence object.\nAC:H - err_fence_put runs only when epfile->ep != ep after ffs_epfile_wait_ep() (epfile->ep is NULLed solely by ffs_func_eps_disable() from gadget set_alt/disable/unbind) or when usb_ep_alloc_request(..., GFP_ATOMIC) fails; the ioctl caller cannot invoke those gadget callbacks and cannot reliably force that small GFP_ATOMIC allocation to fail.\nPR:L - ffs_epfile_ioctl() has no capable() check; FUNCTIONFS_DMABUF_TRANSFER only needs the endpoint file open. FunctionFS inodes take uid/gid/mode from ffs_fs_parse_param() (uid=/gid=/fmode=), which deployed gadgets use to hand ep nodes to non-root daemons such as adbd.\nUI:N - The attacker issues FUNCTIONFS_DMABUF_TRANSFER themselves on an endpoint fd they already hold; ffs_epfile_wait_ep() needing a prior host SET_CONFIGURATION is ambient gadget enumeration, not a victim action at exploit time.\nS:U - dma_fence_put() on the kmalloc'd ffs_dma_fence runs dma_fence_release() in the same kernel that hosts FunctionFS, so impact stays inside that kernel's privilege boundary rather than crossing a VM or IOMMU authority.\nC:H - kmalloc_obj(*fence) is not zeroed and dma_fence_init() has not run, so fence->refcount and fence->ops are leftover heap contents; dma_fence_put() calls dma_fence_release() if the sprayed refcount is 1, which rcu_dereference()s ops and reads other fence fields.\nI:H - dma_fence_release() calls ops->release() through the uninitialized fence->ops pointer (or walks garbage cb_list in the pending-signal path); a same-cache heap spray can point ops at attacker-controlled function pointers for control-flow hijack.\nA:H - dma_fence_release() does list_empty(&fence->cb_list) and dma_fence_lock_irqsave() on uninitialized cb_list/lock and may invoke a wild ops->release(), any of which oopses or panics when the ESHUTDOWN or ENOMEM err_fence_put path runs."}]}],"providerMetadata":{"shortName":"Linux","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateUpdated":"2026-10-19T09:05:54.766Z"},"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.9","versionEndExcluding":"6.12.110"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.9","versionEndExcluding":"6.18.52"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.9","versionEndExcluding":"7.2.6"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.9","versionEndExcluding":"7.3"}]}]}],"x_generator":{"engine":"bippy-1.2.0"}}}}}