요약
내용: ‘PinTheft’라는 새로운 리눅스 로컬 권한 상승 취약점이 발견되었습니다. 이 취약점은 커널의 RDS(Reliable Datagram Sockets) 제로카피 전송 경로에 존재하는 참조 카운트(refcount) 버그와 io_uring을 연쇄적으로 악용하여 메모리 내의 SUID 루트 바이너리를 덮어씁니다. 그 결과, 권한이 없는 로컬 계정에서도 루트 셸을 획득할 수 있습니다. 본 기사 작성 시점에는 아직 CVE 번호가 할당되지 않았습니다.
영향: V12 Security가 공개한 개념 증명( PoC ) 을 통해, 영향을 받는 호스트에서 권한이 없는 로컬 사용자라도 루트 권한을 획득할 수 있는 확실한 경로가 제공됩니다. 이 근본적인 결함은 2018년에 출시된 리눅스 커널 버전 4.17부터 잠재되어 있었습니다.
상태: 이번 발견의 공로를 인정받은 V12 Security의 아론 에사우(Aaron Esau)는 지난 5월 5월에 PinTheft를 공개했으며, 커널 패치도 이미 제공되고 있습니다. 업스트림 수정 후보 은 2026년 5월 5일 netdev 커널 메일링 리스트에 게시되었습니다. CVE-2026-43494가 할당되었으며, CVSS 점수는 없습니다. 현재 상태는 아래의 'KernelCare 리부트리스 패치' 섹션을 참조하십시오.
위험도: 로컬 벡터; 호스트에서 임의의 로컬 사용자로 코드를 실행할 수 있는 권한이 필요하며, 사용자 상호작용은 필요하지 않음. 실제 악용을 위해서는 대상 시스템에 다음 조건이 모두 충족되어야 함: RDS 및 RDS_TCP가 사용 가능하고 로드 가능해야 하며, io_uring이 활성화되어 있고, 읽기 가능한 SUID-root 바이너리가 존재하며, x86_64 페이로드가 있어야 함(기술 자체는 아키텍처에 구애받지 않지만, PoC는 아키텍처에 특화되어 있음). V12는 테스트한 일반적인 배포판 중 Arch Linux에서만 RDS가 기본적으로 로드 가능하다고 밝혔습니다. 다른 배포판들은 해당 모듈이 자동 로딩되지 않도록 차단된 상태로 제공하거나 아예 빌드하지 않습니다.
이 문제가 중요한 이유: 해당 익스플로잇 체인은 신뢰할 수 있으며, 개념 증명(PoC)이 공개된 상태이지만 아직 CVE나 공식 공급업체 권고문은 발표되지 않았습니다. 영향을 받는 배포판에 구축된 멀티테넌트 리눅스 시스템(공유 호스팅, CI 러너, 컨테이너 호스트)은 즉시 위험에 처해 있는 것으로 간주해야 합니다.
지금 바로 다음 조치를 취하십시오. 호스트에서 RDS 워크로드를 실행하지 않는 경우(대부분의 경우 그렇습니다), modprobe 규칙을 사용하여 rds 및 rds_tcp 모듈을 차단하십시오. io_uring이 필요하지 않고 커널 버전이 6.6 이상인 경우, sysctl 명령 하나로 이를 추가로 비활성화할 수 있습니다. 문제 해결 명령어와 구형 커널용 대체 방안은 아래에 나와 있습니다.
이번 달에 다섯 번째 긴급 재부팅 창이 뜨는 걸 원치 않으신가요?
KernelCare는
다운타임이나 서비스 중단 없이 재부팅 없이 리눅스 커널 패치를 적용합니다.
*업데이트 (2026년 5월 21일, UTC 기준 오후 12시): 모든 배포판(Debian 12 및 Proxmox8 제외)용 KernelCare 패치가 메인 피드로 이동되었습니다.
자세한 내용
V12 Security는 2026년 5월 ‘PinTheft’ 개념 증명(PoC)과 기술 보고서를 발표했다. 이 취약점을 발견한 사람은 아론 에사우(Aaron Esau)로 알려져 있다. 이 결함 자체는 2018년 4.17 버전부터 리눅스 커널에 존재해 왔으나, 이 취약점을 악용하는 체인은 버그가 도입되었을 당시에는 존재하지 않았던 io_uring 기능에 의존하고 있다.
이 커널 수정안은 2026년 5월 5일 netdev 메일링 리스트에 공개되었습니다. 다운스트림 배포판 커널들은 아직 이 수정안을 반영 중입니다. KernelCare 엔지니어링 팀은 해당되는 지원 대상 커널을 위해 재부팅 없이 적용 가능한 패치를 준비 중입니다.
초기 보도 중 일부는 PinTheft를 커널 6.13 버전 및 그 이후 버전과 직접적으로 연관 지었습니다. 이는 공개된 PoC(개념 증명)의 의존성을 반영한 것이지, 근본적인 버그의 발생 시기를 나타내는 것은 아닙니다. RDS 제로카피 경로에서 발생한 참조 카운트 문제는 훨씬 오래전부터 존재해 왔지만, PoC와 동일한 작동 방식을 가진 익스플로잇 체인을 구현하려면 여전히 최신 io_uring 기능이 필요합니다.
이 취약점 공격의 작동 원리
프로그램이 네트워크 소켓을 통해 데이터를 전송할 때, 커널은 일반적으로 해당 데이터를 프로그램의 메모리에서 커널 버퍼로 복사합니다. CPU 사이클을 절약하기 위해 최신 커널은 “제로카피(zerocopy)” 전송 방식도 제공합니다. 이 방식에서 커널은 사용자 메모리 페이지를 잠근 후 이를 직접 사용합니다. 고성능 데이터센터 네트워킹을 위해 고안된 비교적 덜 알려진 프로토콜인 RDS는 이 제로카피 모드를 지원합니다.
이 버그는 제로카피 전송이 도중에 실패했을 때 RDS가 이를 처리하는 방식에 기인합니다. 커널이 동일한 페이지를 한 번이 아니라 두 번 해제하게 됩니다. 전송이 실패할 때마다 첫 번째 사용자 페이지에서 참조가 하나씩 소모됩니다.
그 자체만 보면 이는 단순한 회계 처리상의 버그에 불과합니다. 하지만 PinTheft는 현대적인 리눅스 비동기 I/O 인터페이스인 io_uring을 통해 이를 루트 권한 획득 공격으로 전환합니다. io_uring을 사용하면 프로그램이 메모리 페이지를 고정 버퍼로 등록할 수 있는데, 이 과정에서 해당 페이지에 1,024개의 참조가 추가됩니다. 이후 공격자는 1,024회의 실패한 RDS 제로카피 전송을 강제로 유발하여, 이 모든 참조를 감지되지 않게 소진시킵니다. 이제 커널은 아무도 해당 페이지를 사용하지 않는다고 판단하여 페이지를 해제하지만, io_uring은 여전히 해당 페이지에 대한 포인터를 보유하고 있습니다.
다음으로, 공격자는 임의의 SUID 루트 바이너리를 실행합니다. 커널은 해당 바이너리를 페이지 캐시 내의 동일한 해제된 페이지에 로드합니다. 오래된 버퍼에 대한 단 한 번의 io_uring 쓰기 작업만으로도 메모리 내의 바이너리가 셸코드로 덮어쓰게 됩니다. 이제 SUID 바이너리를 실행하면 사용자는 루트 셸로 진입하게 됩니다.
디스크상의 파일은 변경되지 않습니다. 메모리에 있는 페이지 캐시 사본이 덮어쓰기됩니다. 이는 정리 작업에 중요한데, 이에 대해서는 완화 조치 섹션에서 다룹니다.
이 잠재적인 참조 카운트 버그는 리눅스 4.x 버전에서 RDS 제로카피(zerocopy) 지원이 도입된 시점으로 거슬러 올라가는 것으로 보입니다. PoC에서 보여준 것처럼 안정적으로 이 버그를 악용하려면 더 최신 버전의 io_uring 기능(특히 6.12 버전부터 지원되는 IORING_REGISTER_CLONE_BUFFERS)이 추가로 필요하므로, 버그 자체는 오래되었지만 실제로 악용할 수 있는 기간은 더 짧습니다.
누가 영향을 받나요?
중요한 것은 배포판 이름이 아니라, 실행 중인 커널이 RDS 모듈을 로드할 수 있는지 여부입니다. 다음 섹션에 소개된 명령어를 사용하여 커널 구성 및 모듈 로딩 정책을 직접 확인하십시오.
기본으로 로드 가능한 RDS(연구진이 확인함): Arch Linux.
RDS 모듈은 포함되어 있지만 기본적으로 자동 로딩이 차단되어 있습니다: Ubuntu(현재 지원되는 모든 릴리스, kmod 패키지의 블랙리스트 파일을 통해), Debian 11 및 12(로컬 취약점 완화를 위해 RDS 자동 로딩을 비활성화하는 Debian 전용 패치를 통해), Fedora(CONFIG_RDS=m, 하지만 모듈은 kernel-modules-extra에 포함되어 있으며 자체 블랙리스트 파일을 포함하고 있음). 이러한 시스템에서 PoC를 수행하려면 관리자나 워크로드가 의도적으로 rds_tcp를 먼저 로드해야 합니다. 또한 독립적인 테스트 결과에 따르면, 기본 Debian 기반 시스템에서 모듈을 로드하는 것만으로는 PoC가 항상 성공하는 것은 아니므로, 동작 방식은 시스템마다 다를 수 있습니다.
벤더 또는 구성별 검증이 필요합니다: Amazon Linux 2023, openSUSE Tumbleweed, Proxmox VE 7/8/9, Oracle Linux UEK 6 및 7. /boot/config-$(uname -r)에서 CONFIG_RDS를 확인하고, /etc/modprobe.d/ 및 /lib/modprobe.d/ 디렉터리에서 벤더가 제공한 modprobe 규칙을 찾아보십시오.
영향을 받지 않는 경우: 기본 Red Hat 호환 커널을 실행하는 RHEL, AlmaLinux, Rocky Linux 및 CentOS Stream 8/9/10 — 이러한 빌드에는 RDS가 포함되어 있지 않습니다. 또한 RHEL 9 및 10은 기본적으로 io_uring을 비활성화하여 해당 체인의 나머지 부분도 제거합니다.
위의 모든 내용을 무효화하는 한 가지 주의사항이 있습니다. 사용자 정의 커널이나 대체 커널을 실행하는 호스트는 해당 호스트가 속한 배포판과 다르게 동작할 수 있습니다. 특히 Oracle Linux UEK는 종종 RHCK와 함께 실행되며, 다른 상태를 유지합니다.
지금 바로 위험을 줄이세요
실제로 적용할 수 있는 두 가지 해결 방법이 있습니다. 호스트가 실제로 RDS를 사용하는지, 아니면 io_uring을 사용하는지에 따라 선택하십시오.
대부분의 호스트에 권장: RDS 모듈 차단
대부분의 리눅스 서버는 RDS를 사용하지 않습니다. RDS는 주로 오라클 클러스터웨어와 일부 HPC 인피니밴드 환경에서 사용됩니다. RDS 워크로드를 실행하지 않는 호스트에서는 rds 및 rds_tcp 모듈이 로드되지 않도록 설정하는 것이 가장 간단한 해결 방법입니다.
sudo sh -c "printf 'install rds /bin/false\ninstall rds_tcp /bin/false\n' > /etc/modprobe.d/pintheft.conf" sudo rmmod rds_tcp rds 2>/dev/null || true
이 취약점은 메모리 내의 SUID 바이너리만 덮어씁니다. 디스크상의 파일은 변경되지 않습니다. 취약점 대응 조치가 이루어지기 전에 공격 대상이 되었을 가능성이 있는 모든 호스트에서는 페이지 캐시를 비워 메모리 내의 변경 사항을 모두 제거하십시오:
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
커널 패치 또는 KernelCare 라이브 패치 적용 후 원상 복구:
sudo rm /etc/modprobe.d/pintheft.conf
RDS 워크로드( Oracle 클러스터웨어, 특정 HPC 스택 등)를 실행 중인 경우 , 이 완화 조치를 적용하지 마십시오. 아래의 io_uring 대안을 사용하거나 패치된 커널이 출시될 때까지 기다리십시오.
대안: 시스템 전체에서 io_uring 비활성화
kernel.io_uring_disabled sysctl은 Linux 6.6 이상에서 사용할 수 있습니다. 이보다 오래된 배포판 커널(Ubuntu 22.04 (5.15), Debian 11(5.10) 및 12(6.1), Amazon Linux 2023(6.1), RHEL 9(5.14), Ubuntu 24.04(6.8 — 소수 버전 확인 필요) 등)에서는 이 sysctl을 사용할 수 없습니다.
해당 커널에서는 RDS 모듈을 차단하는 것이 현실적인 방법입니다. 구형 커널에서 io_uring을 완전히 비활성화하려면 부팅 매개변수를 설정하거나 커널을 재컴파일해야 하며, RDS를 차단하는 것에 비해 그만한 노력을 들일 가치가 없는 경우가 많습니다.
작업 부하에서 io_uring이 필요하지 않다면, 대신 익스플로잇 체인의 나머지 절반을 중단하십시오.
sudo sysctl -w kernel.io_uring_disabled=2
이는 RHEL 10의 기본 설정이며, RDS 상태와 관계없이 해당 배포판 계열이 적용 범위에서 제외되는 이유입니다. io_uring을 비활성화하면 일부 최신 데이터베이스 엔진 및 비동기 I/O 워크로드에 영향을 줄 수 있으므로, 적용하기 전에 해당 환경에서 반드시 테스트해 보시기 바랍니다.
재부팅 후에도 유지:
echo 'kernel.io_uring_disabled = 2' | sudo tee /etc/sysctl.d/99-pintheft.conf sudo sysctl --system
보안 강화된 호스트에서의 다층 방어
실행 시점에 커널 모듈을 로드하지 않는 워크로드의 경우, 부팅 후 `kernel.modules_disabled=1`을 설정하면 이후의 모든 `modprobe` 호출이 성공하지 못하게 되어, RDS 및 기타 모든 모듈에 대한 자동 로드 경로가 한 번에 차단됩니다.
이는 RDS를 구체적으로 블랙리스트에 등록하는 것보다 더 강력한 조치이므로, 런타임 모듈 로딩이 전혀 예상되지 않는 경우(핫플러그 하드웨어, 온디맨드 파일 시스템 또는 네트워킹 모듈, 첫 사용 시 모듈을 로딩하는 컨테이너 런타임이 없는 경우)에만 사용해야 합니다.
sudo sysctl -w kernel.modules_disabled=1
이 설정은 부팅 중 단방향 스위치와 같으므로, 재부팅하지 않고는 0으로 되돌릴 수 없습니다. 실제 환경에 적용하기 전에 테스트 환경에서 먼저 검증하시기 바랍니다.
호스트가 노출되어 있는지 확인하세요
아래의 세 가지 확인 절차를 수행한 후, 그 결과를 이 섹션 마지막 부분에 제시된 기준과 비교해 보십시오.
- 커널 빌드에 RDS가 포함되어 있나요?
grep -E 'CONFIG_(RDS|RDS_TCP|IO_URING)' /boot/config-$(uname -r) modprobe -n -v rds_tcp ls /lib/modules/$(uname -r)/kernel/net/rds/ 2>/dev/null
- io_uring이 활성화되어 있습니까?
cat /proc/sys/kernel/io_uring_disabled
- 해당 모듈들은 이미 차단 목록에 포함되어 있나요?
grep -rEn '^\s*(blacklist|install)\s+rds' /etc/modprobe.d/ /etc/modules-load.d/ 2>/dev/null
호스트는 다음 조건이 모두 충족될 때만 유효한 대상이 됩니다: CONFIG_RDS 및 CONFIG_RDS_TCP가 사용 가능하고, io_uring_disabled가 0이며, rds 및 rds_tcp 모듈이 블랙리스트에 등재되어 있지 않아야 합니다.
KernelCare 재부팅 없이 적용되는 패치
이 섹션은 패치가 적용될 때마다 업데이트됩니다. 게시물 상단의 업데이트 날짜를 확인해 주세요.
2026년 5월 21일 오후 12시(UTC) 기준 현황: 모든 배포판(Debian 12 및 Proxmox8 제외)용 KernelCare 패치가 메인 피드로 이동되었습니다.
테스트 피드에 제공되면:
kcarectl --update --prefix test
검증이 완료되면, 패치는 다음 예정된 실행 시점에 적용되거나 필요에 따라 수동으로 적용할 수 있습니다:
kcarectl --update
패치가 적용되었는지 확인하십시오. CVE가 할당되면 다음을 통해 확인하십시오:
kcarectl --patch-info | grep CVE-XXXX-XXXXX # CVE 번호로 대체
향후 전개에 주목해야 할 점
- CVE 할당 (작성 시점 기준 없음)
- V12 Security 또는 커널 보안 팀의 공식 권고
- Ubuntu, Debian, Amazon Linux, openSUSE, Oracle 및 Proxmox의 커널 업데이트 배포
- 지원되는 모든 커널 계열에 대한 KernelCare 패치 배포
이 게시물은 CVE 번호가 할당되고 KernelCare 패치가 테스트 버전에서 안정 버전으로 전환될 때 업데이트될 예정입니다. KernelCare 고객은 패치가 메인 피드로 배포되면 자동으로 패치를 받게 됩니다.
모든 커널에 패치를 적용하며, 재부팅이 필요하지 않습니다
아직 KernelCare를 사용 중이 아니시라면, 지금이 바로 재부팅 없이 패치를 적용하는 방식이 긴급 유지보수 시간이나 가동 중단 없이 중요한 리눅스 시스템을 어떻게 보호할 수 있는지 확인해 볼 좋은 기회입니다.