🔍 CVE-2026-63978

9.8
CVSS Score
CRITICAL
2026-07-19
2026-10-21 13:19
✅ 완료

🇰🇷 한글 설명

Linux 커널의 net/handshake 모듈에서 네트워크 네임스페이스 종료 시 대기 중인 요청을 제대로 처리하지 못하는 취약점이 발견되었습니다. 함수 인자 순서 오류로 인해 대기 중인 요청이 해제되지 않고 메모리 참조를 유지하며, 이로 인해 리스트 손상 및 레이스 컨디션(Race Condition)이 발생할 수 있습니다.

💡 쉬운 설명

컴퓨터의 네트워크 관리 공간이 닫힐 때 처리되지 못한 작업들이 메모리에 찌꺼기처럼 남게 되는 문제입니다. 이 과정에서 시스템이 엉뚱한 메모리 주소를 참조하게 되어 시스템이 충돌하거나 보안 문제가 생길 수 있습니다.

🇺🇸 원문 (English)

In the Linux kernel, the following vulnerability has been resolved: net/handshake: Drain pending requests at net namespace exit The arguments to list_splice_init() in handshake_net_exit() are reversed. The call moves the local empty "requests" list onto hn->hn_requests, leaving the local list empty, so the subsequent drain loop runs zero iterations. Pending handshake requests that had not yet been accepted are not torn down when the net namespace is destroyed; each one keeps a reference on a socket file and on the handshake_req allocation. Pass the source and destination in the documented order (list_splice_init(list, head) moves list onto head) so the pending list is transferred to the local scratch list and drained through handshake_complete(). Fixing the splice direction exposes a list-corruption race. After the splice each req->hr_list still has non-empty link pointers, threading the stack-local scratch list rather than hn_requests. A concurrent handshake_req_cancel() -- for example, from sunrpc's TLS timeout on a kernel socket whose netns reference was not taken -- finds the request through the rhashtable, calls remove_pending(), and sees !list_empty(&req->hr_list). __remove_pending_locked() then list_del_init()s an entry off the scratch list while the drain iterates, corrupting it. The same call arriving after the drain loop has run list_del() on an entry hits LIST_POISON instead. Have remove_pending() check HANDSHAKE_F_NET_DRAINING under hn_lock and report not-found when drain is in progress. The drain has already taken ownership; handshake_complete()'s existing test_and_set on HANDSHAKE_F_REQ_COMPLETED still arbitrates between drain and cancel for who calls the consumer's hp_done. Use list_del_init() rather than list_del() in the drain so req->hr_list does not carry LIST_POISON after drain releases the entry. The DRAINING guard in remove_pending() makes cancel return false, but cancel still falls through to test_and_set_bit on HANDSHAKE_F_REQ_COMPLETED and drops the request's hr_file reference. Without another pin, if that is the last reference, sk_destruct frees the request while it is still linked on the drain loop's local list. Pin each request's hr_file under hn_lock before releasing the list, and drop that drain pin after the loop finishes with the request.

📍 영향받는 시스템

Linux Kernel (net/handshake 모듈을 사용하는 버전)

⚔️ 공격 벡터

네트워크 네임스페이스를 생성하고 삭제하는 과정에서 발생하는 레이스 컨디션을 이용한 메모리 오염 및 시스템 불안정 유도

🛡️ 대응 방법

Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 list_splice_init() 인자 수정 및 DRAINING 가드 로직을 적용해야 합니다.

🔧 검증 코드

출력된 커널 버전을 확인하여 해당 취약점이 해결된 최신 패치 버전인지 확인합니다.

Shell / Script
uname -r

📊 CVSS Vector String

CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

💻 영향받는 소프트웨어

Linux Kernel