
AlmaLinux 및 Rocky Linux 8, 9, 10에서 CVE-2026-98432(및 CVE-2026-99999)에 대한 kpatch livepatch
재부팅 없이 실행 중인 AlmaLinux 또는 Rocky Linux 8, 9, 10 호스트(x86_64)에서 CVE-2026-98432를 수정하는 livepatch 모듈입니다. CVE-2026-99999에 대한 수정도 없는 커널에서는 동일한 모듈이 그것까지 수정하므로, 호스트는 커널에 두 가지 중 어느 것이 없든 하나의 모듈만 필요합니다.
상태 (2026-11-02): 모든 모듈이 빌드되고 로드 테스트를 거쳤으며, 아직 릴리스된 것은 없으므로 적용할 것이 없습니다. 다음 단계는 릴리스와, 릴리스된 각 모듈에 대해 한 줄 명령을 테스트하는 것입니다. 그때까지 scripts/livepatch.sh의 테이블에는 모듈이 없으며 모든 커널을 거부합니다.
684개 커널: AlmaLinux 380개와 Rocky Linux 304개, 8.3부터 10.2까지, tools/kernels.tsv에 나열되어 있습니다. 이는 SRPM과 debuginfo가 배포판 미러(vault 포함)에 있는 모든 커널이며, x86_64에 한정되고, debuginfo가 어떤 미러에도 없는 Rocky의 5.14.0-611.41.1.el9_7은 제외됩니다. 여기에는 이전 Rocky 저장소가 다루지 않았던 Rocky의 유일한 8.3 커널인 4.18.0-240.22.1.el8과, 이전 저장소 이후 두 배포판이 릴리스한 커널들이 포함되며, 4.18.0-553.180.1.el8_10(AlmaLinux), 5.14.0-687.61.1.el9_8, 6.12.0-211.69.1.el10_2까지입니다. AlmaLinux 10의 x86_64_v2 변형은 다루지 않습니다.
684개 중 666개는 CVE-2026-99999에 대한 수정도 없으며, 해당 모듈이 둘 다 포함합니다. 나머지 18개는 이미 그것을 가지고 있으며(AlmaLinux 4.18.0-553.177.1.el8_10 및 Rocky 553.178.1.el8_10, 그리고 두 배포판 모두의 5.14.0-687.59.1.el9_8 및 6.12.0-211.67.1.el10_2부터), 해당 모듈은 CVE-2026-98432의 변경만 포함합니다.
각 모듈은 CI에서 빌드되었고, 2026-10-31에 VM에서 scripts/livepatch.sh를 사용해 해당 커널에 적용되었으며(tools/loadtest.sh), 배포판 및 마이너 버전당 한 번씩 총 40회 실행되었습니다. 684개 모두 RESULT: PASS를 출력했습니다. 각 실행에서:
inet_sock_destruct와 tcp_v4_reqsk_destructor가 vmlinux의 패치된 함수로 나열됩니다.tools/tcpopt.py). 이는 수정이 변경하는 두 해제 경로를 옵션이 있는 상태에서 구동합니다. IP 옵션이 없으면 이들은 NULL만 해제합니다.nfnetlink_queue, xt_CHECKSUM(그리고 9와 10에서는 nf_conntrack_bridge)에서 효과를 발휘합니다. 8과 9(511개 커널, 그리고 Rocky의 8.3)에서는 조작된 프레임이 배포된 커널에 의해 단편화되었고 모듈이 적용된 상태에서 드롭되었습니다. 10(154개 커널)에서는 프레임이 결함에 도달하기 전에 거부되므로, 해당 프로브는 그곳에서는 어느 쪽으로도 아무것도 말해주지 않습니다.테스트하지 않은 것: 경쟁 조건 자체입니다. 배포된 커널에서 CVE-2026-98432를 보이고 모듈과 함께 그것이 없음을 보이려면 KASAN과 재전송된 SYN과 자식의 해제가 교차하는 인위적인 인터리빙이 필요하며, 이는 이 VM들에서 요청 시 발생하지 않습니다. 또한 어떤 모듈도 Secure Boot가 켜진 상태에서 테스트되지 않았으며(서명되지 않아 거부될 것임), kpatch.service에 의해 부팅 시 로드되지도 않았습니다.
tools/mkdiffs.sh는 마이너 버전의 모든 커널 SRPM을 포팅합니다. 먼저 %prep가 하는 것처럼 SRPM 자체의 패치를 해당 tarball에 적용합니다(tools/prep.py). AlmaLinux는 그런 방식으로 자체 수정을 포함하며, 그중에는 4.18.0-553.177.1.el8_10의 CVE-2026-99999에 대한 수정이 있고, 10.2의 6.12.0-211.69.1은 Red Hat의 211.56.1 tarball에 466개의 패치를 더한 것이므로, 순수 tarball을 대상으로 만든 포트는 커널이 가진 것을 놓치게 됩니다. 그런 다음 변경된 줄을 tools/ref/와 대조하여 확인합니다. CVE-2026-98432의 것은 업스트림의 것과 같아야 하고, CVE-2026-99999의 것은 8 또는 9의 경우 AlmaLinux의 패치, 10의 경우 업스트림의 것과 같아야 하며, 커널에 해당 수정이 있는 곳에서는 없어야 합니다. 684개 모두 일치했습니다. tools/port.py는 또한 트리의 kfree_rcu()가 NULL 포인터를 건너뛰지 않을 경우 중단합니다. 두 포인터는 보통 모두 NULL이기 때문입니다.
8과 9는 kpatch-build로, 10은 커널 자체의 klp-build로 빌드되며, 둘 다 replace 패치를 빌드하는데, 이것이 모듈이 이전 모듈을 이어받는 방식이다.
업스트림 수정은 torvalds/linux e3f33b0a1d89, "ipv4: free inet_opt and ireq_opt after an RCU grace period"이다. SYN이 IP 옵션을 실어 보내면, 리스너는 이를 복사하지 않고 요청 소켓(ireq_opt)에 보관하고 자식 소켓(inet_opt)에 넘긴다. 동일한 요청에 대한 재전송된 SYN은 다른 CPU에서 SYN-ACK로 응답될 수 있으며, 이때 RCU 아래에서 해당 옵션들을 읽는 동안 자식이 닫히고 inet_sock_destruct()가 일반 kfree()로 이를 해제한다: use after free이다. 요청 소켓 마이그레이션도 tcp_v4_reqsk_destructor()에서 같은 문제를 가진다. 수정은 둘 다 kfree_rcu()로 해제한다.
어느 배포판도 수정을 출시하지 않았다: 2026-10-27 기준 AlmaLinux와 Rocky Linux 8, 9, 10의 최신 커널은 변경 로그에 해당 CVE를 명시하지 않았으며, 4.18.0-305.3.1.el8_4, 4.18.0-553.179.1.el8_10, 5.14.0-687.61.1.el9_8, 6.12.0-211.68.1.el10_2의 소스는 여전히 두 포인터를 kfree()로 해제한다.
nsrg-fmlorg/kpatch-alma-cve-2026-99999와 nsrg-fmlorg/kpatch-rocky-cve-2026-99999에 의해 배포판별로 별도로 더 일찍 수정되었다. 두 배포판 모두 이제 해당 수정이 포함된 커널을 출시하며, 4.18.0-553.177.1.el8_10 (AlmaLinux) 또는 553.178.1.el8_10 (Rocky), 5.14.0-687.59.1.el9_8, 6.12.0-211.67.1.el10_2 이후 버전부터이다. 커널에 이 수정이 없는 경우, 이 저장소의 모듈은 이전 모듈들과 동일한 변경을 담고 있으며, 이미 로드된 이전 모듈을 대체한다(위의 해당 모듈이 있던 665개 커널 각각에서 테스트됨).
| 경로 | 설명 |
|---|---|
build.sh | 배포판의 컨테이너 안에서 특정 커널용 모듈을 빌드한다 |
tools/kernels.tsv | CI가 빌드하는 커널: 배포판, 마이너, 커널 버전 |
tools/select-kernels.py | CI 실행 시 이 중 어떤 커널을 선택할지 |
tools/mkdiffs.sh | 특정 마이너의 모든 커널에 대한 포트를 만들고 tools/ref/와 대조하여 검사한다 |
tools/prep.py | 포팅 전에 %prep가 하는 것처럼 SRPM 자체의 패치를 해당 tarball에 적용한다 |
tools/port.py | 커널 트리에 적용되는 변경 자체 |
tools/kpatchify.py | 포트를 kpatch-build에 입력되는 형태로 변환한다 |
tools/klp-overlay.sh, tools/klp-overlay-lds.py, tools/klp-overlay/ | 10.2의 klp-build를 10.0과 10.1에 제공한다 |
tools/klpsymcheck.py | klp-build 모듈의 심볼을 출시된 커널과 대조하여 검사한다 |
tools/loadtest.sh, tools/loadtest-guest.sh, tools/loadtest-bootprep.sh, tools/loadtest-bootinfo.sh | VM에서 출시된 커널을 부팅하고 모듈을 적용, 검사, 제거한다 |
tools/csum-probe.sh, tools/csum-inject.py | CVE-2026-99999를 변경 전후로 프로브한다 |
tools/tcpopt.py | IP 옵션이 존재하는 상태에서 CVE-2026-98432가 변경하는 두 해제 경로를 구동한다 |
tools/doccheck.py | 파일이 두 README 모두에 명시되지 않았거나 링크가 깨졌을 때 실패한다 |
scripts/livepatch.sh | 호스트에서 출시된 모듈을 적용, 검사, 제거한다 |
scripts/build-local.sh | 자신의 머신에서 특정 커널의 모듈을 빌드하고 로드 테스트한다 |
.github/workflows/diffs.yml | 두 배포판의 모든 마이너에 대해 tools/mkdiffs.sh를 실행한다 |
.github/workflows/build.yml | 모듈을 빌드하고 로드 테스트한다 |
.github/workflows/docs.yml | tools/doccheck.py를 실행한다 |