CVE-2025-37999 (GCVE-0-2025-37999)

Vulnerability from cvelistv5 – Published: 2025-05-29 13:15 – Updated: 2026-05-11 21:19
VLAI
Title
fs/erofs/fileio: call erofs_onlinefolio_split() after bio_add_folio()
Summary
In the Linux kernel, the following vulnerability has been resolved: fs/erofs/fileio: call erofs_onlinefolio_split() after bio_add_folio() If bio_add_folio() fails (because it is full), erofs_fileio_scan_folio() needs to submit the I/O request via erofs_fileio_rq_submit() and allocate a new I/O request with an empty `struct bio`. Then it retries the bio_add_folio() call. However, at this point, erofs_onlinefolio_split() has already been called which increments `folio->private`; the retry will call erofs_onlinefolio_split() again, but there will never be a matching erofs_onlinefolio_end() call. This leaves the folio locked forever and all waiters will be stuck in folio_wait_bit_common(). This bug has been added by commit ce63cb62d794 ("erofs: support unencoded inodes for fileio"), but was practically unreachable because there was room for 256 folios in the `struct bio` - until commit 9f74ae8c9ac9 ("erofs: shorten bvecs[] for file-backed mounts") which reduced the array capacity to 16 folios. It was now trivial to trigger the bug by manually invoking readahead from userspace, e.g.: posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED); This should be fixed by invoking erofs_onlinefolio_split() only after bio_add_folio() has succeeded. This is safe: asynchronous completions invoking erofs_onlinefolio_end() will not unlock the folio because erofs_fileio_scan_folio() is still holding a reference to be released by erofs_onlinefolio_end() at the end.
Impacted products
Vendor Product Version CPE status
Linux Linux Affected: ce63cb62d794c98c7631c2296fa845f2a8d0a4a1 , < 61e0fc3312309867e5a3495329dad0286d2a5703 (git)
Affected: ce63cb62d794c98c7631c2296fa845f2a8d0a4a1 , < c26076197df348c84cc23e5962d61902e072a0f5 (git)
Affected: ce63cb62d794c98c7631c2296fa845f2a8d0a4a1 , < bbfe756dc3062c1e934f06e5ba39c239aa953b92 (git)
guessed Create a notification for this product.
Linux Linux Affected: 6.12
Unaffected: 0 , < 6.12 (semver)
Unaffected: 6.12.29 , ≤ 6.12.* (semver)
Unaffected: 6.14.7 , ≤ 6.14.* (semver)
Unaffected: 6.15 , ≤ * (original_commit_for_fix)
guessed Create a notification for this product.
Show details on NVD website

