{
  "affected": [
    {
      "ecosystem_specific": {
        "urgency": "not yet assigned"
      },
      "package": {
        "ecosystem": "Debian:13",
        "name": "linux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "6.12.96-1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "ecosystem_specific": {
        "urgency": "not yet assigned"
      },
      "package": {
        "ecosystem": "Debian:14",
        "name": "linux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "7.1.4-1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "ecosystem_specific": {
        "urgency": "not yet assigned"
      },
      "package": {
        "ecosystem": "Debian:12",
        "name": "linux-6.12"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "6.12.100-1~deb12u1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "details": "In the Linux kernel, the following vulnerability has been resolved:  mm: shrinker: fix shrinker_info teardown race with expansion  expand_shrinker_info() iterates all visible memcgs under shrinker_mutex, including memcgs that have not finished -\u003ecss_online() yet.  Once pn-\u003eshrinker_info has been published, teardown must stay serialized with expand_shrinker_info() until that memcg is either fully online or no longer visible to iteration.  Today alloc_shrinker_info() breaks that rule by dropping shrinker_mutex before freeing a partially initialized shrinker_info array, which may cause the following race:  CPU0                   CPU1 ====                   ====  css_create --\u003e list_add_tail_rcu(\u0026css-\u003esibling, \u0026parent_css-\u003echildren);     online_css     --\u003e mem_cgroup_css_online         --\u003e alloc_shrinker_info             --\u003e alloc node0 info                 rcu_assign_pointer(C-\u003enode0-\u003eshrinker_info, old0)                 alloc node1 info -\u003e FAIL -\u003e goto err                 mutex_unlock(shrinker_mutex)                         shrinker_alloc()                        --\u003e shrinker_memcg_alloc                            --\u003e mutex_lock(shrinker_mutex)                                expand_shrinker_info                                --\u003e mem_cgroup_iter see the memcg                                    expand_one_shrinker_info                                    --\u003e old0 = C-\u003enode0-\u003eshrinker_info                                        memcpy(new-\u003eunit, old0-\u003eunit, ...);                  free_shrinker_info                 --\u003e kvfree(old0);                                         /* double free !! */                                        kvfree_rcu(old0, rcu);  The same problem exists later in mem_cgroup_css_online().  If alloc_shrinker_info() succeeds but a subsequent objcg allocation fails, the free_objcg -\u003e free_shrinker_info() unwind path tears down the already published pn-\u003eshrinker_info arrays without shrinker_mutex.  The expand_one_shrinker_info() can race with that teardown in the same way, leading to use-after-free or double-free of the old shrinker_info.  Fix this by serializing shrinker_info teardown with shrinker_mutex, and by keeping alloc_shrinker_info() error cleanup inside the locked section.",
  "id": "DEBIAN-CVE-2026-64418",
  "modified": "2026-09-14T16:47:29.960530522Z",
  "published": "2026-07-25T10:17:25.727Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://security-tracker.debian.org/tracker/CVE-2026-64418"
    }
  ],
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "upstream": [
    "CVE-2026-64418"
  ]
}