요점부터
Linux 커널 RxGK(rxrpc의 GSS 보안 계층) 디코드 경로에 COW(Copy-on-Write) 가드가 빠져 있어요. 비특권 사용자가 보낸 skb의 복호화 결과가 페이지 캐시의 공유 페이지에 그대로 쓰여요. 그 자리가 /etc/shadow, /etc/sudoers, SUID 바이너리의 페이지라면, 평범한 사용자가 root가 돼요.
별명은 DirtyDecrypt입니다. CVE는 CVE-2026-31635로 묶였지만, NVD에는 CVSS 3.1 7.5 High DoS로만 올라 있습니다. 발견자(Zellic + V12 보안팀)가 PoC로 보여준 실제 영향은 root LPE입니다. 2026-05-18에 PoC가 공개됐고, PoC repo는 GitHub에 그대로 있습니다. 즉시 악용 가능한 상태입니다.
CVE 한 줄, 함수 한 줄, 영향 두 가지
같은 결함이 두 모습으로 나뉘어 있습니다.
| NVD / 메인테이너 시각 | Zellic/V12 PoC 시각 | |
|---|---|---|
| 위치 | rxgk_verify_response ↔ rxgk_decrypt_skb | rxgk_decrypt_skb |
| 결함 종류 | 길이 검증 반전 (CWE-130) | COW 가드 누락 |
| 결과 | skb_to_sgvec()에서 BUG_ON() → 커널 패닉 | 페이지 캐시 임의 위치 쓰기 → root |
| CVSS | 7.5 High (DoS) | 평가 없음 (LPE) |
| 분류 | DoS | LPE (Dirty 시리즈) |
메인테이너는 V12의 DirtyDecrypt 보고에 “동일 서브시스템(net/rxrpc)의 같은 모듈군이라 중복 보고"라고 회신했고, DirtyDecrypt에는 별도 CVE가 붙지 않았습니다. 패치 자체는 메인라인에 조용히 머지됐습니다. 운영자 입장에서 중요한 것은 CVE 한 줄로 묶였더라도 영향이 DoS에 그치지는 않는다는 점입니다. NVD 등급만 보고 우선순위를 매기면 위험을 놓칩니다.
Dirty 시리즈 계보
페이지 캐시의 공유 페이지에 비특권 사용자가 결정론적 쓰기를 하는 결함은 이번이 처음이 아닙니다. 한 달도 안 된 Copy Fail (CVE-2026-31431)과도 같은 자리에 섭니다.
| Dirty COW (2016) | Dirty Pipe (2022) | Copy Fail (2026-04) | DirtyDecrypt (2026-05) | |
|---|---|---|---|---|
| 클래스 | race condition | flag 초기화 누락 | 직선형 논리 버그 | COW 가드 누락 |
| 성공률 | 확률적 | 거의 결정론적 | 결정론적 | 결정론적 |
| 트리거 표면 | madvise + writeable 매핑 | splice + vmsplice | splice + AF_ALG | rxrpc 소켓 |
| 영향 코드 경로 | mm/memory.c | fs/splice.c | crypto/algif_aead.c | net/rxrpc/rxgk_*.c |
| 익스플로이트 전제 | 광범위 | 광범위 | 광범위 | RxGK 사용 |
DirtyDecrypt가 다른 셋과 가장 다른 지점은 트리거 표면이 좁다는 것입니다. RxRPC를 쓰는 환경은 사실상 Andrew File System(AFS) 클라이언트 또는 그 GSS 보안 계층 RxGK를 쓰는 환경에 한정됩니다.
영향 범위와 패치
| 제품 | 영향 받는 버전 | 해결 버전 |
|---|---|---|
| Linux kernel | 6.19 이상 6.19.13 미만 | 6.19.13 이상 |
| Linux kernel | 6.16.1 이상 6.18.23 미만 | 6.18.23 이상 |
| Linux kernel | 7.0-rc1 ~ 7.0-rc7 | rc8 이후 메인라인 |
배포판별 노출 정도는 RxGK가 기본 활성화돼 있는지에 따라 갈립니다.
| 배포판 | RxGK 기본 상태 | 노출 |
|---|---|---|
| Fedora / Arch Linux / openSUSE Tumbleweed | 활성화 | 즉시 영향 |
| Debian Stable / RHEL / Ubuntu LTS | 비활성화 | 일반적으로 안전 |
NVD 데이터는 CVE-2026-31635에, 메인라인 패치 커밋은 다음에 있습니다.
패치의 핵심은 공유 fragment를 가진 skb를 in-place로 복호화하기 전에 사본을 먼저 만든다는 한 줄입니다. 빠져 있던 COW 가드가 그 자리에 들어갑니다.
RxGK 복호화 경로의 메커니즘
RxRPC는 Andrew File System(AFS)의 네트워크 전송 프로토콜입니다. RxGK는 그 위에 GSS-API 기반 보안 계층을 얹습니다. 들어오는 데이터 패킷이 RESPONSE 인증자를 들고 오면, rxgk_verify_response()가 그 길이를 검증하고 rxgk_decrypt_skb()가 복호화를 수행합니다.
문제의 자리는 두 군데입니다.
rxgk_verify_response. 길이 검증 비교 연산이 반전돼 있습니다. 비정상적으로 큰 인증자 길이가 통과해서skb_to_sgvec()에 도달하고, 거기에서BUG_ON()이 트리거됩니다. 이것이 NVD에 등록된 DoS 경로입니다.rxgk_decrypt_skb. 들어온 socket buffer(skb)가 페이지 캐시 페이지를 fragment로 참조하고 있을 때, 그 페이지에 in-place로 복호화 결과를 씁니다. 공유 페이지에 쓰기 전에 사본을 만드는 COW 가드가 빠져 있습니다. 이것이 V12/Zellic의 LPE 경로입니다.
후자가 왜 root로 이어지는지 살펴보겠습니다. 페이지 캐시 페이지는 커널에서 누가 그 페이지를 매핑하고 있는지 구별하지 않습니다. /etc/shadow, /etc/sudoers, /usr/bin/sudo 같은 SUID 바이너리도 동일한 페이지 캐시에 들어와 있습니다. 비특권 프로세스가 그 페이지를 read-only로 매핑해 두고, RxGK 디코드 경로를 통해 같은 페이지에 임의 바이트를 쓰면, 디스크는 그대로지만 메모리상의 권한 파일이 바뀝니다. 이후 execve() 또는 인증 검사 시점에 변조된 페이지가 그대로 사용됩니다.
flowchart TD
USR["비특권 프로세스"]
TGT["SUID·shadow 페이지"]
PC["page cache"]
SOCK["RxRPC 소켓
(RxGK 인증)"]
SKB["incoming skb
(공유 fragment)"]
DEC["rxgk_decrypt_skb"]
GUARD["COW 가드 없음"]
WRITE["in-place 쓰기"]
EXEC["execve / sudo"]
ROOT["root 쉘"]
USR --> SOCK
USR -- "mmap 참조" --> TGT
TGT --> PC
SOCK --> SKB
PC -- "공유 페이지" --> SKB
SKB --> DEC
DEC --> GUARD
GUARD --> WRITE
WRITE -- "권한 페이지 변조" --> PC
USR --> EXEC
EXEC -- "변조 페이지 로드" --> ROOT
이 흐름은 결정론적입니다. race condition도, ASLR 우회도 필요 없습니다. PoC는 표준 라이브러리만으로 동작합니다.
임시로 막으려면 모듈 차단
패치를 즉시 못 올리는 환경에서는 영향 모듈을 끄는 방법이 있습니다. RxGK가 의존하는 모듈 4종을 블랙리스트로 묶습니다.
# 사용 여부 확인
lsmod | grep -E '^(rxrpc|af_rxrpc|rxgk|kafs)\s'
# 사용 중이고 외부에서 필요 없다면 블랙리스트
cat <<'EOF' | sudo tee /etc/modprobe.d/rxgk-blacklist.conf
blacklist rxgk
blacklist rxrpc
blacklist af_rxrpc
blacklist kafs
EOF
# 적용 (즉시 unload)
sudo rmmod kafs rxgk rxrpc af_rxrpc 2>/dev/null || true
built-in으로 컴파일된 커널이면 unload가 불가능합니다. 두 가지 선택지가 남습니다.
- 영향 받지 않는 커널(6.19.13 / 6.18.23 이상)으로 교체 후 재부팅
- RxGK/RxRPC를 module 또는 disable 옵션으로 다시 컴파일
Fedora, Arch, openSUSE Tumbleweed는 보통 모듈이지만, 자체 빌드 커널은 확인이 필요합니다.
# RxGK 관련 옵션이 모듈인지 built-in인지 확인
zcat /proc/config.gz 2>/dev/null | grep -E 'CONFIG_(AFS|RXRPC|RXGK)'
# 또는
grep -E 'CONFIG_(AFS|RXRPC|RXGK)' /boot/config-$(uname -r)
=m은 모듈(블랙리스트로 처리 가능), =y는 built-in(커널 교체 필요)입니다.
지금 해야 할 일
- 커널 버전을 확인합니다.
uname -r로 보고, 6.16.1 ~ 6.18.22 또는 6.19 ~ 6.19.12, 7.0-rc1 ~ rc7이면 영향권입니다. - 배포판 노출을 평가합니다. Fedora, Arch, openSUSE Tumbleweed면 RxGK가 켜져 있을 가능성이 높고, RHEL, Ubuntu LTS, Debian Stable이면 보통 비활성화지만 자체 빌드는 확인이 필요합니다.
- 모듈 사용 여부를 확인합니다.
lsmod | grep -E 'rxrpc|rxgk|kafs'로 적재 여부를 보면 되고, AFS 클라이언트를 안 쓰면 99% 적재돼 있지 않습니다. - 패치를 적용합니다. 6.19.13 / 6.18.23 / 7.0-rc8 이후로 올리고, 배포판 패키지가 따라잡혔는지는
dnf updateinfo/apt changelog linux-image-*등으로 확인합니다. - 즉시 패치가 불가능하면 모듈을 블랙리스트에 넣습니다. 위의 conf 파일로 처리하되, AFS 클라이언트가 필요한 환경이면 패치를 우선시합니다.
- 변조 흔적을 점검합니다. 페이지 캐시 변조는 디스크에 남지 않지만, root 쉘 획득 후 흔적은
/var/log/auth.log,last,who, sudo 로그에 일부 남습니다. PoC 공개일(2026-05-18) 이후 비정상 sudo 호출 패턴을 검토합니다.
미배정 CVE라는 회색지대
DirtyDecrypt는 자체 CVE가 없습니다. CVE-2026-31635에 묶였고, 그 등록은 DoS 등급입니다. 운영자는 다음 두 가지를 함께 떠올려야 합니다.
- NVD 등급은 영향 모델 중 하나만 반영합니다. 같은 결함이 다른 모델에서 더 무서울 수 있습니다.
- CVE가 미배정이라고 결함이 작은 것도 아닙니다. 패치 머지 시점, PoC 공개 시점, 발견자 공개 시점이 운영자의 실제 시계입니다.
이번 자리의 시계는 4월 24일 NVD 공개 → 5월 18일 PoC 공개입니다. 한 달이 안 됐습니다. NVD 등급에 안주했다면 6.19.13 패치를 미뤘을 자리에, PoC가 같은 함수에서 root를 가져갔습니다.
정리
| 항목 | 값 |
|---|---|
| 별명 | DirtyDecrypt |
| CVE | CVE-2026-31635 (묶임, DoS 등급) |
| 함수 | rxgk_decrypt_skb / rxgk_verify_response |
| 결함 | COW 가드 누락 + 길이 검증 반전 |
| 영향 | DoS (NVD), root LPE (PoC) |
| CVSS | 3.1 7.5 High (NVD; DoS만) |
| 영향 커널 | 6.16.1 ~ 6.18.22/6.19 ~ 6.19.12/7.0-rc1 ~ rc7 |
| 패치 | 6.19.13/6.18.23/7.0-rc8 |
| PoC 공개 | 2026-05-18 |
| 발견자 | Zellic/V12 보안팀 |
| 임시 완화 | rxgk, rxrpc, af_rxrpc, kafs 모듈 블랙리스트 |
AFS 클라이언트를 쓰지 않는다면 노출 면적은 좁아요. 쓰고 있다면, 또는 자체 빌드 커널에서 CONFIG_RXGK=y라면, 지금이 패치를 올릴 자리예요.
참고
- NVD (CVE-2026-31635)
- kernel.org 패치 (beee051f259a)
- kernel.org 패치 (e2f1a80d8b1e)
- v12-security/pocs (dirtydecrypt PoC)
- SecurityWeek — PoC Released for DirtyDecrypt
- BleepingComputer — Exploit available for new DirtyDecrypt Linux root escalation flaw
- SecPod — DirtyDecrypt Technical Analysis
- Moselwal — DirtyDecrypt Linux Kernel LPE (CVE-2026-31635)
- Copy Fail (CVE-2026-31431): 한 달 전 같은 자리의 페이지 캐시 쓰기 LPE