CVE-2026-98473

Estado: RecibidaSin puntuar—
Gravedad—Sin puntuar
Probabilidad de explotación0.17 %mayor que el 6 % 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:

s390/vfio-ap: corregir la fuga de GISC de KVM y de páginas cuando se elimina una cola de la configuración del host

Existen tres problemas relacionados en el manejo de los recursos de interrupción y de página de KVM cuando se elimina una cola de la configuración AP del host mientras está asignada a un dispositivo mediado (mdev).

Problema 1: ~~~~~~~~~ AP_RESPONSE_Q_NOT_AVAIL no se gestiona en vfio_ap_mdev_reset_queue()

Cuando el bus AP elimina un dispositivo de cola cuyo adaptador o dominio se ha retirado de la configuración AP del host, se llama a vfio_ap_mdev_remove_queue().

Leer descripción completaMostrar menos

Si la cola sigue en la configuración AP del host en ese momento, se llama a vfio_ap_mdev_reset_queue(), que emite un PQAP(ZAPQ). Como el adaptador ya no está en la configuración del host, ap_zapq() devuelve AP_RESPONSE_Q_NOT_AVAIL (0x01). Este código de respuesta no se gestiona en la sentencia switch de vfio_ap_mdev_reset_queue() y cae en el caso por defecto, que emite un WARN pero no llama a vfio_ap_free_aqic_resources(). En consecuencia, si el invitado habilitó el manejo de interrupciones para la cola, se filtran tanto el registro GISC de KVM como la página de invitado fijada en memoria que contiene el byte indicador de notificación (NIB).

Esto se corrige añadiendo AP_RESPONSE_Q_NOT_AVAIL al mismo caso que AP_RESPONSE_DECONFIGURED y AP_RESPONSE_CHECKSTOPPED en vfio_ap_mdev_reset_queue(). Al igual que esos códigos de respuesta, Q_NOT_AVAIL indica que la cola no está operativa y no son posibles más intentos de reinicio; la acción correcta es liberar de inmediato los recursos de interrupción.

Problema 2: ~~~~~~~~~ AP_RESPONSE_Q_NOT_AVAIL no se gestiona en apq_status_check()

En vfio_ap_mdev_reset_queue() hay cuatro casos que indican que el reinicio de la cola aún no se ha completado, en cuyo caso apq_reset_check() se encola en una cola de trabajo para verificar la finalización de la operación de reinicio. Esta función utiliza la función PQAP(TAPQ) para obtener el estado de la cola y llama a apq_status_check() para verificar si el reinicio se ha completado, ha fallado o debe ejecutarse de nuevo. Como se describe en el Problema 1, apq_reset_check() no comprueba específicamente AP_RESPONSE_Q_NOT_AVAIL, lo que puede provocar una fuga del registro GISC de KVM y de la página de invitado fijada en memoria que contiene el NIB.

Esto se corrige añadiendo un caso para AP_RESPONSE_Q_NOT_AVAIL en apq_status_check() que devuelve -ENODEV. El invocador, apq_reset_check(), comprobará entonces este código de retorno y llamará a vfio_ap_free_aqic_resources() para evitar la fuga.

Problema 3: ~~~~~~~~~ vfio_ap_free_aqic_resources() provoca una fuga de saved_isc cuando kvm es NULL

vfio_ap_free_aqic_resources() protege la llamada a kvm_s390_gisc_unregister() con:

Si matrix_mdev->kvm es NULL -lo que puede ocurrir cuando vfio_ap_mdev_unset_kvm() ya se ha ejecutado y ha borrado kvm antes de que una ruta de limpieza posterior llegue a esta función-, el WARN_ON se activa y se omite todo el bloque. Esto deja q->saved_isc con un valor no inválido, lo que crea una posible doble liberación en cualquier llamada posterior a esta función.

