리눅스 TCP Use-After-Free: 패치 vs 완화
CVE-2026-98432 리눅스 커널 TCP UAF(CVSS 9.8)의 패치 vs 완화 선택 기준. 4줄짜리 수정이 방화벽 규칙보다 나은 이유를 정리했습니다.

커널에 원격에서 도달 가능한 TCP 핸드셰이크 경로의 use-after-free가 있는데, 배포판은 아직 수정본을 내놓지 않았고, 누군가 이미 동작하는 root 익스플로잇을 시연해 버렸습니다. 그럼 계획은 뭘까요? 그냥 기다리면서 버틸지, 아니면 방화벽에서 패킷을 드롭하기 시작할지. CVE-2026-98432로 공개된 리눅스 TCP use-after-free는 보안 운영에서 가장 오래된 고민인 패치냐 완화냐를 따져볼 좋은 사례이고, 솔직히 말해 두 선택지는 전혀 대등하지 않습니다. 그중 하나만 실제로 문제를 해결하거든요.
저도 이 판단을 양쪽에서 해봤습니다. 완화 조치가 서류상으로는 충분해 보여서 긴급 커널 롤아웃을 미룬 적도 있었고, 반대로 '임시' 방화벽 규칙이 운영 환경에서 8개월 동안 조용히 썩어 가는 걸 지켜본 적도 있습니다. 그 규칙이 가리고 있던 CVE는 다들 잊은 상태였죠. 이번 버그는 어떤 접근이 언제 유리한지 따져볼 좋은 계기입니다. 트레이드오프가 유독 분명하게 드러나거든요.
실제 TCP Use-After-Free의 정체
메커니즘을 봐야 완화가 무엇을 할 수 있고 무엇을 못 하는지 판단할 수 있습니다. 서버가 IPv4 TCP 연결을 받으면 커널은 반쯤 열린 핸드셰이크를 가벼운 request socket으로 추적하다가, 핸드셰이크가 끝나면 이를 정식 소켓으로 승격합니다. 상대방의 IPv4 헤더에 옵션이 붙어 있었다면, 커널은 응답에 그 옵션을 되돌려 주기 위해 옵션을 저장해 둡니다. 문제는 여기서 발생합니다. 커널이 저장된 옵션을 복사하지 않고 새 연결에 그대로 넘긴 뒤 바로 해제해 버리는데, 다른 CPU는 핸드셰이크 응답을 만들려고 여전히 그 값을 읽고 있을 수 있습니다. 인증이 필요 없는 원격 피어가 도달할 수 있는 use-after-free이고, 여러분 애플리케이션 코드가 한 줄도 실행되기 전에 일어난다는 뜻입니다.
Eric Dumazet가 올린 업스트림 수정은 4줄입니다. 두 개의 일반 kfree() 호출을 kfree_rcu()로 바꾸는 것인데, 이렇게 하면 모든 리더가 메모리 사용을 끝낼 때까지 해제가 미뤄집니다. 이 부류의 버그에 대한 정석적인 커널 수정이에요. RCU 리더는 여러분이 볼 수 없는 참조를 쥐고 있으니, 유예 기간(grace period)이 끝나기를 기다렸다가 메모리를 회수하는 겁니다. 커널 자체 CNA는 이 문제에 CVSS 9.8을 매겼습니다. Red Hat은 처음에 8.1로 평가했다가 10월 30일 네트워크 전제 조건이 없다는 점을 근거로 9.8 Critical로 올렸습니다.
노출 위험을 계산할 때 바뀌는 세부 사항이 두 가지 있습니다. 첫째, 레이스가 실패해도 조용히 떨어집니다. 실패한 시도는 핸드셰이크만 실패시키고 시스템을 패닉으로 날리지 않으니, 공격자는 원하는 만큼 계속 재시도할 수 있습니다. 둘째, Anthropic이 시연한 익스플로잇 경로는 멀티패스 TCP(MPTCP) 리스너가 있는 호스트를 노립니다. Go 보안팀에 따르면 Go 1.24부터 Go 프로그램은 커널이 허용하는 리눅스 환경에서 기본으로 MPTCP 리스너를 엽니다. 여러분의 플릿을 점검해 보세요.
ss -Mlnp # MPTCP listeners and their owning processes
sysctl net.mptcp.enabled # 1 means apps may open MPTCP sockets
ss -M 출력이 비어 있으면 MPTCP 리스너가 없다는 뜻입니다. 그래도 안심하긴 이릅니다. Go 팀도 분명히 말했지만, 근본 버그는 MPTCP에만 해당하는 문제가 아닙니다. 핸드셰이크 처리 과정의 일반적인 UAF이고, MPTCP는 누군가 종단 간 공격을 입증한 경로일 뿐입니다.
패치 경로: 수정된 커널, 재부팅, 끝
패치는 설명하기 지루할 만큼 단순합니다. 취약점을 없애는 유일한 선택지이고, 다른 방법은 취약점의 모양만 바꿉니다. 수정된 커널은 10월 11일과 15일에 유지보수 중인 모든 stable 라인에 올라왔습니다. 버그는 Linux 4.4까지 거슬러 올라가기 때문에, 업스트림이 더 이상 손대지 않는 오래된 커널을 쓰는 장기 운영 시스템도 많이 영향을 받습니다.
문제는 재부팅입니다. 커널 업데이트는 머신이 새 커널로 부팅되기 전까지 아무 효과가 없고, 실제 운영 비용은 바로 이 재부팅에서 나옵니다. Kubernetes 노드를 비워야 하고, 페일오버 리허설을 해야 하고, 업무 시간에는 아무도 건드리고 싶어 하지 않는 데이터베이스 프라이머리가 있습니다. 그래서 '그냥 패치하세요'는 항상 맞지만 조언으로서는 결코 충분하지 않습니다. 롤아웃 계획이 필요합니다. 카나리 호스트를 먼저 올리고, 다음으로 무상태 티어를, 마지막으로 유지보수 윈도우를 잡아 상태 저장 티어를 올리는 식이죠. 전 플릿 긴급 커널 교체를 해본 적이 있다면 이미 감이 올 겁니다. 이런 일을 잘 해내는 팀은 아무 일도 없을 때 노드 드레이닝을 리허설해 둔 팀입니다. 조용한 화요일에 쌓은 방어적 엔지니어링 습관이 9.8짜리 취약점이 터졌을 때 빛을 발합니다.
짚고 넘어갈 함정이 하나 있습니다. dpkg -l이나 rpm -q kernel에서 수정된 패키지가 보여도, 실행 중인 커널이 그보다 이전 버전이라면 의미가 없습니다. 실제로 돌고 있는 것을 알려주는 건 uname -r입니다. RHEL 계열이라면 needs-restarting -r로 재부팅이 대기 중인지 바로 확인할 수 있습니다. 사후 보고서를 검토하다 보면 '패치된' 플릿이 실제로는 설치만 되고 실행되지 않은 커널들의 집합이었던 경우를 본 적이 있습니다. 실행 중인 버전은 업스트림 번호가 아니라 배포판 트래커와 대조해서 확인하세요. 배포판 커널은 자체 버전 체계 아래에 백포트를 담고 있으니까요.
완화 경로: IPv4 옵션 드롭, MPTCP 비활성화
공개된 임시 완화책은 취약 경로를 트리거하는 IP 옵션이 달린 수신 IPv4 TCP 패킷을 드롭하는 nftables 규칙입니다. 여기에 MPTCP를 쓰지 않는다면 sysctl -w net.mptcp.enabled=0으로 끄는 것도 함께 적용할 수 있습니다. 둘 다 빠르고, 재부팅이 필요 없으며, 구성 관리 도구로 반나절이면 배포할 수 있습니다. 매력은 바로 여기에 있습니다.
이제 기대를 살짝 낮춰야 할 부분입니다. Red Hat 공지에는 이 규칙이 “취약점 노출을 줄이지만 완전히 막을 수는 없다”고 적혀 있습니다. 이 문장은 두 번 읽어 보세요. 완화는 공격 표면을 좁힐 뿐 닫지는 못합니다. 일반 트래픽에서 IP 옵션이 달린 패킷은 드물고, 대부분의 미들박스가 어차피 이를 떨어뜨리기 때문에 인터넷에서의 익스플로잇 가능성은 낮다고 여겨집니다. 하지만 '드물다'와 '불가능하다'는 전혀 다른 말입니다. 게다가 이 버그는 누군가 우연히 테스트한 옵션 경로에만 있는 게 아니라 일반적인 핸드셰이크 코드에 있습니다.
더 미묘한 비용도 있습니다. 완화책은 해결됐다는 잘못된 안도감을 줍니다. 티켓은 '거의 끝남'으로 옮겨지고, 패치 작업의 긴박함은 빠져나가며, 6주 뒤에도 여러분은 왜 이걸 하고 있었는지 기억이 흐려진 채 취약한 커널을 패킷 필터 뒤에서 계속 돌리고 있을 겁니다. 이 패턴은 PHP의 치명적 CVE 대응 기간을 다룬 글에서도 이야기한 적이 있습니다. 그때도 취약한 것을 아예 내린 팀이, 영리한 필터를 여러 겹 쌓은 팀보다 나은 결과를 냈습니다. 스택은 달라도 교훈은 같습니다.
패치냐 완화냐: 언제 무엇이 이기는가
압박 속에서 이런 판단을 여러 해 해온 끝에 정리한 솔직한 점수표입니다.
- 사용 중인 배포판에 수정된 커널이 나왔다. 패치가 확실히 이깁니다. Debian, SUSE Enterprise, Oracle UEK, Amazon Linux 모두 수정본을 냈습니다. 4줄짜리 업스트림 수정보다 나은 완화책은 없습니다. 재부팅 일정을 잡고, 링 단위로 롤아웃한 뒤 다음으로 넘어가세요.
- 수정된 커널은 아직 없고 노출 위험은 실재한다. 바로 완화하세요. 완화책은 바로 이런 상황을 위해 있습니다. Ubuntu와 RHEL은 10월 말까지도 “Vulnerable”/영향받음 상태였습니다. 인터넷에 노출돼 있고 MPTCP 리스너가 있다면, 오늘 당장 IP 옵션 패킷을 드롭하고 MPTCP를 끄세요. 그리고 수정 커널은 출시를 막고 있는 릴리스처럼 계속 추적하세요.
- 인터넷에 노출돼 있지만 관리형 앞단 뒤에 있다. 긴박함은 줄어듭니다. 트래픽이 로드 밸런서, CloudFront, API Gateway를 거쳐 와서 신뢰할 수 없는 원시 TCP로 인스턴스에 닿지 않는다는 AWS 안내는 타당합니다. 그래도 완화는 비용이 적으니 적용하고, 긴급 주기가 아니라 일반 주기 안에서 패치하세요.
- 단일 코어나 단일 큐 시스템. 우선순위는 낮습니다. 레이스가 성립하려면 여러 CPU에서 패킷이 동시에 처리돼야 합니다. 임베디드 장비와 작은 VM은 숨통이 트이지만, 누구도 재부팅하지 않는 장비가 되기 쉬우니 '우선순위 낮음'이 '영원히 안 함'이 되지 않게 하세요.
- 수명이 다한 커널(업스트림 5.10 이전). 업스트림과 무관하게 쓸 수 있는 선택지는 완화뿐입니다. 이 경우에는 완화가 진짜로 이기는 시나리오인데, 대안은 오지 않을 수도 있는 벤더 백포트이기 때문입니다. 동시에 이 장비 자체가 취약점이라는 강력한 신호이기도 하니, 진짜 해결책은 장비 교체입니다.

