{
  "schema_version": "1.6.1",
  "id": "RPI-CVE-2025-40242",
  "modified": "2026-10-09T11:39:44Z",
  "upstream": [
    "CVE-2025-40242"
  ],
  "published": "2025-12-04T15:33:57Z",
  "summary": "gfs2: Fix unlikely race in gdlm_put_lock",
  "details": "In the Linux kernel, the following vulnerability has been resolved:\n\ngfs2: Fix unlikely race in gdlm_put_lock\n\nIn gdlm_put_lock(), there is a small window of time in which the\nDFL_UNMOUNT flag has been set but the lockspace hasn't been released,\nyet.  In that window, dlm may still call gdlm_ast() and gdlm_bast().\nTo prevent it from dereferencing freed glock objects, only free the\nglock if the lockspace has actually been released.",
  "severity": [
    {
      "type": "CVSS_V3",
      "score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H"
    }
  ],
  "affected": [
    {
      "package": {
        "ecosystem": "Raspberry Pi OS:12",
        "name": "linux"
      },
      "versions": [
        "1:6.1.47-1+rpt4"
      ],
      "ecosystem_specific": {
        "binaries": [
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-2712",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v6",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v7",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v7l",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v8",
            "binary_version": "1:6.1.47-1+rpt4"
          }
        ]
      },
      "database_specific": {
        "per_version": {
          "1:6.1.47-1+rpt4": {
            "linux_commit": "655fc658a15ae7a6f37103754adb39ba52a9a14e",
            "upstream_version": "6.1.47",
            "assessment": "commit ancestry (strak rule)",
            "upstream_fixed": "6.1.168",
            "compiled_filter": false
          }
        }
      }
    }
  ],
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://www.cve.org/CVERecord?id=CVE-2025-40242"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/5fdc1474e678eea1700aa266c0b7c2c96f81dd0d"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/4913592a3358f6ec366b8346b733d5e2360b08e1"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/279bde3bbb0ac0bad5c729dfa85983d75a5d7641"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/64c61b4ac645222fa7b724cef616c1f862a72a40"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/28c4d9bc0708956c1a736a9e49fee71b65deee81"
    }
  ],
  "database_specific": {
    "source": "https://git.kernel.org/pub/scm/linux/security/vulns.git",
    "upstream_modified": "2026-08-05T12:19:11Z",
    "severity": {
      "source": "kernel CNA",
      "cvss_v3_score": 7.0,
      "cvss_v3_severity": "High",
      "scenario": "AV:L - The window is opened by a local umount or a local filesystem withdraw, and the glock free is performed by local filesystem activity (inode eviction, glock shrinker, `glock_work_func`); the DLM bast that dereferences the freed object comes from an authenticated cluster peer on a private interconnect and cannot by itself create the dangling pointer. There is no network-facing service path into `gdlm_put_lock()`.\nAC:H - Exploitation requires winning a race whose opening the attacker does not control \u2014 `DFL_UNMOUNT` is set only by a root-driven umount or an error-driven withdraw \u2014 and additionally requires a DLM ast/bast for that exact resource to arrive after the free but before `dlm_release_lockspace()` completes, plus slab reuse after the RCU grace period. The author explicitly characterises it as an \"unlikely race\" in a \"small window of time\".\nPR:L - Once the teardown window is open (via administrator umount, cluster-manager failover, or a withdraw provoked by storage errors), an ordinary unprivileged user with access to the GFS2 mount drives the vulnerable side: normal file operations force glock disposal through `__gfs2_glock_put \u2192 lm_put_lock`, and creating inodes sprays `gfs2_glock_cachep` to groom the freed object. No capability check exists anywhere on that path.\nUI:N - The attacker only performs ordinary file operations on an already-mounted GFS2 filesystem; no victim must open a file, mount media, or take any deliberate action. The privileged unmount/withdraw is an environmental system state, accounted for in Attack Complexity rather than user interaction.\nS:U - The freed `struct gfs2_glock`, the DLM callback that writes into it, and any resulting corruption all live in the host kernel's own security authority. No hypervisor, IOMMU, or sandbox boundary is crossed.\nC:H - This is a use-after-free on a slab object whose contents the attacker can groom by reallocating glocks, and `gdlm_ast()` reads `gl->gl_flags`, `gl->gl_dstamp`, `gl->gl_name.ln_type` and the `gl->gl_name.ln_sbd` pointer out of the freed memory before the dead-lockref guard, using `ln_sbd` as a dereference target \u2014 giving an attacker-steerable kernel read primitive.\nI:H - Three distinct writes hit the freed object: DLM's `lksb->sb_status`/`sb_flags` stores, `clear_bit(GLF_BLOCKING, &gl->gl_flags)`, and `gfs2_update_stats(&gl->gl_stats, ...)`; worse, `this_cpu_ptr(gl->gl_name.ln_sbd->sd_lkstats)` turns a groomed pointer in the freed object into the destination of a read-modify-write, and a surviving lockref check leads into `gfs2_glock_complete()` and `gl->gl_ops` indirect calls \u2014 a control-flow hijack path.\nA:H - Dereferencing a freed glock from the DLM callback workqueue produces KASAN splats, oopses on garbage `ln_sbd`/`gl_ops` pointers, and `BUG()` in `gdlm_bast()` on an unrecognised mode, panicking the node. On a clustered filesystem, crashing the node also triggers fencing and cluster-wide recovery."
    }
  }
}