{
  "containers": {
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "fs/erofs/fileio.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "61e0fc3312309867e5a3495329dad0286d2a5703",
              "status": "affected",
              "version": "ce63cb62d794c98c7631c2296fa845f2a8d0a4a1",
              "versionType": "git"
            },
            {
              "lessThan": "c26076197df348c84cc23e5962d61902e072a0f5",
              "status": "affected",
              "version": "ce63cb62d794c98c7631c2296fa845f2a8d0a4a1",
              "versionType": "git"
            },
            {
              "lessThan": "bbfe756dc3062c1e934f06e5ba39c239aa953b92",
              "status": "affected",
              "version": "ce63cb62d794c98c7631c2296fa845f2a8d0a4a1",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "fs/erofs/fileio.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "6.12"
            },
            {
              "lessThan": "6.12",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.12.*",
              "status": "unaffected",
              "version": "6.12.29",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.14.*",
              "status": "unaffected",
              "version": "6.14.7",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "6.15",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.12.29",
                  "versionStartIncluding": "6.12",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.14.7",
                  "versionStartIncluding": "6.12",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.15",
                  "versionStartIncluding": "6.12",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nfs/erofs/fileio: call erofs_onlinefolio_split() after bio_add_folio()\n\nIf bio_add_folio() fails (because it is full),\nerofs_fileio_scan_folio() needs to submit the I/O request via\nerofs_fileio_rq_submit() and allocate a new I/O request with an empty\n`struct bio`.  Then it retries the bio_add_folio() call.\n\nHowever, at this point, erofs_onlinefolio_split() has already been\ncalled which increments `folio-\u003eprivate`; the retry will call\nerofs_onlinefolio_split() again, but there will never be a matching\nerofs_onlinefolio_end() call.  This leaves the folio locked forever\nand all waiters will be stuck in folio_wait_bit_common().\n\nThis bug has been added by commit ce63cb62d794 (\"erofs: support\nunencoded inodes for fileio\"), but was practically unreachable because\nthere was room for 256 folios in the `struct bio` - until commit\n9f74ae8c9ac9 (\"erofs: shorten bvecs[] for file-backed mounts\") which\nreduced the array capacity to 16 folios.\n\nIt was now trivial to trigger the bug by manually invoking readahead\nfrom userspace, e.g.:\n\n posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED);\n\nThis should be fixed by invoking erofs_onlinefolio_split() only after\nbio_add_folio() has succeeded.  This is safe: asynchronous completions\ninvoking erofs_onlinefolio_end() will not unlock the folio because\nerofs_fileio_scan_folio() is still holding a reference to be released\nby erofs_onlinefolio_end() at the end."
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-05-11T21:19:21.337Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/61e0fc3312309867e5a3495329dad0286d2a5703"
        },
        {
          "url": "https://git.kernel.org/stable/c/c26076197df348c84cc23e5962d61902e072a0f5"
        },
        {
          "url": "https://git.kernel.org/stable/c/bbfe756dc3062c1e934f06e5ba39c239aa953b92"
        }
      ],
      "title": "fs/erofs/fileio: call erofs_onlinefolio_split() after bio_add_folio()",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2025-37999",
    "datePublished": "2025-05-29T13:15:56.825Z",
    "dateReserved": "2025-04-16T04:51:23.976Z",
    "dateUpdated": "2026-05-11T21:19:21.337Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "vulnerability-lookup:meta": {
    "epss": {
      "cve": "CVE-2025-37999",
      "date": "2026-09-15",
      "epss": "0.00174",
      "percentile": "0.0706"
    },
    "nvd": "{\"cve\":{\"id\":\"CVE-2025-37999\",\"sourceIdentifier\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"published\":\"2025-05-29T14:15:36.597\",\"lastModified\":\"2026-06-17T09:15:51.227\",\"vulnStatus\":\"Analyzed\",\"cveTags\":[],\"descriptions\":[{\"lang\":\"en\",\"value\":\"In the Linux kernel, the following vulnerability has been resolved:\\n\\nfs/erofs/fileio: call erofs_onlinefolio_split() after bio_add_folio()\\n\\nIf bio_add_folio() fails (because it is full),\\nerofs_fileio_scan_folio() needs to submit the I/O request via\\nerofs_fileio_rq_submit() and allocate a new I/O request with an empty\\n`struct bio`.  Then it retries the bio_add_folio() call.\\n\\nHowever, at this point, erofs_onlinefolio_split() has already been\\ncalled which increments `folio-\u003eprivate`; the retry will call\\nerofs_onlinefolio_split() again, but there will never be a matching\\nerofs_onlinefolio_end() call.  This leaves the folio locked forever\\nand all waiters will be stuck in folio_wait_bit_common().\\n\\nThis bug has been added by commit ce63cb62d794 (\\\"erofs: support\\nunencoded inodes for fileio\\\"), but was practically unreachable because\\nthere was room for 256 folios in the `struct bio` - until commit\\n9f74ae8c9ac9 (\\\"erofs: shorten bvecs[] for file-backed mounts\\\") which\\nreduced the array capacity to 16 folios.\\n\\nIt was now trivial to trigger the bug by manually invoking readahead\\nfrom userspace, e.g.:\\n\\n posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED);\\n\\nThis should be fixed by invoking erofs_onlinefolio_split() only after\\nbio_add_folio() has succeeded.  This is safe: asynchronous completions\\ninvoking erofs_onlinefolio_end() will not unlock the folio because\\nerofs_fileio_scan_folio() is still holding a reference to be released\\nby erofs_onlinefolio_end() at the end.\"},{\"lang\":\"es\",\"value\":\"En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: fs/erofs/fileio: llamar a erofs_onlinefolio_split() despu\u00e9s de bio_add_folio(). Si bio_add_folio() falla (porque est\u00e1 lleno), erofs_fileio_scan_folio() debe enviar la solicitud de E/S mediante erofs_fileio_rq_submit() y asignar una nueva solicitud de E/S con un `struct bio` vac\u00edo. Luego, vuelve a intentar la llamada a bio_add_folio(). Sin embargo, en este punto, ya se ha llamado a erofs_onlinefolio_split(), lo que incrementa `folio-\u0026gt;private`; el reintento llamar\u00e1 a erofs_onlinefolio_split() de nuevo, pero nunca habr\u00e1 una llamada erofs_onlinefolio_end() coincidente. Esto deja el folio bloqueado para siempre y todos los que esperan quedar\u00e1n atascados en folio_wait_bit_common(). Este error se a\u00f1adi\u00f3 con el commit ce63cb62d794 (\\\"erofs: compatibilidad con inodos no codificados para fileio\\\"), pero era pr\u00e1cticamente imposible de solucionar porque hab\u00eda espacio para 256 folios en la estructura `struct bio`, hasta el commit 9f74ae8c9ac9 (\\\"erofs: acortar bvecs[] para montajes con respaldo de archivo\\\"), que redujo la capacidad del array a 16 folios. Ahora era f\u00e1cil activar el error invocando manualmente la lectura anticipada desde el espacio de usuario, por ejemplo: posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED); Esto deber\u00eda solucionarse invocando erofs_onlinefolio_split() solo despu\u00e9s de que bio_add_folio() se haya ejecutado correctamente. Esto es seguro: las finalizaciones asincr\u00f3nicas que invocan erofs_onlinefolio_end() no desbloquear\u00e1n el folio porque erofs_fileio_scan_folio() todav\u00eda contiene una referencia que erofs_onlinefolio_end() liberar\u00e1 al final.\"}],\"affected\":[{\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"affectedData\":[{\"vendor\":\"Linux\",\"product\":\"Linux\",\"defaultStatus\":\"unaffected\",\"programFiles\":[\"fs/erofs/fileio.c\"],\"repo\":\"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git\",\"versions\":[{\"version\":\"ce63cb62d794c98c7631c2296fa845f2a8d0a4a1\",\"lessThan\":\"61e0fc3312309867e5a3495329dad0286d2a5703\",\"versionType\":\"git\",\"status\":\"affected\"},{\"version\":\"ce63cb62d794c98c7631c2296fa845f2a8d0a4a1\",\"lessThan\":\"c26076197df348c84cc23e5962d61902e072a0f5\",\"versionType\":\"git\",\"status\":\"affected\"},{\"version\":\"ce63cb62d794c98c7631c2296fa845f2a8d0a4a1\",\"lessThan\":\"bbfe756dc3062c1e934f06e5ba39c239aa953b92\",\"versionType\":\"git\",\"status\":\"affected\"}]},{\"vendor\":\"Linux\",\"product\":\"Linux\",\"defaultStatus\":\"affected\",\"programFiles\":[\"fs/erofs/fileio.c\"],\"repo\":\"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git\",\"versions\":[{\"version\":\"6.12\",\"status\":\"affected\"},{\"version\":\"0\",\"lessThan\":\"6.12\",\"versionType\":\"semver\",\"status\":\"unaffected\"},{\"version\":\"6.12.29\",\"lessThanOrEqual\":\"6.12.*\",\"versionType\":\"semver\",\"status\":\"unaffected\"},{\"version\":\"6.14.7\",\"lessThanOrEqual\":\"6.14.*\",\"versionType\":\"semver\",\"status\":\"unaffected\"},{\"version\":\"6.15\",\"lessThanOrEqual\":\"*\",\"versionType\":\"original_commit_for_fix\",\"status\":\"unaffected\"}]}]}],\"metrics\":{\"cvssMetricV31\":[{\"source\":\"nvd@nist.gov\",\"type\":\"Primary\",\"cvssData\":{\"version\":\"3.1\",\"vectorString\":\"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H\",\"baseScore\":5.5,\"baseSeverity\":\"MEDIUM\",\"attackVector\":\"LOCAL\",\"attackComplexity\":\"LOW\",\"privilegesRequired\":\"LOW\",\"userInteraction\":\"NONE\",\"scope\":\"UNCHANGED\",\"confidentialityImpact\":\"NONE\",\"integrityImpact\":\"NONE\",\"availabilityImpact\":\"HIGH\"},\"exploitabilityScore\":1.8,\"impactScore\":3.6}]},\"weaknesses\":[{\"source\":\"nvd@nist.gov\",\"type\":\"Primary\",\"description\":[{\"lang\":\"en\",\"value\":\"NVD-CWE-noinfo\"}]}],\"configurations\":[{\"nodes\":[{\"operator\":\"OR\",\"negate\":false,\"cpeMatch\":[{\"vulnerable\":true,\"criteria\":\"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*\",\"versionStartIncluding\":\"6.12\",\"versionEndExcluding\":\"6.12.29\",\"matchCriteriaId\":\"69281F47-5478-4C16-818E-9DAC6D962CB6\"},{\"vulnerable\":true,\"criteria\":\"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*\",\"versionStartIncluding\":\"6.13\",\"versionEndExcluding\":\"6.14.7\",\"matchCriteriaId\":\"5715A6F5-A34A-4B27-8A64-82825E963995\"},{\"vulnerable\":true,\"criteria\":\"cpe:2.3:o:linux:linux_kernel:6.15:rc1:*:*:*:*:*:*\",\"matchCriteriaId\":\"8D465631-2980-487A-8E65-40AE2B9F8ED1\"},{\"vulnerable\":true,\"criteria\":\"cpe:2.3:o:linux:linux_kernel:6.15:rc2:*:*:*:*:*:*\",\"matchCriteriaId\":\"4C9D071F-B28E-46EC-AC61-22B913390211\"},{\"vulnerable\":true,\"criteria\":\"cpe:2.3:o:linux:linux_kernel:6.15:rc3:*:*:*:*:*:*\",\"matchCriteriaId\":\"13FC0DDE-E513-465E-9E81-515702D49B74\"},{\"vulnerable\":true,\"criteria\":\"cpe:2.3:o:linux:linux_kernel:6.15:rc4:*:*:*:*:*:*\",\"matchCriteriaId\":\"8C7B5B0E-4EEB-48F5-B4CF-0935A7633845\"},{\"vulnerable\":true,\"criteria\":\"cpe:2.3:o:linux:linux_kernel:6.15:rc5:*:*:*:*:*:*\",\"matchCriteriaId\":\"2D240580-3048-49B2-9E27-F115A9DF8224\"}]}]}],\"references\":[{\"url\":\"https://git.kernel.org/stable/c/61e0fc3312309867e5a3495329dad0286d2a5703\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"tags\":[\"Patch\"]},{\"url\":\"https://git.kernel.org/stable/c/bbfe756dc3062c1e934f06e5ba39c239aa953b92\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"tags\":[\"Patch\"]},{\"url\":\"https://git.kernel.org/stable/c/c26076197df348c84cc23e5962d61902e072a0f5\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"tags\":[\"Patch\"]}]}}",
    "redhat_vex": {
      "aggregate_severity": "Moderate",
      "current_release_date": "2026-06-30T00:14:30+00:00",
      "cve": "CVE-2025-37999",
      "id": "CVE-2025-37999",
      "initial_release_date": "2025-05-29T00:00:00+00:00",
      "product_status:known_affected": "76",
      "product_status:known_not_affected": "198",
      "source": "Red Hat CSAF VEX",
      "status": "final",
      "title": "kernel: fs/erofs/fileio: call erofs_onlinefolio_split() after bio_add_folio()",
      "url": "https://security.access.redhat.com/data/csaf/v2/vex/2025/cve-2025-37999.json",
      "version": "3"
    },
    "suse_vex": {
      "aggregate_severity": "moderate",
      "current_release_date": "2026-08-28T17:03:20Z",
      "cve": "CVE-2025-37999",
      "id": "CVE-2025-37999",
      "initial_release_date": "2025-05-30T01:26:30Z",
      "product_status:known_not_affected": "505",
      "product_status:recommended": "78",
      "source": "SUSE CSAF VEX",
      "status": "interim",
      "title": "SUSE CVE CVE-2025-37999",
      "url": "https://ftp.suse.com/pub/projects/security/csaf-vex/cve-2025-37999.json",
      "version": "15"
    }
  }
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…