Cuando kvm es NULL, el invitado de KVM ya está desmantelado, por lo que kvm_s390_gisc_unregister() no necesita ni puede ser llamada; sin embargo, q->saved_isc siempre debe borrarse. Para corregirlo, se separa la llamada a kvm_s390_gisc_unregister() del reinicio de q->saved_isc. El WARN_ON ahora solo protege el caso realmente imposible de que matrix_mdev sea NULL. Un kvm NULL se gestiona correctamente omitiendo únicamente la llamada de desregistro, y q->saved_isc = VFIO_AP_ISC_INVALID se establece incondicionalmente siempre que saved_isc no fuera ya inválido.

Adicionalmente, se añade una cláusula else a la comprobación de la configuración del host en vfio_ap_mdev_remove_queue() para llamar directamente a vfio_ap_free_aqic_resources() cuando la cola no está en la configuración AP del host. Esto actúa como mecanismo de respaldo: cuando el bus AP invoca el callback .remove del controlador tras retirar un adaptador de la configuración del host, la cola deja de ser direccionable por definición, por lo que vfio_ap_mdev_reset_queue ---truncated---

Detalles técnicos trazas, registros y código del informe original
    if (q->saved_isc != VFIO_AP_ISC_INVALID &&
        !WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm)))

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.17 %
Percentil entre todas las CVEs puntuadas
6
Fecha de la puntuación
20/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 4 referencias

JSON original (NVD)

