CVE-2026-98414

Estado: RecibidaSin puntuar—
Gravedad—Sin puntuar
Probabilidad de explotación0.21 %mayor que el 10 % de las CVE
Explotación activaNono figura en el catálogo de CISA
Exploit públicoNo conocidosin código público localizado

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:

memcg: evitar cargar el memcg raíz desde obj_cgroup_charge_pages()

obj_cgroup_charge_pages() resuelve el objcg a su memcg y llama a try_charge_memcg(), que no cortocircuita el memcg raíz. Ese memcg puede ser el memcg raíz: obj_cgroup_is_root() refleja el memcg para el que se creó el objcg y nunca se actualiza, mientras que memcg_reparent_objcgs() sí redirige objcg->memcg al padre al eliminar el directorio (rmdir). Por tanto, un objcg de un hijo en proceso de eliminación de la raíz pasa todos los filtros de obj_cgroup_is_root() pero se resuelve al memcg raíz.

Leer descripción completaMostrar menos

Los folios conservan el objcg con el que se cargaron, por lo que esto es fácil de alcanzar mediante zswap: asignar memoria anónima en un cgroup, mover la tarea fuera, eliminar el cgroup y, a continuación, escribir en memory.reclaim del cgroup raíz. Los folios recuperados se cargan a través del objcg reasignado y terminan en refill_stock() con el memcg raíz:

Más allá de la advertencia, la carga es asimétrica: obj_cgroup_uncharge_pages() omite refill_stock() para el memcg raíz, por lo que el contador de páginas de la raíz crece y nunca se descarga. No es visible para el usuario, ya que memory.current no se expone en la raíz, pero constituye una fuga.

Se utiliza try_charge(), que retorna pronto para el memcg raíz, restaurando la simetría con obj_cgroup_uncharge_pages().

La secuencia anterior se incluyó en un reproductor independiente (zswap activado, swap en un disco virtio, 512 MB de memoria anónima asignada dentro de un hijo del cgroup raíz, luego la tarea se migró al cgroup raíz, se eliminó el hijo y después "echo 600M swappiness=max > memory.reclaim" en la raíz) y se ejecutó en una VM con CONFIG_DEBUG_VM=y. Reproduce la advertencia en la primera escritura en zswap de un folio reasignado, con la misma cadena de llamadas que el informe. Con este parche aplicado, la advertencia desaparece mientras que el número de escrituras en zswap durante la ejecución no cambia, por lo que la misma ruta sigue ejercitándose. Las pruebas de selftests de cgroup test_zswap, test_kmem y test_memcontrol no muestran nuevos fallos.

Detalles técnicos trazas, registros y código del informe original
  WARNING: mm/memcontrol.c:2198 at refill_stock+0x644/0x940
   refill_stock+0x644/0x940
   try_charge_memcg+0x12d6/0x1570
   __obj_cgroup_charge+0x35/0xf0
   obj_cgroup_charge+0x1de/0x210
   obj_cgroup_charge_zswap+0x83/0x270
   zswap_store+0x1620/0x2000
   swap_writeout+0x94c/0x14c0
   shrink_folio_list+0x3388/0x52b0
   [...]
   try_to_free_mem_cgroup_pages+0x30d/0x830
   user_proactive_reclaim+0x504/0x840
   memory_reclaim+0x1f/0x30

Traducción automática del texto original de NVD (en inglés).

CVSS

NVD no ha asignado puntuación CVSS a esta CVE (habitual desde el cambio de política de abril de 2026).

Probabilidad de explotación (EPSS)

Probabilidad de explotación en los próximos 30 días
0.21 %
Percentil entre todas las CVEs puntuadas
10
Fecha de la puntuación
21/10/2026

EPSS (Exploit Prediction Scoring System, de FIRST) estima la probabilidad de que una vulnerabilidad sea explotada en 30 días. Complementa a CVSS (impacto) y a CISA KEV (explotación confirmada).

Tecnologías afectadas (1)

⚠ Inferidas por IA a partir de la descripción — NVD aún no ha analizado esta CVE; no son CPE verificados.

Referencias

Mostrar las 3 referencias

JSON original (NVD)