배포판 격차가 진짜 이야기다
신경 쓰여야 할 건 버그 자체가 아닙니다. 4줄짜리 UAF 수정은 stable 커널에 매달 들어옵니다. 진짜 문제는 세계에서 가장 큰 서버 배포판 두 곳, Ubuntu와 RHEL이 업스트림 이후 2주가 넘도록 수정 커널을 내놓지 못했다는 점입니다. 반면 Amazon Linux는 모든 커널을 패치했고, 커뮤니티 리빌드인 AlmaLinux는 업스트림보다 먼저 테스트 중인 수정 커널을 내놓았습니다. HN 커뮤니티도 이를 눈치챘고, 불만을 가질 만합니다. 서버 준비성을 가장 세게 내세우는 배포판들이니까요.
실무자 입장에서 결론은 멋있지 않습니다. 노출 기간은 업스트림이 아니라 벤더의 백포트 파이프라인이 정합니다. 이로부터 두 가지가 나옵니다. 첫째, 배포판 트래커 URL을 알고 실제로 감시하세요. 이 CVE는 커널 CNA, Red Hat, 배포판들이 모두 상세 페이지를 올린 동안에도 NVD에서 '접수됨' 상태로 분석 없이 머물러 있었습니다. 둘째, 배포판의 대응 속도를 선택 기준으로 삼으세요. Amazon Linux는 기존 두 강자보다 눈에 띄게 빠른 커널 수정 파이프라인을 방금 보여줬습니다. 마케팅 자료에서는 중요하지 않겠지만, 9.8짜리 취약점이 떨어지는 핼러윈 주말에는 아주 중요합니다.
AI가 쓴 익스플로잇이 시계를 바꾼다
공지에서 가장 중요한 문장은 쉽게 지나치기 쉽습니다. Anthropic은 자사 Claude 모델이 초기 프롬프팅 이후 커널 포인터 누출에서 root 셸까지 한 시간이 안 되는 기계 시간 안에 동작하는 원격 root 익스플로잇을 만들었다고 보고했습니다. 공개하지는 않았고, HN의 회의론자들은 '그냥 믿어 달라'는 식의 표현을 두고 한바탕 놀렸습니다. 그럴 만합니다. 그래도 마케팅 효과를 빼고 봐도 방향은 분명합니다. '다이프가 stable 트리에 들어옴'부터 '동작하는 익스플로잇 존재'까지의 시간이 줄고 있습니다. 익스플로잇 작성의 병목은 버그가 아니라 diff를 읽고 힙 그루밍을 해낼 사람이었는데, 그 병목이 무너지고 있기 때문입니다.
이것은 패치냐 완화냐의 결정 기간을 압축합니다. 익스플로잇 개발에 몇 주가 걸렸다면 '지금은 완화하고, 다음 유지보수 윈도우에 패치하자'도 방어할 수 있었습니다. 하지만 모델이 공개 커밋만 보고 하룻밤 만에 PoC를 뽑아낼 수 있다면, 완화 단계는 몇 시간 단위로 재야 하고 패치 단계도 며칠 안에 끝내야 합니다. 4줄짜리 수정은 공개돼 있고 누구나 연구할 수 있습니다. 익스플로잇도 그만큼 빨리 나왔다고 가정하세요.

