- Người dùng cục bộ không có đặc quyền có thể kết hợp
authencesn, AF_ALG, splice() để tạo ghi 4 byte vào page cache của tệp có thể đọc, từ đó leo thang lên quyền root
- Chạy nguyên vẹn trên nhiều bản phân phối Linux chỉ với một script Python 732 byte, không cần offset theo từng kernel hay điều kiện race, và có thể dùng cùng một exploit để chiếm root shell
- Phạm vi ảnh hưởng bao gồm phần lớn các bản phân phối Linux phổ biến trước khi có bản vá; do
AF_ALG được bật trong cấu hình mặc định nên hệ thống bị phơi nhiễm rộng rãi từ năm 2017 đến thời điểm vá
- Trên host đa tenant, Kubernetes / cụm container, runner CI, và Cloud SaaS cho phép chạy mã người dùng, chỉ một tài khoản thường hoặc một pod cũng có thể dẫn tới root trên host, nên cần ưu tiên vá
- Biện pháp xử lý ưu tiên là vá kernel có chứa commit mainline
a664bf3d603d; trước khi vá, cần vô hiệu hóa algif_aead và chặn AF_ALG đối với workload không đáng tin cậy
Tổng quan lỗ hổng
- Chỉ với một lỗi logic tuyến tính, kết hợp
authencesn, AF_ALG, splice() là có thể leo thang đặc quyền cục bộ dẫn tới ghi 4 byte vào page cache
- Hoạt động giống nhau trên diện rộng các bản phân phối Linux phát hành từ sau năm 2017 chỉ với một script Python 732 byte, không cần offset theo kernel hay race window
- Cùng một binary exploit có thể giành được root shell trên nhiều bản phân phối mà không cần chỉnh sửa
- Chỉ cần một tài khoản cục bộ không đặc quyền; không cần truy cập mạng, tính năng debug kernel hay primitive cài sẵn nào khác
Phạm vi ảnh hưởng
- Phần lớn các bản phân phối Linux phổ biến dùng kernel chưa vá đều nằm trong phạm vi ảnh hưởng
- Trong cấu hình mặc định,
AF_ALG của kernel crypto API thực tế được bật trên gần như mọi bản phân phối mainstream, nên bị lộ trực tiếp từ năm 2017 đến thời điểm vá
- Các bản phân phối đã được xác minh trực tiếp gồm Ubuntu 24.04 LTS, Amazon Linux 2023, RHEL 14.3, SUSE 16
- Debian, Arch, Fedora, Rocky, Alma, Oracle và các nhánh nhúng cũng sẽ bị ảnh hưởng tương tự nếu dùng kernel bị tác động
Môi trường cần ưu tiên vá
- Trên host Linux đa tenant, nhiều người dùng chia sẻ cùng một kernel nên một tài khoản bất kỳ có thể lập tức trở thành root
- Trong Kubernetes / cụm container, page cache được chia sẻ trên toàn host nên một pod có thể chiếm quyền nút và vượt qua ranh giới tenant
- Với runner CI và build farm, mã PR không đáng tin cậy chạy dưới quyền người dùng thường có thể trở thành root trên runner
- Trong Cloud SaaS cho phép thực thi mã người dùng, container hoặc script do tenant tải lên có thể dẫn tới root trên host
- Máy chủ đơn tenant mang tính chất LPE nội bộ mạnh hơn và có thể kết hợp với web RCE hoặc thông tin xác thực bị đánh cắp
- Laptop và workstation một người dùng có mức độ khẩn cấp thấp hơn, nhưng thực thi mã cục bộ vẫn có thể dẫn tới leo thang root ngay lập tức
PoC đã công khai và cách sử dụng
- PoC được công khai để phía phòng thủ có thể dùng cho việc kiểm tra hệ thống và xác minh bản vá của nhà cung cấp
copy_fail_exp.py chỉ dùng thư viện chuẩn Python 3.10+ là os, socket, zlib
- Mục tiêu mặc định là
/usr/bin/su, và có thể truyền một binary setuid khác qua argv[1]
- Nó sửa đổi binary setuid trong page cache; thay đổi không tồn tại sau khi khởi động lại nhưng root shell đạt được vẫn hoạt động thực tế
- Issue tracker
Cách giảm thiểu
- Trước hết cần vá kernel, và phải cập nhật lên kernel của bản phân phối có chứa commit mainline
a664bf3d603d
- Bản vá này đảo ngược tối ưu hóa in-place của
algif_aead được đưa vào năm 2017 để page cache page không còn đi vào writable destination scatterlist
- Trước khi vá, khuyến nghị vô hiệu hóa module
algif_aead
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead 2>/dev/null || true
- Với container, sandbox, CI chạy workload không đáng tin cậy, cần chặn tạo socket
AF_ALG bằng seccomp bất kể đã vá hay chưa
Ảnh hưởng khi vô hiệu hóa
- Trên phần lớn hệ thống, gần như không có tác động đo được
dm-crypt / LUKS, kTLS, IPsec/XFRM, in-kernel TLS, bản dựng mặc định của OpenSSL/GnuTLS/NSS, SSH, và kernel keyring crypto không bị ảnh hưởng
- Chúng dùng trực tiếp kernel crypto API và không đi qua đường
AF_ALG
- Nếu trong OpenSSL có bật rõ ràng engine
afalg, một số đường offload mã hóa nhúng, hoặc ứng dụng tự bind trực tiếp socket aead/skcipher/hash, thì có thể bị ảnh hưởng
- Có thể kiểm tra bằng
lsof | grep AF_ALG hoặc ss -xa
- Tắt
AF_ALG sẽ không làm chậm các đối tượng vốn không gọi tới nó, còn các đối tượng đang dùng nó sẽ quay về các thư viện mã hóa userspace thông thường
Điểm khác với Linux LPE thông thường
- Khác với các Linux LPE điển hình, lỗi này không có race condition và cũng không cần offset riêng theo từng bản phân phối
- Độ tin cậy được nêu là 100% trong một lần chạy, đồng thời không bị giới hạn ở một dải phiên bản kernel hẹp mà bao phủ giai đoạn dài từ 2017 đến 2026
- Chỉ 732 byte và dùng thư viện chuẩn Python nên không cần payload biên dịch sẵn hay phụ thuộc riêng
- Đường ghi vượt qua VFS và page bị hỏng không bị đánh dấu dirty, nên không có gì được ghi xuống đĩa
- Vì page cache được chia sẻ trên toàn host, nó không chỉ là LPE đơn thuần mà còn hoạt động như primitive thoát container
Nguyên lý hoạt động và đặc điểm phát hiện
- Người dùng cục bộ không đặc quyền có thể ghi 4 byte có thể kiểm soát vào page cache của tệp có thể đọc trên hệ thống Linux và dùng điều đó để chiếm quyền root
- Mục tiêu không phải tệp thực trên đĩa mà là page cache trong bộ nhớ; nếu sửa bản sao được cache của
/usr/bin/su thì ở góc nhìn execve điều đó tương đương thay đổi chính binary
- Vì không có thay đổi trên đĩa nên inotify không kích hoạt, và sau khi khởi động lại hoặc cache bị đẩy ra thì tệp gốc sẽ được nạp lại
- Các công cụ hash thông thường như
sha256sum, AIDE, Tripwire đọc page cache qua read(), nên khi phần hỏng còn nằm trong cache thì hash có thể khác với giá trị chuẩn
- Khi cache bị đẩy ra hoặc máy khởi động lại, hash sẽ lại khớp như cũ, và trong ảnh pháp chứng của đĩa cũng chỉ còn tệp chưa bị sửa
- Trong IMA appraisal enforcing mode, nếu bật every-read measurement thì có thể chặn tại thời điểm
execve trước khi binary đã bị hỏng được thực thi
Khác biệt với các lỗ hổng khác
- Thuộc cùng họ với Dirty Pipe, ở chỗ userspace không đặc quyền có thể làm hỏng page cache và ghi vào binary setuid để lấy root mà không cần thay đổi trên đĩa
- Nhưng cơ chế khác nhau: Dirty Pipe khai thác pipe buffer flags, còn Copy Fail khai thác AEAD scratch write vượt qua ranh giới chained scatterlist
- Dirty Pipe yêu cầu kernel 5.8 trở lên với bản vá nhất định, còn Copy Fail bao phủ khoảng thời gian từ 2017 đến 2026
- Khác với Dirty Cow, không cần thắng một race COW dựa trên TOCTOU, cũng không cần thử nhiều lần hay làm hệ thống mất ổn định
Chi tiết bổ sung
/usr/bin/su không phải là bắt buộc; bất kỳ binary setuid-root nào người dùng có thể đọc như passwd, chsh, chfn, mount, sudo, pkexec đều có thể là mục tiêu
- Đây không phải lỗ hổng từ xa; trước hết vẫn cần thực thi mã cục bộ với quyền người dùng thường
- Nếu web RCE rơi vào tài khoản dịch vụ không đặc quyền, hoặc kết hợp với foothold SSH hay PR độc hại trên runner CI, thì có thể dẫn tới root
- Bản vá đảo ngược tối ưu hóa in-place của
algif_aead, tách req->src và req->dst trở lại thành các scatterlist riêng biệt
- Page cache page chỉ còn nằm ở nguồn chỉ đọc, còn đích có thể ghi của tác vụ mã hóa chỉ còn là user buffer
Lịch công bố và tài liệu tiếp theo
- 2026-03-23 được báo cáo cho nhóm bảo mật Linux kernel
- 2026-03-24 đã có xác nhận ban đầu
- 2026-03-25 bản vá được đề xuất và review
- 2026-04-01 bản vá được commit vào mainline
- 2026-04-22 được gán CVE-2026-31431
- 2026-04-29 được công bố tại https://copy.fail/
- Phân tích kỹ thuật trên blog Xint
- Bao gồm root cause, sơ đồ scatterlist, dòng thời gian 2011→2015→2017, và walkthrough exploit
- Phần 2 nói về thoát container trong Kubernetes dự kiến sẽ được công bố sau
Thông tin liên quan đến Xint Code
- Lỗ hổng được tìm ra theo cách AI-assisted; điểm khởi đầu là nghiên cứu của con người rằng
splice() chuyển page cache page vào crypto subsystem, và nguồn gốc page trong scatterlist có thể là một lớp lỗi còn ít được khám phá
- Sau đó Xint Code đã mở rộng việc audit toàn bộ subsystem
crypto/ của Linux ở quy mô khoảng 1 giờ, và mục nghiêm trọng nhất trong kết quả chính là Copy Fail
- Xint Code
- Bài write-up trên blog Xint
- Các bug rủi ro cao khác cũng được phát hiện trong cùng đợt quét và hiện vẫn đang trong quá trình coordinated disclosure
1 bình luận
Ý kiến trên Hacker News
Với góc nhìn của người làm việc với mã crypto của kernel Linux, các vụ khai thác AF_ALG bùng lên định kỳ thực sự rất khó chịu
AF_ALG đã được đưa vào kernel từ lâu mà không được rà soát đầy đủ, cấu trúc lại quá phức tạp, đồng thời mở ra một bề mặt tấn công khổng lồ cho các chương trình userspace không đặc quyền
Hơn nữa nó gần như không cần thiết. userspace vốn đã có sẵn mã mật mã riêng, còn mã crypto của kernel ban đầu là để phục vụ các trường hợp dùng nội bộ trong kernel như dm-crypt
authencesn trong vụ khai thác lần này thực chất cũng chỉ là chi tiết triển khai nội bộ của IPsec, nên việc phơi bày nó thành API mã hóa/giải mã userspace dùng chung ngay từ đầu đã là sai lầm
Nếu bạn quản lý cấu hình kernel Linux, tôi rất khuyến nghị tắt toàn bộ các tùy chọn CONFIG_CRYPTO_USER_API_*
Chỉ cần làm vậy thôi thì không chỉ lỗi lần này mà còn phần lớn lỗi AF_ALG trong quá khứ và tương lai đã không thể bị khai thác
Nếu có chương trình userspace nào bị hỏng thì đúng hơn là nên hỗ trợ chuyển chúng sang mã crypto userspace, và thực tế cũng đã có trường hợp chuyển như vậy rồi
Ngay từ đầu AF_ALG vốn cũng chẳng có mấy ứng dụng ngoài phục vụ khai thác
Trước đây kiểu API userspace như vậy có thể còn tạm chấp nhận được, nhưng trong thời đại có syzbot và phát hiện lỗi có hỗ trợ bởi LLM thì giờ khó mà trụ nổi nữa
Các lập luận được đưa ra gồm: cho phép userspace dùng được bộ tăng tốc phần cứng chỉ truy cập được ở chế độ kernel, có thể chuyển khóa vào kernel thay vì giữ lâu trong bộ nhớ ứng dụng, và trong môi trường thiếu RAM như embedded thì có thể giảm footprint so với thư viện crypto userspace
Tôi không chắc như vậy đã là biện minh đủ mạnh hay chưa, nhưng ít nhất thì đúng là có lý do tồn tại
Linus vốn nổi tiếng là khá kén chọn về việc đưa gì vào kernel, nên bối cảnh đằng sau API này hẳn sẽ là một câu chuyện thú vị
Nó cho phép xử lý băm và mã hóa bằng các lệnh gọi
read(2)/write(2)thông thườngCó vẻ đã có chút lộn xộn trong quá trình công bố
Các vendor dường như không xem lỗ hổng này là đặc biệt nghiêm trọng, nên nhiều bản phân phối vẫn đang ở trạng thái chưa vá
https://access.redhat.com/security/cve/cve-2026-31431 ghi là "Moderate severity", "Fix deferred", và các trang theo dõi của Debian, Ubuntu, SUSE cũng trông tương tự
Nhưng upstream đã không truyền đạt rõ ràng rằng đây là một lỗ hổng, và Linus cùng Greg vốn cũng không quá coi trọng khái niệm phân loại như vậy trong kernel
Dù vậy, vì có thể leo thang đặc quyền lên root từ local nên nhìn chung vẫn nên được xem là ưu tiên cao
https://ubuntu.com/security/cves/about#priority
Hơi đáng tiếc là bài gốc không ghi ngay phiên bản kernel nào bị ảnh hưởng và phiên bản nào đã vá
Đặc biệt vì đây là module builtin nên cũng không thể dễ dàng gỡ bằng
rmmodTrong lúc tìm xem kernel 6.19.14 của Fedora 44 có dễ tổn thương không, tôi đã tìm thấy bài trên mailing list linux-cve-announce https://lore.kernel.org/linux-cve-announce/2026042214-CVE-2026-31431-3d65@gregkh/T/#u
Ở đó ghi rằng lỗi đã được sửa bằng commit tương ứng trong 6.18.22, 6.19.12, 7.0, nên khá hữu ích để tham khảo
Nếu muốn kiểm tra xem biện pháp giảm thiểu được khuyến nghị là chặn module kernel
algif_aeadbằng cấu hình modprobe đã được áp dụng hay chưa, thì không cần phải chạy nguyên một đoạn shell bị làm rốiChỉ với vài dòng Python như dưới đây là có thể kiểm tra dễ đọc xem module có thực sự được nạp hay không
python3 -c 'import socket; s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0); s.bind(("aead","authencesn(hmac(sha256),cbc(aes))")); print("algif_aead probably successfully loaded, mitigation not effective; remove again with: rmmod algif_aead")'Nếu biện pháp giảm thiểu đã áp dụng đúng thì
modprobe algif_aeadcũng phải thất bại với lỗiChắc là không ai chạy AI agent hoàn toàn tự trị trên một hệ điều hành bị ảnh hưởng với quyền người dùng thường đâu nhỉ
Nếu kết hợp với prompt injection zero-day thì có thể thành thảm họa thật sự
curl | shthành chuẩn mặc định của ngànhLPE nghĩa là local privilege escalation
Mảng bảo mật có quá nhiều chữ viết tắt, và dù có thể đoán theo ngữ cảnh nhưng ban đầu vẫn nên viết đầy đủ ra
Tuy vậy, nếu bài viết hướng đến độc giả rộng hơn thì tôi đồng ý là nên định nghĩa rõ ràng
Hơn nữa, cả bài này trông cũng giống nội dung do AI tạo ra
Cái này hơi buồn cười
Trang đó ghi là chạy trên RHEL 14.3, nhưng phiên bản như vậy không hề tồn tại
RHEL hiện đang ở 10.x, nên tôi còn tưởng họ đi TARDIS nữa chứ
Đôi khi nó hiện như
gcc (GCC) 14.3.1 20250617 (Red Hat 14.3.1-2), và trong các ví dụ bên dưới cũng thấy dấu vết tương tựhttps://github.com/anthropics/claude-code/issues/40741
https://docs.oracle.com/en/database/oracle/tuxedo/22/otxig/software-requirements-red-hat-enterprise-linux-10-64-bit.html
6.12.0-124.45.1.el10_1, mà cái đó rõ ràng là kernel của RHEL 10Những lỗi gõ kiểu này ngược lại lại rất giống do người tạo ra
Các chuỗi số dài copy-paste thì chính xác, còn mấy con số đơn giản lại gõ tay rồi sai
Đã có giai đoạn thu thập thông tin khá gấp để giải thích vấn đề này, và đúng vậy, cũng có yếu tố marketing
Vì thế có lẫn vào vài lỗi nhỏ, và tôi xem việc bạn chỉ ra là rất đáng cảm ơn
https://access.redhat.com/articles/red-hat-enterprise-linux-release-dates
Đến lúc thấy cả dòng "Talk to our security experts" ở cuối trang, tôi còn thấy như thể chuyên gia bảo mật đó có khi tên là Claude
Trên RHEL 9/10, algif_aead không phải module mà là builtin nên không thể unload
Vì vậy tôi đã tìm một cách thay thế là chặn AF_ALG bằng systemd, nhưng cách này cần drop-in cho từng dịch vụ bị phơi bày
Cũng có sẵn playbook Ansible xử lý những chỗ quan trọng như
sshdvàuser@https://gist.github.com/m3nu/c19269ef4fd6fa53b03eb388f77464da
initcall_blacklist=algif_aead_initlàm tham số boot kernel rồi khởi động lạiLàm vậy thì khai thác không còn hoạt động nữa
Tôi lo về các đường thực thi khác như
cronjob,slurmjob, và sẽ tốt hơn nếu có cách để mọi tiến trình đều kế thừa thiết lập này ở cấp systemd thay vì phải thêm cho từng dịch vụ riêng lẻCó vẻ khai thác này hoạt động bằng cách thay thế binary SUID để khiến nó chạy với PID 0
Nhưng trong khi trang đó lại tuyên bố có thể thoát khỏi Kubernetes / container clusters và CI runners & build farms, thì tôi không thấy phần giải thích nào thực sự chứng minh việc thoát container hay đặc biệt là thoát user namespace
Tôi đã thử trong rootless Podman và đúng như dự đoán là không thể thoát container
Ngoài ra họ còn nói có thể "biến mọi bản phân phối Linux phát hành từ 2017 thành root", nhưng thực tế chỉ thử trên bốn bản và trên Alpine thì không chạy được
Họ đã nhá hàng
"Next: "From Pod to Host," how Copy Fail escapes every major cloud Kubernetes platform."https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=72548b093ee3
Tuy vậy, khả năng khai thác thực tế sẽ khác nhau tùy đó là bản phát hành major mới hay kernel bảo trì của nhánh cũ
Dù vậy, khi tôi trực tiếp chạy PoC trên một instance 24.04 thì lỗ hổng có vẻ là thật, và đủ lớn để đáng lo
Chỉ là số lượng bản phân phối bị ảnh hưởng có vẻ ít hơn nhiều so với tuyên bố, và còn khá xa mới đến mức mọi bản phân phối từ sau 2017
Ví dụ, nếu tôi hiểu đúng thì Ubuntu ngay cả 16.04 EOL cũng bị ảnh hưởng chút ít, còn tác động chính thực tế có vẻ nằm ở các kernel vendor mới được phân phối gần đây như
linux-gcp,linux-oracle-6.7, tức nhánh 6.17Dù vậy sẽ cần thêm bước khác, và Alpine có thể cũng dính lỗ hổng gốc nhưng chỉ là script cần chỉnh lại mà thôi
Suy cho cùng đây không phải exploit đa dụng hoàn chỉnh mà là PoC
Bản thân trang này có vẻ hơi vibecoded và mang mùi quảng cáo, nhưng lỗ hổng thì là thật và mức độ nguy hiểm cũng có vẻ cao
Giờ thì cũng hiểu vì sao hôm nay có một bản cập nhật bảo mật lớn, nên tôi sẽ tăng ưu tiên cập nhật lên
Họ vừa đóng góp có ý nghĩa cho hệ sinh thái OSS bằng cách tìm ra lỗi thật và vá nó, đồng thời cũng bán công cụ bảo mật của mình
Chỉ là giờ còn ai tự tay làm từng trang web nữa đâu, nhất là nếu còn là kernel developer thì lại càng hợp lý hơn