Giữa tháng 10/2026, nhân Linux có thêm một lỗ hổng mà ai đang vận hành máy chủ cũng nên dừng tay đọc: CVE-2026-98432. Lỗi nằm ngay trong đường xử lý kết nối TCP qua IPv4, tồn tại từ Linux 4.4, và được chấm CVSS 9.8. Bài này tóm lại lỗi là gì, ai bị ảnh hưởng và nên làm gì trên máy chủ của mình.

Lỗi nằm ở đâu?

Khi bắt tay ba bước TCP hoàn tất, hàm tcp_v4_syn_recv_sock() chuyển các IP option của request socket sang socket con mà không sao chép — hai bên dùng chung một vùng nhớ. Nếu cùng lúc một CPU khác đang xử lý gói SYN gửi lại cho đúng request đó và dựng gói SYN-ACK, socket con có thể bị giải phóng giữa chừng. Vùng nhớ chứa option bị kfree() ngay, trong khi CPU kia vẫn đọc nó: một lỗi use-after-free do race condition.

Lỗi xuất hiện từ khi request socket được đưa vào bảng ehash và xử lý mà không cần giữ khóa của listener. Một biến thể tương tự xảy ra khi bật di chuyển request socket (net.ipv4.tcp_migrate_req=1 hoặc chương trình BPF reuseport).

Bản vá rất gọn: đổi sang kfree_rcu() để vùng nhớ chỉ được giải phóng sau một chu kỳ RCU, đúng như các đường xử lý khác vốn đã làm. IPv6 không dính lỗi chính vì phía IPv6 có sao chép option.

Vì sao nghiêm trọng?

Đội Frontier Red Team của Anthropic công bố đã dùng Claude viết bản khai thác chứng minh khái niệm: từ xa, không cần tài khoản, không cần người dùng tương tác, kẻ tấn công lấy được quyền root trên máy chủ có MPTCP listener. Theo mô tả, khâu vượt KASLR mất khoảng 48 phút, khâu thực thi lệnh thêm khoảng 5 phút. Điểm đáng ngại là một lần race thất bại chỉ làm hỏng bắt tay chứ không làm sập máy, nên kẻ tấn công có thể thử lại nhiều lần mà khó bị phát hiện.

Anthropic không công bố mã khai thác. Đến thời điểm viết bài chưa có báo cáo khai thác ngoài thực tế, nhưng với mức độ này thì không nên đợi.

Cần lưu ý: bản khai thác được trình diễn cần MPTCP, nhưng bản thân lỗi không riêng gì MPTCP. Nhóm bảo mật Go đã cảnh báo hệ thống không có MPTCP listener vẫn có thể bị tấn công theo cách khác.

Ai bị ảnh hưởng?

  • Mọi máy chạy kernel Linux từ 4.4 trở lên chưa được vá.
  • Rủi ro cao nhất: máy chủ mở MPTCP listener ra Internet. Lưu ý từ Go 1.24, chương trình Go mặc định bật MPTCP cho socket listen trên Linux — rất nhiều dịch vụ viết bằng Go đang mở MPTCP mà chủ nhân không hề biết.

Các nhánh stable đã có bản vá từ các phiên bản:

5.10.272   5.15.223   6.1.190    6.6.159
6.12.113   6.18.56    7.2.10     7.3

Kernel của bản phân phối (Ubuntu, RHEL, Debian, SUSE…) có số phiên bản riêng, nên hãy xem thông báo bảo mật của bản phân phối mình đang dùng thay vì so trực tiếp với danh sách trên.

Kiểm tra máy chủ của bạn

# Kernel đang chạy
uname -r

# Có MPTCP listener nào đang mở không?
ss -Mltnp

# MPTCP có đang bật ở mức hệ thống không? (1 = bật)
sysctl net.mptcp.enabled

Xử lý thế nào?

1. Cập nhật kernel và khởi động lại

Đây là cách duy nhất thật sự sửa lỗi. Cài kernel mới nhất từ bản phân phối, rồi reboot — cài xong mà không khởi động lại thì máy vẫn chạy kernel cũ. Nếu bản phân phối hỗ trợ livepatch, có thể dùng để vá ngay khi chưa sắp xếp được lịch reboot.

2. Giảm thiểu tạm thời khi chưa vá được

Các biện pháp dưới đây chỉ thu hẹp bề mặt tấn công, không thay thế được kernel đã vá:

  • Tắt MPTCP toàn hệ thống: sysctl -w net.mptcp.enabled=0. Chương trình Go khởi động sau đó sẽ tự quay về TCP thường; chương trình đang chạy có thể gặp lỗi ở kết nối mới, nên khởi động lại dịch vụ sau khi tắt.
  • Tắt MPTCP riêng cho dịch vụ Go: đặt biến môi trường GODEBUG=multipathtcp=0, hoặc thêm godebug multipathtcp=0 vào go.mod rồi build lại. Cách này dễ sót: chỉ một listener bị bỏ quên là đủ, và code gọi SetMultipathTCP sẽ ghi đè cấu hình này.
  • Chặn gói TCP mang IPv4 option ở tường lửa: một số bản phân phối (ví dụ AlmaLinux) đã hướng dẫn rule nftables cho việc này. Lưu ý rule có thể bị vượt qua bởi lưu lượng giữa các container trên cùng máy.
  • Bật init_on_free=1: tham số khởi động này xóa trắng vùng nhớ khi giải phóng, khiến dữ liệu đọc được qua lỗi use-after-free chỉ còn là số 0. Không sửa lỗi nhưng làm khó kẻ tấn công; đổi lại hiệu năng có thể giảm khoảng 1–5% với tải cấp phát bộ nhớ nhiều.
# Ví dụ trên RHEL/AlmaLinux
grubby --update-kernel=ALL --args="init_on_free=1"
reboot
grep -o init_on_free=1 /proc/cmdline

Ghi chú của tôi

Đây là một trong những lỗ hổng kernel đầu tiên mà bản khai thác root từ xa được viết với sự hỗ trợ của AI và công bố công khai quy trình. Khoảng cách từ lúc lỗi được công bố tới lúc có người khai thác được sẽ ngày càng ngắn. Với người vận hành máy chủ, bài học vẫn cũ nhưng gấp hơn: có lịch cập nhật kernel định kỳ, biết rõ máy mình đang mở cổng gì, và đừng để reboot thành việc "để sau".

Tham khảo