제 권고
패치하세요. 완화는 다리 역할로만 쓰고, 그 다리에는 만료일을 붙이세요. 구체적으로는 배포판에 수정 커널이 있다면 지금 롤아웃을 시작하고, 재부팅할 때마다 uname -r로 확인하세요. Ubuntu나 RHEL을 쓰고 있다면 IP 옵션 드롭과 MPTCP 비활성화를 오늘 배포하고, 수정 커널이 없는 상태는 블로커 의존성으로 취급하세요. 트래커는 주간이 아니라 매일 확인하세요. 인터넷에 노출되고 MPTCP 리스너가 있는 것을 먼저 처리하고, 그다음에는 인바운드 TCP를 받는 나머지 전부를 처리하세요. 사실상 거의 모든 시스템이 해당합니다. 컨테이너는 구원자가 아닙니다. 호스트 커널을 공유하니, 노드를 패치하세요.
이 버그가 몇 년마다 새 CVE 번호를 달고 가르쳐 주는 더 깊은 교훈은 이것입니다. 완화는 시간을 벌어 줄 뿐이고, 구멍을 실제로 막는 것은 패치뿐입니다. 그리고 완화가 벌어 주는 시간은 점점 짧아지고 있습니다. 필요해지기 전에 빠르고 안전한 커널 롤아웃 역량을 키워 두세요. 다음 4줄짜리 수정은 이미 누군가의 큐에서 기다리고 있으니까요.