Mostrar
{
  "id": "CVE-2026-98414",
  "cveTags": [],
  "metrics": {},
  "affected": [
    {
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
      "affectedData": [
        {
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "product": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "20d6c17252282c3af261d1cde8e34def1b2458c8",
              "lessThan": "d5cdff14c385bf42d03c0dd4c3e88ddf4c28b8a9",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "20d6c17252282c3af261d1cde8e34def1b2458c8",
              "lessThan": "ecc03877b1b05cb1e3a72175ccb868383eccc518",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "20d6c17252282c3af261d1cde8e34def1b2458c8",
              "lessThan": "6e673d0879ef78c395cfe0d3ba316690a60055d8",
              "versionType": "git"
            }
          ],
          "programFiles": [
            "mm/memcontrol.c"
          ],
          "defaultStatus": "unaffected"
        },
        {
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "product": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "6.15"
            },
            {
              "status": "unaffected",
              "version": "0",
              "lessThan": "6.15",
              "versionType": "semver"
            },
            {
              "status": "unaffected",
              "version": "6.18.54",
              "versionType": "semver",
              "lessThanOrEqual": "6.18.*"
            },
            {
              "status": "unaffected",
              "version": "7.2.8",
              "versionType": "semver",
              "lessThanOrEqual": "7.2.*"
            },
            {
              "status": "unaffected",
              "version": "7.3",
              "versionType": "original_commit_for_fix",
              "lessThanOrEqual": "*"
            }
          ],
          "programFiles": [
            "mm/memcontrol.c"
          ],
          "defaultStatus": "affected"
        }
      ]
    }
  ],
  "published": "2026-10-14T14:17:52.673",
  "references": [
    {
      "url": "https://git.kernel.org/stable/c/6e673d0879ef78c395cfe0d3ba316690a60055d8",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/d5cdff14c385bf42d03c0dd4c3e88ddf4c28b8a9",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/ecc03877b1b05cb1e3a72175ccb868383eccc518",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    }
  ],
  "vulnStatus": "Received",
  "descriptions": [
    {
      "lang": "en",
      "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nmemcg: avoid charging the root memcg from obj_cgroup_charge_pages()\n\nobj_cgroup_charge_pages() resolves the objcg to its memcg and calls\ntry_charge_memcg(), which does not short circuit the root memcg.  That\nmemcg can be the root memcg: obj_cgroup_is_root() reflects the memcg the\nobjcg was created for and is never updated, while memcg_reparent_objcgs()\ndoes redirect objcg->memcg to the parent on rmdir.  An objcg of a dying\nchild of root therefore passes every obj_cgroup_is_root() filter but\nresolves to the root memcg.\n\nFolios keep the objcg they were charged with, so this is easy to reach\nthrough zswap: allocate anon memory in a cgroup, move the task out, remove\nthe cgroup, then write to the root cgroup's memory.reclaim.  The reclaimed\nfolios are charged through the reparented objcg and end up in\nrefill_stock() with the root memcg:\n\n  WARNING: mm/memcontrol.c:2198 at refill_stock+0x644/0x940\n   refill_stock+0x644/0x940\n   try_charge_memcg+0x12d6/0x1570\n   __obj_cgroup_charge+0x35/0xf0\n   obj_cgroup_charge+0x1de/0x210\n   obj_cgroup_charge_zswap+0x83/0x270\n   zswap_store+0x1620/0x2000\n   swap_writeout+0x94c/0x14c0\n   shrink_folio_list+0x3388/0x52b0\n   [...]\n   try_to_free_mem_cgroup_pages+0x30d/0x830\n   user_proactive_reclaim+0x504/0x840\n   memory_reclaim+0x1f/0x30\n\nBeyond the warning, the charge is asymmetric: obj_cgroup_uncharge_pages()\nskips refill_stock() for the root memcg, so the root's page counter grows\nand is never uncharged.  It is not user visible, since memory.current is\nnot exposed on the root, but it is a leak.\n\nUse try_charge(), which returns early for the root memcg, restoring the\nsymmetry with obj_cgroup_uncharge_pages().\n\nThe above sequence was scripted into a standalone reproducer (zswap on,\nswap on a virtio disk, 512MB of anon memory faulted in inside a child of\nthe root cgroup, the task then migrated to the root cgroup, the child\nremoved, followed by \"echo 600M swappiness=max > memory.reclaim\" on the\nroot) and run in a CONFIG_DEBUG_VM=y VM.  It reproduces the splat on the\nfirst zswap store of a reparented folio, with the same call chain as the\nreport.  With this patch applied the splat is gone while the zswap store\ncount over the run is unchanged, so the same path is still exercised. \ncgroup selftests test_zswap, test_kmem and test_memcontrol show no new\nfailures."
    }
  ],
  "lastModified": "2026-10-19T10:18:46.707",
  "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
}