
Guía de análisis y mitigación para CVE-2026-31431, una escalada de privilegios local del kernel de Linux en el subsistema criptográfico algif_aead, con evaluación de impacto para RHEL y OpenShift, incluyendo el endurecimiento de seccomp y SCC.
Escalada de Privilegios Local en el subsistema criptográfico algif_aead del kernel de Linux.
CVE-2026-31431, apodado "Copy Fail", es un error lógico en la plantilla criptográfica authencesn del kernel de Linux (algif_aead). Permite a un usuario local sin privilegios realizar una escritura controlada de 4 bytes en la caché de páginas de cualquier archivo legible, lo que puede aprovecharse para modificar un binario setuid y obtener acceso root.
a664bf3d603d| Fecha | Evento |
|---|---|
| 2026-03-23 | Reportado al equipo de seguridad del kernel de Linux |
| 2026-04-01 | Parche aplicado al mainline |
| 2026-04-22 | CVE asignado |
| 2026-04-29 | Divulgación pública |
El exploit requiere dos cosas: un socket AF_ALG (permitido por defecto en todos los perfiles seccomp) y un binario setuid (p. ej. /usr/bin/su). La mitigación clave es allowPrivilegeEscalation: false — esto establece la bandera no_new_privs del kernel de Linux mediante prctl(PR_SET_NO_NEW_PRIVS, 1), lo que hace que el kernel ignore los bits setuid/setgid en execve(). Dado que el exploit depende de ejecutar un binario setuid modificado, esto bloquea el paso final de escalada.
Esta no es una característica específica de OpenShift — funciona de la misma manera en Kubernetes estándar (Pod Security Standards Restricted), Docker (--security-opt no-new-privileges) y Podman. OpenShift simplemente lo aplica por defecto mediante el SCC restricted-v2, mientras que otras plataformas requieren configuración explícita.
RHEL 8 y RHEL 9 incluyen kernels que contienen el código vulnerable. Un usuario local sin privilegios con acceso shell puede explotar esto para obtener root. Aplique el parche inmediatamente.
yum updateinfo list cves CVE-2026-31431
yum update kernel
OpenShift se ejecuta en RHCOS, que incluye el kernel vulnerable. El impacto práctico depende de las Restricciones de Contexto de Seguridad (SCC) de la carga de trabajo.
Las cargas de trabajo estándar que utilizan el SCC restricted-v2 predeterminado no son explotables porque se aplica allowPrivilegeEscalation: false.
Los pods que se ejecutan con SCC elevados (anyuid, privileged o SCC personalizados que permitan allowPrivilegeEscalation: true) son vulnerables. Esto incluye comúnmente:
anyuidEl acceso directo al nodo (p. ej. mediante oc debug node/) siempre es vulnerable — escalada de privilegios local estándar, sin aislamiento de contenedores.
Se proporciona un pod de prueba para verificar si los requisitos previos del exploit se cumplen en su clúster. No intenta explotar la vulnerabilidad — solo verifica:
AF_ALG? (superficie de ataque del kernel alcanzable)no_new_privs? (bloquea la escalada setuid)oc apply -f test-pod.yaml
oc logs cve-2026-31431-check
oc delete -f test-pod.yaml
Use la variante Deployment para probar en múltiples nodos escalando réplicas o usando anti-afinidad de pods:
oc apply -f test-deployment.yaml
oc logs -l app=cve-2026-31431-check
oc delete -f test-deployment.yaml
| Código | Significado |
|---|---|
0 | No explotable — socket AF_ALG bloqueado por seccomp |
1 | Parcialmente expuesto — AF_ALG alcanzable pero setuid bloqueado por no_new_privs |
2 | Vulnerable — todos los requisitos previos del exploit se cumplen |
En un clúster OpenShift estándar con SCC restricted-v2, debería ver el código de salida 1 (parcialmente expuesto): el socket AF_ALG se puede crear (RuntimeDefault seccomp no lo bloquea), pero no_new_privs impide el paso de escalada setuid. El PoC publicado no funcionará, pero la vulnerabilidad a nivel de kernel sigue siendo alcanzable — se recomienda aplicar el parche.
Esta es la única corrección completa. Actualice el kernel en todos los nodos y reinicie.
Para OpenShift, actualice a una versión de RHCOS que incluya la corrección y realice un reinicio gradual de nodos.
Si algif_aead está compilado como módulo cargable (CONFIG_CRYPTO_USER_API_AEAD=m):
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead 2>/dev/null || true
Esto NO funciona si algif_aead está integrado (=y), que es el caso en RHCOS. Verifique con:
modinfo algif_aead 2>&1 | grep builtin
grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r)
Si el módulo del kernel está integrado, la única mitigación previa al parche para contenedores es bloquear la llamada al sistema socket(AF_ALG, ...) mediante un perfil seccomp personalizado.
Cree el MachineConfig para colocar el perfil en todos los nodos (repita con role: master para los nodos del plano de control):
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
labels:
machineconfiguration.openshift.io/role: worker
name: 99-worker-seccomp-deny-af-alg
spec:
config:
ignition:
version: 3.2.0
storage:
files:
- path: /var/lib/kubelet/seccomp/deny-af-alg.json
mode: 0644
contents:
source: data:application/json;charset=utf-8;base64,ewogICJkZWZhdWx0QWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwKICAic3lzY2FsbHMiOiBbCiAgICB7CiAgICAgICJuYW1lcyI6IFsic29ja2V0Il0sCiAgICAgICJhY3Rpb24iOiAiU0NNUF9BQ1RfRVJSTk8iLAogICAgICAiYXJncyI6IFsKICAgICAgICB7CiAgICAgICAgICAiaW5kZXgiOiAwLAogICAgICAgICAgInZhbHVlIjogMzgsCiAgICAgICAgICAib3AiOiAiU0NNUF9DTVBfRVEiCiAgICAgICAgfQogICAgICBdCiAgICB9CiAgXQp9
El contenido base64 se decodifica a:
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": ["socket"],
"action": "SCMP_ACT_ERRNO",
"args": [
{
"index": 0,
"value": 38,
"op": "SCMP_CMP_EQ"
}
]
}
]
}
Nota: Aplicar un MachineConfig desencadena un reinicio gradual de nodos.
securityContext:
seccompProfile:
type: Localhost
localhostProfile: deny-af-alg.json
Para proteger todos los contenedores sin modificar las especificaciones de pods, sobrescriba el perfil seccomp predeterminado de CRI-O (/etc/crio/seccomp.json) mediante MachineConfig agregando la regla de filtro AF_ALG al perfil existente.
Identifique los pods que se ejecutan con privilegios elevados:
# Encontrar pods que no usan restricted-v2
oc get pods -A -o json | jq -r '
.items[] |
select(.metadata.annotations["openshift.io/scc"] != "restricted-v2") |
"\(.metadata.namespace)/\(.metadata.name) → \(.metadata.annotations["openshift.io/scc"])"
'
Estos son los pods donde funciona la cadena completa del exploit. Priorice el parcheo o la mitigación seccomp para los nodos que ejecutan estas cargas de trabajo.
Bloquear los sockets AF_ALG tiene un impacto insignificante en la mayoría de las cargas de trabajo. Los siguientes no se ven afectados:
Solo las aplicaciones configuradas explícitamente para usar el motor afalg de OpenSSL se verán afectadas.
| Entorno | allowPrivilegeEscalation | Root del Contenedor | Root del Host | Riesgo |
|---|
| RHEL 8 / RHEL 9 (usuario local) | n/a | n/a | Sí | Crítico |
Nodo OpenShift (acceso shell, p. ej. oc debug node/) | n/a | n/a | Sí | Crítico |
Pod OpenShift — SCC restricted-v2 (predeterminado) | false | No | No | Bajo |
Pod OpenShift — SCC anyuid | true | Sí | No (aislamiento de namespace) | Alto |
Pod OpenShift — SCC privileged | true | Sí | Sí (sin aislamiento) | Crítico |
| Pod OpenShift — SCC personalizado | depende | depende | depende | Auditoría |
| Pod Kubernetes — PSS Restricted | false | No | No | Bajo |
| Pod Kubernetes — PSS Baseline / sin política | true (predeterminado) | Sí | No | Alto |
Docker / Podman — --security-opt no-new-privileges | false | No | No | Bajo |
| Docker / Podman — predeterminado | true | Sí | No | Alto |