Mostrar
{
  "id": "CVE-2026-98473",
  "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": "b9bd10c43456d16abd97b717446f51afb3b88411",
              "lessThan": "da69d3ac53490724eba0ade9deb4e539a6ae9034",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "b9bd10c43456d16abd97b717446f51afb3b88411",
              "lessThan": "cf441a0db681dfad5e89b015d6be11365159d7a9",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "b9bd10c43456d16abd97b717446f51afb3b88411",
              "lessThan": "3c3433657c82f200dae36c29e2b80681c81b85be",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "b9bd10c43456d16abd97b717446f51afb3b88411",
              "lessThan": "65e05ec252a9b79e75930d3c4dd42d8877db04c5",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "582014b08cb83383cdd61f052cd81e8aa5023696",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "7abe1494896c052d5dcf4ba910656777aff72fbb",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "6.6.15",
              "lessThan": "6.7",
              "versionType": "semver"
            },
            {
              "status": "affected",
              "version": "6.7.3",
              "lessThan": "6.8",
              "versionType": "semver"
            }
          ],
          "programFiles": [
            "drivers/s390/crypto/vfio_ap_ops.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.8"
            },
            {
              "status": "unaffected",
              "version": "0",
              "lessThan": "6.8",
              "versionType": "semver"
            },
            {
              "status": "unaffected",
              "version": "6.12.112",
              "versionType": "semver",
              "lessThanOrEqual": "6.12.*"
            },
            {
              "status": "unaffected",
              "version": "6.18.55",
              "versionType": "semver",
              "lessThanOrEqual": "6.18.*"
            },
            {
              "status": "unaffected",
              "version": "7.2.9",
              "versionType": "semver",
              "lessThanOrEqual": "7.2.*"
            },
            {
              "status": "unaffected",
              "version": "7.3",
              "versionType": "original_commit_for_fix",
              "lessThanOrEqual": "*"
            }
          ],
          "programFiles": [
            "drivers/s390/crypto/vfio_ap_ops.c"
          ],
          "defaultStatus": "affected"
        }
      ]
    }
  ],
  "published": "2026-10-18T16:16:57.793",
  "references": [
    {
      "url": "https://git.kernel.org/stable/c/3c3433657c82f200dae36c29e2b80681c81b85be",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/65e05ec252a9b79e75930d3c4dd42d8877db04c5",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/cf441a0db681dfad5e89b015d6be11365159d7a9",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/da69d3ac53490724eba0ade9deb4e539a6ae9034",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    }
  ],
  "vulnStatus": "Received",
  "descriptions": [
    {
      "lang": "en",
      "value": "In the Linux kernel, the following vulnerability has been resolved:\n\ns390/vfio-ap: fix KVM GISC and page leak when queue removed from host config\n\nThree related problems exist in the handling of KVM interrupt and page\nresources when a queue is removed from the host's AP configuration\nwhile assigned to a mediated device (mdev).\n\nProblem 1:\n~~~~~~~~~\nAP_RESPONSE_Q_NOT_AVAIL not handled in vfio_ap_mdev_reset_queue()\n\nWhen the AP bus removes a queue device whose adapter or domain has\nbeen removed from the host's AP configuration,\nvfio_ap_mdev_remove_queue() is called. If the queue is still in the\nhost's AP configuration at that point, it calls\nvfio_ap_mdev_reset_queue(), which issues a PQAP(ZAPQ). Since the\nadapter is already gone from the host configuration, ap_zapq() returns\nAP_RESPONSE_Q_NOT_AVAIL (0x01). This response code is not handled in\nvfio_ap_mdev_reset_queue()'s switch statement and falls through to\nthe default case, which issues a WARN but does not call\nvfio_ap_free_aqic_resources(). As a result, if IRQ handling was\nenabled for the queue by the guest, the KVM GISC registration and\nthe pinned guest page holding the notification indicator byte (NIB)\nare both leaked.\n\nThis is fixed by adding AP_RESPONSE_Q_NOT_AVAIL to the same case as\nAP_RESPONSE_DECONFIGURED and AP_RESPONSE_CHECKSTOPPED in\nvfio_ap_mdev_reset_queue(). Like those response codes, Q_NOT_AVAIL\nindicates the queue is not operational and no further reset attempts\nare possible; the correct action is to free the IRQ resources\nimmediately.\n\nProblem 2:\n~~~~~~~~~\n AP_RESPONSE_Q_NOT_AVAIL not handled in apq_status_check()\n\nIn vfio_ap_mdev_reset_queue(), there are four cases that indicate a queue\nreset has not yet completed, in which case apq_reset_check() is queued to\na work queue to verify completion of the reset operation. This function\nuses the PQAP(TAPQ) function to get the queue's status and calls\napq_status_check() to verify whether the reset has completed, failed or\nneeds to be executed again. As described in Problem #1 above,\napq_reset_check() does not specifically check for AP_RESPONSE_Q_NOT_AVAIL,\nthereby potentially leaking KVM GISC registration and the pinned guest page\nholding the NIB.\n\nThis is fixed by adding a case statement for AP_RESPONSE_Q_NOT_AVAIL to\napq_status_check() and returning -ENODEV for that case. The caller,\napq_reset_check() will then check for this return code and call\nvfio_ap_free_aqic_resources() to prevent the leak.\n\nProblem 3:\n~~~~~~~~~\nvfio_ap_free_aqic_resources() leaks saved_isc when kvm is NULL\n\nvfio_ap_free_aqic_resources() guards the call to\nkvm_s390_gisc_unregister() with:\n\n    if (q->saved_isc != VFIO_AP_ISC_INVALID &&\n        !WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm)))\n\nIf matrix_mdev->kvm is NULL -- which can happen when\nvfio_ap_mdev_unset_kvm() has already run and cleared kvm before a\nsubsequent cleanup path reaches this function -- the WARN_ON fires\nand the entire block is skipped. This leaves q->saved_isc set to a\nnon-invalid value, creating a potential double-free on any subsequent\ncall to this function.\n\nWhen kvm is NULL the KVM guest is already torn down, so\nkvm_s390_gisc_unregister() need not and cannot be called; however,\nq->saved_isc must always be cleared. Fix this by separating the\nkvm_s390_gisc_unregister() call from the q->saved_isc reset. The\nWARN_ON now guards only the genuinely impossible case of matrix_mdev\nbeing NULL. A NULL kvm is handled gracefully by skipping only the\nunregister call, and q->saved_isc = VFIO_AP_ISC_INVALID is set\nunconditionally whenever saved_isc was not already invalid.\n\nAdditionally, add an else clause to the host-config check in\nvfio_ap_mdev_remove_queue() to call vfio_ap_free_aqic_resources()\ndirectly when the queue is not in the host's AP configuration. This\nserves as a backstop: when the AP bus fires the driver .remove\ncallback after an adapter is removed from the host config, the queue\nis by definition no longer addressable, so vfio_ap_mdev_reset_queue\n---truncated---"
    }
  ],
  "lastModified": "2026-10-19T10:18:57.850",
  "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
}