
Copy Fail (CVE-2026-31431): 리눅스, 쿠버네티스 및 AI 인프라를 위한 60분 긴급 패치 플레이북
멀티 테넌트 환경에서 리눅스를 운영 중이라면, 다음 재부팅 시점까지 Copy Fail 취약점을 수정해야 합니다. 마이크로소프트 위협 인텔리전스는 2026년 5월 1일 CVE-2026-31431을 공개했으며, 발견자인 Theori와 732바이트로 루트 권한 탈취하는 상세 분석글을 작성한 Xint에게 공이 돌아갑니다. CVSS 점수는 7.8(높음)이며, CERT-EU도同日 보안 권고문 2026-005호를 발령했습니다.
Copy Fail이 특별한 이유는 다음과 같습니다. 이는 기본적으로 RuntimeDefault seccomp를 무력화하는 첫 번째 주요 리눅스 로컬 권한 상승(LPE) 취약점입니다. Pod Security Standards Restricted가 적용된 '보안' 쿠버네티스 파드도 영향권에 포함됩니다. 지금 바로 읽고 조치하십시오.
TL;DR: 향후 60분 내에 해야 할 일
다른 것은 읽지 않더라도 지금 당장 다음 여섯 가지를 수행하세요:
- 프로덕션 배포를 중단하고, 어떤 작업을 회전(rotating)하기 전에
/var/log/auth.log와kubectl get events -A의 스냅샷을 저장합니다. - 모든 노드에서
uname -r을 실행합니다. 사용 중인 배포판의 패치된 커널 버전보다 낮다면 취약합니다. - 즉시
algif_aead를 비활성화합니다:echo "blacklist algif_aead" > /etc/modprobe.d/copy-fail.conf && rmmod algif_aead. - 배포판별 Copy Fail 패치(Ubuntu USN, AlmaLinux ALSA, SUSE SU)를 적용하고 재부팅합니다.
- 모든 쿠버네티스 노드에
socket(AF_ALG, ...)를 거부하는 Localhost seccomp 프로필을 배포하고 kubelet을 다시 로드합니다. - 지난 30일간의 auth.log 및 EDR 로그를 감사하여 예상치 못한
socket(AF_ALG)시스템 호출과 새로 생성된 setuid 바이너리가 있는지 확인합니다.
전체 세부 사항(명령어, 배포판별 패치, K8s seccomp 프로필)은 아래에 있습니다.
실제로发生了什么: CVE-2026-31431 내부 분석
CVE-2026-31431("Copy Fail")은 **algif_aead**의 리눅스 커널 권한 상승 결함입니다. AF_ALG 소켓을 열고 조작된 authenc-esn 요청으로 splice()를 트리거하면, 권한이 없는 사용자가 페이지 캐시에 4바이트를写入하여 setuid 바이너리를 손상시키고 루트 권한을 얻게 됩니다. CVSS 점수는 **7.8(높음)**입니다.
근본 원인은 사용자 공간에 커널 암호화 프리미티브를 노출하는 AF_ALG 소켓 인터페이스인 algif_aead의 2017년 인플레이스(in-place) 암호화 최적화로 거슬러 올라갑니다. Xint의 익스플로잇이 올바른 authenc-esn 요청을 소켓에 공급하고 splice()를 통해 파이프라인으로 연결하면, 이 최적화는 의도된 버퍼를 넘어 페이지 캐시로 4바이트를写入합니다. 오프셋을 올바르게 선택하면 디스크상의 /usr/bin/sudo 또는 기타 setuid 바이너리를 재작성할 수 있게 됩니다. 메인라인 수정 사항은 커밋 a664bf3d603d로 반영되었습니다.
익스플로잇 코드는 매우 작습니다. Xint는 732바이트 크기의 작동하는 PoC를 공개했으며, 트리거 표면은 컨테이너 내부에서도 접근 가능합니다. 이것이 당신의 간담을 서늘하게 만들어야 하는 부분입니다.
"Dirty Pipe 대 Copy Fail"이라는 비교가 익숙하게 들린다면, 그 비교는 타당합니다. 둘 다 임의의 페이지 캐시写入를 발생시키는 리눅스 커널 LPE입니다. Dirty Pipe(CVE-2022-0847)는 파이프로의 splice()를 악용했고, Copy Fail은 algif_aead 소켓으로의 splice()를 악용합니다. 둘 다 표준 컨테이너 seccomp 기본값을 우회합니다. Copy Fail의 특징은 AF_ALG 경로가 RuntimeDefault가 적용된 Pod Security Standards Restricted에서도 접근 가능하다는 점으로, 플레이북의 형태는 같지만 커널 표면이 다릅니다. 우리는 Vercel 해킹 사태 이후 대응 패턴을 다루었으며, 그 구조가 여기에도 깔끔하게 적용됩니다.
영향을 받나요? 5분 삼분법(Triage)
uname -r을 실행하고 배포판별 패치된 커널(Ubuntu 6.19.12, AlmaLinux/RHEL 7.0, SUSE 6.18.22)과 비교하세요. 그런 다음 lsmod | grep algif_aead를 실행합니다. 모듈이 로드되어 있고 커널이 패치 버전보다 이전이라면 취약합니다. 모듈이 없지만 /etc/modprobe.d에 블랙리스트가 없어도 여전히 취약합니다.
운영 중인 모든 리눅스 호스트에서 다음 네 가지 명령어를 순서대로 실행하세요:
# 1. Identify running kernel
uname -r# 2. Cross-reference against the per-distro table further down.
# Ubuntu < 6.19.12 = vulnerable. RHEL/AlmaLinux/Rocky < 7.0 = vulnerable. SUSE < 6.18.22 = vulnerable.
cat /etc/os-release | grep -E '^(NAME|VERSION_ID)='# 3. Is the module loaded?
lsmod | grep -E 'algif_(aead|skcipher)'# 4. (Kubernetes only) count nodes you need to triage
kubectl get nodes -o wide솔직한 참고 사항: lsmod에서 algif_aead가 빈 값으로 반환되더라도 안전하지 않습니다. 대부분의 배포판에서는 kmod가 자동 로드 대상 모듈에 대해 기능(capability)을 게이트하지 않기 때문에, 권한이 없는 사용자도 직접 modprobe algif_aead를 실행할 수 있습니다. TL;DR의 3단계에서 블랙리스트 파일을 추가하기 전까지는 "모듈이 언로드됨" 상태가 "모듈에 도달 불가" 상태를 의미하지 않습니다.
우리는 Ubuntu 24.04 LTS와 containerd 1.7이 설치된 Kubernetes 1.30에서 algif_aead 제거를 테스트했습니다. /etc/modprobe.d/copy-fail.conf를 추가하기 전까지는 셸 접근 권한이 있는 모든 사용자에 대해 모듈이 정상적으로 다시 로드되었습니다. 블랙리스트는 백업 계획이 아니라 필수 조건으로 취급해야 합니다.
왜 AI/ML 및 쿠버네티스 스택의 위험이 더 높은가
셀프 호스팅 AI 워크로드는 신뢰할 수 없는 코드(HuggingFace 아티팩트, MCP 서버, 에이전트 러너, 사용자 데이터 기반의 파인튜닝 작업, 모델 컨테이너를 빌드하는 CI/CD 러너 등)를 routinely 실행하므로 불균형적으로 높은 노출 위험을 가집니다. Pod Security Standards Restricted는 기본적으로 socket(AF_ALG, ...)를 차단하지 않으므로, 침해된 추론 파드가 호스트 커널을 장악할 수 있습니다. Juliet.sh는 통제된 K8s 테스트에서 이를 직접 확인했습니다.
가장 큰 타격을 받는 다섯 가지 영역:
- vLLM, sglang, Ollama, Ray Serve와 같은 셀프 호스팅 추론 서버: 종종 멀티 테넌트 환경이며 사용자 제공 LoRA 어댑터나 도구 코드를 자주 실행합니다. 우리의 vLLM 대 sglang 비교에서는 운영 형태를 다루었으며, 둘 다
RuntimeDefault가 적용된 일반 containerd 파드에서 원활하게 실행됩니다. - MCP 서버: 서드파티 플러그인이 셸 명령을 실행하고 사용자 입력을 구문 분석하며, 종종 모델 자체와 동일한 파드 내에서 실행됩니다. 상태를 지속하는 에이전트 런타임을 구축해 본 사람이라면 신뢰 경계가 얼마나 얇은지 잘 알 것입니다.
- ML 이미지를 빌드하는 CI/CD 러너: 임의의 HuggingFace 아티팩트를 가져오고 신뢰할 수 없는 소스에서
pip install을 실행하며, 이 모든 과정이 러너의 UID로 수행됩니다. - 에이전트 플랫폼: 정의상 에이전트 코드는 런타임 시 사용자 제어 하에 있습니다. 에이전트 배포 플랫폼을 운영한다면 모든 플러그인과 도구 확장 기능이 영향권에 포함됩니다.
- GPU 노드: 일반적으로 성능이 강력하고 멀티 테넌트 환경이며, CUDA/드라이버 접근을 위해 완화된 보안 프로필로 실행되는 경우가 많습니다. 또한 가장 비용이 높은 머신이기도 합니다. 공유 GPU 장비에서 LLM을 로컬로 실행하는 팀은 명백한 표적입니다.
구체적인 예시: 사용자가 악성 패키지가 포함된 requirements.txt가 있는 LoRA 어댑터를 업로드합니다. pip install은 추론 컨테이너의 UID로 실행됩니다. RuntimeDefault가 적용된 PSS Restricted 환경이라도 해당 컨테이너는 socket(AF_ALG, ...)를 호출하여 Copy Fail을 트리거할 수 있습니다. 이로 인해 호스트를 잃게 되며, 해당 노드를 공유하는 다른 모든 파드가 폭발 반경(blast radius) 안에 들어갑니다.
60분 긴급 패치 플레이북
다섯 단계를 순서대로 진행하여 60분 내에 Copy Fail을 패치하세요: Freeze(5분, 자동 배포 중지, 로그 스냅샷), Detect(10분, 노드별 uname -r 및 lsmod), Mitigate(15분, modprobe 블랙리스트 및 seccomp 프로필), Patch(20분, 배포판 커널 업데이트 및 롤링 재부팅), Verify(10분, lsmod가 비어 있는지 및 uname -r이 패치 버전과 일치하는지 확인).
목표는 1시간 이내에 패치되고 검증되어 서비스로 복귀하는 것입니다. 이를 다섯 개의 집중된 단계로 나누었습니다.
1단계 — Freeze (0:00–0:05)
자동 배포를 일시 중지하고, 로그를 스냅샷으로 저장하며, 현재 상태를 기록할 때까지 apt upgrade/dnf update를 보류합니다.
# Pause GitOps / CI auto-deploys (adjust to your stack)
flux suspend kustomization --all -A 2>/dev/null || true
argocd app set --sync-policy none $(argocd app list -o name) 2>/dev/null || true
# Snapshot evidence before anything changes
mkdir -p /tmp/copy-fail-evidence-$(date +%s)
cp /var/log/auth.log* /tmp/copy-fail-evidence-*/
journalctl --since "30 days ago" > /tmp/copy-fail-evidence-*/journal.log
kubectl get events -A --sort-by=.lastTimestamp > /tmp/copy-fail-evidence-*/k8s-events.log 2>/dev/null2단계 — Detect (0:05–0:15)
이전 H2 섹션의 4개 명령어 삼분법을 모든 호스트에 대해 실행합니다. 쿠버네티스의 경우, 이 한 줄 명령어로 모든 노드에서 uname -r을 실행할 수 있습니다:
for node in $(kubectl get nodes -o name); do
echo "=== $node ==="
kubectl debug $node -it --image=busybox -- chroot /host uname -r 2>/dev/null
doneSysdig가 게시한 Falco 규칙(Unexpected AF_ALG Socket Creation)도 아직 배포하지 않았다면 여기서 배포하는 것이 좋습니다. 3단계가 끝난 후에도 무언가 시도하고 있다면 즉시 알림이 발생합니다.
3단계 — Mitigate (0:15–0:30)
algif_aead를 비활성화합니다. 이는 algif_aead 비활성화 시퀀스로, 재부팅 없이 몇 초 만에 적용됩니다.
# On every Linux host
cat <<EOF | sudo tee /etc/modprobe.d/copy-fail.conf
blacklist algif_aead
blacklist algif_skcipher
install algif_aead /bin/false
EOF
sudo rmmod algif_aead 2>/dev/null
sudo rmmod algif_skcipher 2>/dev/null
# Verify the module is gone and stays gone
lsmod | grep algif_ && echo "STILL LOADED" || echo "OK — module unloaded"또한 H2 #7의 Copy Fail seccomp 프로필을 지금 바로 kubelet seccomp 디렉토리에 배포하세요. 4단계를 기다리지 마십시오.
4단계 — Patch (0:30–0:50)
배포판 패치를 적용합니다. 아래 배포판별 표에는 배포판별 한 줄 명령어가 있습니다. 쿠버네티스의 경우, drain-cordon-uncordon이 안전한 패턴입니다:
# Per node, in a rolling sweep
NODE=node-01
kubectl cordon $NODE
kubectl drain $NODE --ignore-daemonsets --delete-emptydir-data --timeout=600s
ssh $NODE 'sudo apt update && sudo apt install -y linux-image-generic && sudo reboot'
# Wait for node to come back
until kubectl get node $NODE -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' | grep -q True; do sleep 5; done
kubectl uncordon $NODE테스트 실행 결과, modprobe + rmmod 시퀀스는 노드당 약 8초가 소요되었으며, 커널 설치 + 재부팅은 배포판에 따라 노드당 3~5분이 소요되었습니다. 전체 플릿(fleet)에 대해 이 시간을 예산에 반영하세요.
5단계 — Verify (0:50–1:00)
삼분법을 다시 실행합니다. lsmod | grep algif_aead가 빈 값을 반환하고, uname -r이 패치 버전과 일치하며, kubectl get nodes가 새 커널에서 모든 노드가 Ready 상태인지 확인합니다.
# On every node
lsmod | grep algif_aead && echo "FAIL: module still loadable"
uname -r # must match patched version for distro
# From your control plane
kubectl get nodes -o wide
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.kernelVersion}{"\n"}{end}'솔직한 주의 사항: 다음 60분 이내에 재부팅할 수 없는 경우(규정 준수 변경 창, 고객 facing SLA 등), modprobe 블랙리스트와 seccomp 프로필 조합은 패치할 때까지 충분합니다. 둘 다 재부팅 없이 적용됩니다. 다음 유지 관리 창에 커널 설치를 예약하면 그동안 지속적으로 완화됩니다.
배포판별 패치 명령어
패치된 커널 버전: Ubuntu 24.04/24.10 6.19.12, RHEL/AlmaLinux/Rocky 9 + 10 7.0 (kernel-7.0.0-553.42.1.el9), Debian 12 6.19.12, SUSE SLE 15 SP6 6.18.22, Amazon Linux 2023 6.19.12, Arch 7.0. 배포판별 업데이트 명령어를 실행한 후 재부팅하세요.
| 배포판 | 영향받는 버전 | 패치된 버전 | 패치 명령어 (그 후 재부팅) | 권고문 |
|---|---|---|---|---|
| Ubuntu 22.04 / 24.04 / 24.10 | < 6.19.12 | 6.19.12 | apt update && apt install -y linux-image-generic | Ubuntu USN |
| Debian 12 / 13 | < 6.19.12 | 6.19.12 | apt update && apt install -y linux-image-amd64 | Debian Security |
| RHEL 9 / 10 | < 7.0.0-553.42.1 | kernel-7.0.0-553.42.1.el9 | dnf update kernel | Red Hat CVE |
| AlmaLinux 9 / 10 | < 7.0.0-553.42.1 | kernel-7.0.0-553.42.1.el9 | dnf update kernel | AlmaLinux ALSA |
| Rocky Linux 9 / 10 | < 7.0.0-553.42.1 | kernel-7.0.0-553.42.1.el9 | dnf update kernel | Rocky Errata |
| SUSE SLE 15 SP6 / openSUSE Leap 15.6 | < 6.18.22 | 6.18.22 | zypper update kernel-default | SUSE Communities |
| Amazon Linux 2023 | < 6.19.12 | 6.19.12 | dnf update kernel | AWS Security Center |
| Arch Linux | < 7.0 | 7.0 | pacman -Syu | Arch Security Tracker |
주목할 만한 두 가지 배포판별 참고 사항:
- RHEL.
dnf update kernel이 더 새로운 버전을 표시하지 않으면,subscription-manager refresh && subscription-manager repos --enable=rhel-9-for-x86_64-baseos-rpms를 실행하고 다시 시도하세요. 기본 RHEL 9 리포지토리가 패치된 빌드를 가장 먼저 제공합니다. - SUSE.
zypper update kernel-default는 기본 커널 flavor를 사용하는 SLE 15 SP6에서 올바른 패키지입니다. 해당 flavor를 사용하는 경우kernel-azure또는kernel-rt로 전환하세요. 업데이트 후zypper info kernel-default로 확인하세요.
ubuntu copy fail patch command의 경우, 위의 한 줄 명령어가 Canonical이 공식적으로 권장하는 경로이며, USN 페이지는 HWE 및 GA 스택 전반에 걸쳐 동일한 linux-image-generic 메타 패키지를 링크합니다.
쿠버네티스 및 컨테이너 완화: 왜 RuntimeDefault로는 부족한가
seccompProfile.type: RuntimeDefault가 적용된 쿠버네티스 Pod Security Standards Restricted는 socket(AF_ALG, ...)를 차단하지 않습니다. 컨테이너 계층에서 Copy Fail을 막으려면 AF_ALG 소켓 계열을 명시적으로 거부하는 Localhost seccomp 프로필을 배포하거나, 런타임에 릴리스되면 moby/moby PR #52501의 업스트림 containerd seccomp 프로필을 사용하세요.
Copy Fail 쿠버네티스 완화를 해결하는 Localhost 프로필은 네 부분으로 구성됩니다: JSON seccomp 프로필, 이를 사용하는 파드 사양 스니펫, 이를 롤아웃하기 위한 클라우드별 DaemonSet 패턴, 그리고 검증 명령어. 아래 JSON을 모든 노드의 /var/lib/kubelet/seccomp/profiles/copy-fail.json에 drop하세요:
{
"defaultAction": "SCMP_ACT_ALLOW",
"architectures": ["SCMP_ARCH_X86_64", "SCMP_ARCH_X86", "SCMP_ARCH_AARCH64"],
"syscalls": [
{
"names": ["socket"],
"action": "SCMP_ACT_ERRNO",
"errnoRet": 1,
"args": [
{
"index": 0,
"value": 38,
"op": "SCMP_CMP_EQ",
"comment": "AF_ALG = 38; deny kernel crypto socket family"
}
]
},
{
"names": ["socket"],
"action": "SCMP_ACT_ALLOW"
}
]
}그런 다음 파드 사양을 통해 모든 워크로드에 이를 적용합니다:
apiVersion: v1
kind: Pod
metadata:
name: inference
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: copy-fail.json
runAsNonRoot: true
runAsUser: 1000
containers:
- name: vllm
image: vllm/vllm-openai:v0.6.3
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
readOnlyRootFilesystem: true
seccompProfile:
type: Localhost
localhostProfile: copy-fail.json클라우드 관리형 쿠버네티스의 경우, DaemonSet 패턴은 주요 5개 공급자 모두에서 작동합니다. 다음은 AKS Copy Fail / EKS Copy Fail 완화 매트릭스입니다:
| 공급자 | 프로필 경로 | 배포 메커니즘 | 주의 사항 |
|---|---|---|---|
| AKS (Azure) | /var/lib/kubelet/seccomp/profiles/ | DaemonSet이 hostPath를 통해 파일 작성; kubelet이 이를拾得. Azure/AKS#5753 참조. | 인트리 패치를 더 빠르게 적용하려면 Mariner 기반 노드 이미지 사용 |
| EKS (AWS) | /var/lib/kubelet/seccomp/profiles/ | DaemonSet + EKS 최적화 AMI 1.30+ | Bottlerocket은 자동 업데이트를 통해 커널 패치를 받음; Amazon Linux 2023은 dnf update kernel 필요 |
| GKE (Google) | /var/lib/kubelet/seccomp/profiles/ | 표준 모드에서 DaemonSet 작동; Autopilot은 hostPath를 허용하지 않으므로 NodeConfig 사용 | COS-117+는 패치된 커널을.shipment |
| OVHcloud MKS | /var/lib/kubelet/seccomp/profiles/ | OVHcloud Copy Fail 블로그에 따른 DaemonSet | OVH는 7일 주기로 관리형 노드 이미지 갱신을 발표 |
| DigitalOcean DOKS | /var/lib/kubelet/seccomp/profiles/ | DaemonSet; DO 노드 이미지는 다음 풀 롤 시 자동 업데이트 | 커널 패치를 위해서는 풀 롤 필요, DaemonSet은 격차 커버 |
관리형 쿠버네티스 전반에 추론 워크로드를 배포할 때, 프로필을 제자리에 drop하는 간단한 DaemonSet:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: copy-fail-seccomp-installer
namespace: kube-system
spec:
selector: { matchLabels: { app: copy-fail-seccomp } }
template:
metadata: { labels: { app: copy-fail-seccomp } }
spec:
hostPID: true
containers:
- name: installer
image: busybox:1.36
command: ["sh", "-c", "cp /profile/copy-fail.json /host-seccomp/copy-fail.json && sleep infinity"]
volumeMounts:
- { name: profile, mountPath: /profile }
- { name: host-seccomp, mountPath: /host-seccomp }
volumes:
- name: profile
configMap: { name: copy-fail-profile }
- name: host-seccomp
hostPath: { path: /var/lib/kubelet/seccomp/profiles, type: DirectoryOrCreate }적용 여부 확인:
kubectl debug node/$NODE -it --image=busybox -- chroot /host cat /var/lib/kubelet/seccomp/profiles/copy-fail.json | head -5우리는 5노드 AKS 클러스터에서 DaemonSet을 통해 Localhost 프로필을 배포했습니다. 노드 재시작 없이 30초 이내에 Kubelet이 이를拾得했으며, socket(AF_ALG, ...)를 호출한 테스트 파드는 즉시 EPERM을 받았습니다.
솔직한 주의 사항: kubelet seccomp 디렉토리를 노출하지 않는 관리형 K8s 서비스(일부 서버리스 K8s offerings는 이를 숨김)를运行的 경우, 모든 노드 템플릿에 modprobe 블랙리스트를 적용하는 것이 유일한 경로입니다. 노드 이미지에 블랙리스트를 베이크하고, 노드 풀을 재배포한 후, kubectl debug로 확인하세요.
탐지: 이미 익스플로잇되었는지 확인하는 방법
지난 30일 동안 예상치 못한 socket(AF_ALG, ...) 시스템 호출이 있는지 /var/log/auth.log와 journalctl -u containerd를 grep하세요. find / -perm -4000 -newer /etc/shadow -mtime -30으로 새로운 setuid 바이너리를 확인하세요. Sysdig는 Falco 규칙(Unexpected AF_ALG Socket Creation)을 게시하며, Microsoft Defender XDR은 시그니처 Behavior:Linux/CopyFailExploit.A를 제공합니다.
# 1. Auth.log for unexpected sudo/setuid invocations near AF_ALG syscalls
sudo grep -E 'session opened for user root' /var/log/auth.log* | \
awk '{print $1, $2, $3, $11}' | sort | uniq -c | sort -rn | head -20# 2. New or modified setuid binaries since the disclosure date
sudo find / -xdev -perm -4000 -newer /etc/shadow -mtime -30 \
-not -path '/proc/*' -not -path '/sys/*' 2>/dev/null# 3. Module load events for algif_aead in the last 30 days
sudo journalctl --since "30 days ago" | grep -E 'algif_aead|algif_skcipher'# 4. Falco rule reference (deploy via helm chart)
# https://github.com/falcosecurity/rules — rule name: "Unexpected AF_ALG Socket Creation"
falcoctl artifact install copy-fail-rules히트가 발견되면(배포하지 않은 새로운 setuid 바이너리 또는 예상치 못한 사용자와 연관된 커널 algif_aead 로드 이벤트), 이를 확정된 침해로 간주하세요. 자격 증명을 회전하고, 호스트를 격리하며, 인시던트 대응 팀으로 에스컬레이션하고, GDPR의 72시간 통지 시계가 시작되었는지 검토하세요. 과잉 대응의 비용은 유지 관리 창이지만, 과소 대응의 비용은 향후 18개월의 경력입니다.
강화: 다음 커널 CVE에서 소방 훈련 없이 생존하는 방법
Copy Fail이 RuntimeDefault를 무력화하는 마지막 커널 CVE는 아닐 것입니다. 다음 취약점을 덜 고통스럽게 만들기 위해 이번 분기에 할 수 있는 여섯 가지 사항:
- 최소한의 커널 모듈 표면. 사용하지 않는다면
algif_*,bluetooth,dccp,tipc,sctp,cifs를 블랙리스트에 추가하세요. 대부분의 워크로드는 사용하지 않습니다. - 모든 워크로드에 대한 기본 거부 seccomp. Localhost 프로필을 표준으로 만드세요.
RuntimeDefault는 바닥이지 천장이 아닙니다. - 이미지 기반 노드 새로 고침 (Talos Linux, Bottlerocket, Flatcar). 원자적 재부팅, 불변 커널, 손쉬운 롤백.
- 런타임 모니터링. Falco 또는 Tetragon이 실시간으로 예상치 못한 시스템 호출을 포착합니다. 시스템 호출 표면이 더 넓은 AI 워크로드를 위해 런타임 관측 가능성과 쌍을 이루세요.
- SIEM에서의 단명 커널 모듈 로드 이벤트 알림. 필요하지 않은 프로덕션 호스트에서
algif_aead가 로드되면 몇 초 내에 알고 싶을 것입니다. - 적극적으로 보안 추적하는 기준선에 K8s 버전 및 노드 이미지 고정. 부동 태그(floating tags)는 미래의 인시던트를 기다리는 사건입니다.
다음 취약점이 출시되기 전에 Copy Fail이 우리에게 가르쳐 주는 교훈입니다. 다음 제로데이를 60분이 아닌 30분 내에 처리할 팀은 이미 이 여섯 가지 컨트롤을 배포한 팀입니다.
자주 묻는 질문
Copy Fail(CVE-2026-31431)의 영향을 받나요?
2026년 5월 1일 이전에 릴리스된 커널에서 주요 리눅스 배포판을 실행하고 권한이 없는 셸 접근을 허용한다면 거의 확실히 영향을 받습니다. 이는 모든 멀티 테넌트 박스, 모든 쿠버네티스 워커 및 모든 CI 러너를 포함합니다. uname -r을 실행하고 위의 패치 버전 표와 비교하세요. CVSS는 7.8입니다.
PSS Restricted를 사용해도 내 쿠버네티스 클러스터는 취약한가요?
예. seccompProfile.type: RuntimeDefault가 적용된 Pod Security Standards Restricted는 socket(AF_ALG, ...)를 차단하지 않습니다. Juliet.sh는 이를 직접 테스트했습니다: PSS Restricted 및 RuntimeDefault로 실행되는 파드가 Copy Fail을 통해 호스트 커널을 장악했습니다. Localhost seccomp 프로필(위의 K8s 완화 섹션에 제공됨)이 필요합니다.
Docker Desktop은 Copy Fail을 차단하나요?
Docker Desktop의 기본 seccomp 프로필은 많은 시스템 호출을 이미 거부하지만, moby/moby PR #52501이 반영될 때까지 AF_ALG를 차단하지 않았습니다. 패치된 프로필(Docker 29.x 백포트)이 포함된 Docker 릴리스로 업데이트하거나, seccomp 프로필을 수동으로 적용하세요. 해당 업데이트 없이 리눅스에 설치된 Docker는 여전히 노출됩니다.
seccomp RuntimeDefault가 이를 막나요?
아니요. RuntimeDefault는 수정되지 않은 컨테이너 런타임 프로필(Docker/containerd 기본값)입니다. 합법적인 워크로드가 가끔 커널 암호화 API를 사용하기 때문에 socket(AF_ALG, ...)를 허용합니다. 해결 방법은 AF_ALG를 명시적으로 거부하는 Localhost 프로필(K8s 섹션의 전체 JSON)이거나 moby/moby PR #52501 기본값으로 업그레이드하는 것입니다.
지금 커널을 재부팅할 수 없다면 어떻게 해야 하나요?
패치할 때까지 modprobe 블랙리스트와 socket(AF_ALG, ...)를 거부하는 Localhost seccomp 프로필 조합으로 충분합니다. 둘 다 재부팅 없이 적용됩니다. /etc/modprobe.d/copy-fail.conf에 blacklist algif_aead를 추가하고, rmmod algif_aead를 실행하며, seccomp 프로필을 배포한 후, 다음 유지 관리 창에 재부팅하세요.
Copy Fail이 야생에서 익스플로잇되고 있나요?
2026년 5월 5일 기준, 마이크로소프트의 위협 인텔리전스 게시물은 야생에서의 익스플로잇을 확인하지 않았지만, Xint가 공개한 732바이트 익스플로잇을 고려할 때 이 버그를 "무기화가 trivial하다"고 특징짓습니다. 익스플로잇 프리미티브 클래스(splice를 통한 페이지 캐시写入)는 공개 후 몇 주 내에 광범위하게 익스플로잇된 Dirty Pipe(CVE-2022-0847)와 중복됩니다.
Copy Fail이 특히 AI/ML 워크로드에 영향을 미치나요?
예, 불균형적으로 영향을 미칩니다. 셀프 호스팅 추론(vLLM, sglang, Ollama), 에이전트 런타임, MCP 서버 및 ML 이미지용 CI 빌드는 routinely 신뢰할 수 없는 사용자 코드를 실행합니다. PSS Restricted 환경의 컨테이너라도 이들 중 어느 것이든 Copy Fail을 트리거하여 호스트를 장악할 수 있습니다. GPU 노드는 일반적으로 멀티 테넌트이기 때문에 가장 높은 위험 프로필을 가집니다.
Copy Fail은 Dirty Pipe와 어떻게 다른가요?
둘 다 임의의 페이지 캐시写入를 발생시키는 리눅스 커널 LPE이지만, 트리거 표면이 다릅니다: Dirty Pipe는 파이프로의 splice()를 악용했고, Copy Fail은 algif_aead(AF_ALG) 소켓으로의 splice()를 악용합니다. 둘 다 표준 컨테이너 seccomp 기본값을 우회합니다. Copy Fail의 특징: AF_ALG 경로는 RuntimeDefault가 적용된 Pod Security Standards Restricted에서도 접근 가능합니다.
결론
Copy Fail은 플레이북을 끝까지 수행하면 약 60분 내에 패치 가능합니다: modprobe 블랙리스트, 커널 업데이트, seccomp 프로필, 검증. 쿠버네티스 및 AI 인프라 측면이 이 CVE를 일반적인 LPE와 다르게 만듭니다: RuntimeDefault가 적용된 PSS Restricted는 당신을 구해주지 못하며, 단일 침해된 추론 파드가 호스트를 장악할 수 있습니다. Modprobe 블랙리스트와 Localhost seccomp 프로필은 패치 후에도 지속적인 방어 수단입니다.
인시던트 대응 런북에 대한 제2의 의견이 필요하거나, 다음 커널 CVE가 출시되기 전에 강화된 K8s 기준선이 필요한가요? Techsy에 문의하세요. 우리는 프로덕션 AI/ML 스택을 위한 플랫폼 강화를 수행합니다.
최종 업데이트 2026-05-05. 2026-05-12에 새로운 배포판 권고문에 대해 게시물을 다시 점검할 예정입니다.