CVE-2025-71074 (GCVE-0-2025-71074)
Vulnerability from cvelistv5
Published
2026-01-13 15:31
Modified
2026-08-05 12:11
Summary
In the Linux kernel, the following vulnerability has been resolved: functionfs: fix the open/removal races ffs_epfile_open() can race with removal, ending up with file->private_data pointing to freed object. There is a total count of opened files on functionfs (both ep0 and dynamic ones) and when it hits zero, dynamic files get removed. Unfortunately, that removal can happen while another thread is in ffs_epfile_open(), but has not incremented the count yet. In that case open will succeed, leaving us with UAF on any subsequent read() or write(). The root cause is that ffs->opened is misused; atomic_dec_and_test() vs. atomic_add_return() is not a good idea, when object remains visible all along. To untangle that * serialize openers on ffs->mutex (both for ep0 and for dynamic files) * have dynamic ones use atomic_inc_not_zero() and fail if we had zero ->opened; in that case the file we are opening is doomed. * have the inodes of dynamic files marked on removal (from the callback of simple_recursive_removal()) - clear ->i_private there. * have open of dynamic ones verify they hadn't been already removed, along with checking that state is FFS_ACTIVE.
Impacted products
Vendor Product Version
Linux Linux Version: ddf8abd2599491cbad959c700b90ba72a5dce8d0
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "drivers/usb/gadget/function/f_fs.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "e5bf5ee266633cb18fff6f98f0b7d59a62819eee",
              "status": "affected",
              "version": "ddf8abd2599491cbad959c700b90ba72a5dce8d0",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "drivers/usb/gadget/function/f_fs.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "2.6.35"
            },
            {
              "lessThan": "2.6.35",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "6.19",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.19",
                  "versionStartIncluding": "2.6.35",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nfunctionfs: fix the open/removal races\n\nffs_epfile_open() can race with removal, ending up with file-\u003eprivate_data\npointing to freed object.\n\nThere is a total count of opened files on functionfs (both ep0 and\ndynamic ones) and when it hits zero, dynamic files get removed.\nUnfortunately, that removal can happen while another thread is\nin ffs_epfile_open(), but has not incremented the count yet.\nIn that case open will succeed, leaving us with UAF on any subsequent\nread() or write().\n\nThe root cause is that ffs-\u003eopened is misused; atomic_dec_and_test() vs.\natomic_add_return() is not a good idea, when object remains visible all\nalong.\n\nTo untangle that\n\t* serialize openers on ffs-\u003emutex (both for ep0 and for dynamic files)\n\t* have dynamic ones use atomic_inc_not_zero() and fail if we had\nzero -\u003eopened; in that case the file we are opening is doomed.\n\t* have the inodes of dynamic files marked on removal (from the\ncallback of simple_recursive_removal()) - clear -\u003ei_private there.\n\t* have open of dynamic ones verify they hadn\u0027t been already removed,\nalong with checking that state is FFS_ACTIVE."
        }
      ],
      "metrics": [
        {
          "cvssV3_1": {
            "baseScore": 7.8,
            "baseSeverity": "HIGH",
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
            "version": "3.1"
          },
          "scenarios": [
            {
              "lang": "en",
              "value": "AV:L - The race is reached through local open, close, read, write, or ioctl operations on FunctionFS endpoint files. A USB host cannot directly invoke ffs_epfile_open(), so this is local rather than physical or network access.\nAC:L - The attacker can race opening a dynamic endpoint against closing the sole remaining ep0 descriptor and repeat the attempt with controlled threads. Both race sides and the freed allocation\u0027s endpoint-controlled size are attacker-controlled.\nPR:L - Mounting FunctionFS requires CAP_SYS_ADMIN in the initial user namespace, but endpoint opening has no capability check and uid/gid/fmode options permit delegation to non-root service accounts, as in [AOSP FunctionFS mounts](https://android.googlesource.com/device/google/gs201/%2B/587 5d29f/conf/init.gs201.usb.rc). A low-privileged local account with delegated endpoint access can therefore trigger the race.\nUI:N - The attacker independently performs endpoint configuration, concurrent open and close operations, and subsequent use of the stale descriptor without victim interaction.\nS:U - Exploitation corrupts memory within the kernel\u0027s existing security authority and constitutes ordinary local kernel compromise rather than crossing a VM or IOMMU boundary.\nC:H - The attacker-sized heap object contains numerous pointers and can be reclaimed before stale read, ioctl, or release operations, making kernel-memory disclosure through the UAF defensible.\nI:H - The stale object reaches mutex and list operations, atomic modification, xchg and kfree operations, and USB request handling, providing plausible arbitrary-write, arbitrary-free, and control-flow-hijacking primitives.\nA:H - Dereferencing the freed object, locking reclaimed mutexes, freeing attacker-influenced pointers, or triggering warnings under panic-on-warn can crash or panic the kernel."
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-08-05T12:11:53.356Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/e5bf5ee266633cb18fff6f98f0b7d59a62819eee"
        }
      ],
      "title": "functionfs: fix the open/removal races",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2025-71074",
    "datePublished": "2026-01-13T15:31:27.413Z",
    "dateReserved": "2026-01-13T15:30:19.647Z",
    "dateUpdated": "2026-08-05T12:11:53.356Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…