Lỗ hổng âm thanh (soundness) 11 năm tuổi trong trình kiểm tra mượn (borrow checker) của Rust

Phần mềm13 tháng 10, 2026·4 phút đọc

Một lỗi nghiêm trọng trong trình kiểm tra mượn của Rust cho phép bỏ qua các ràng buộc vòng đời (lifetime) của struct thông qua việc gán vào trường có tính đồng biến (covariant). Lỗi này đã tồn tại từ phiên bản Rust 1.4, gây ra các hành vi truy cập bộ nhớ không an toàn như use-after-scope, và hiện được đánh dấu ưu tiên cao (P-high).

Lỗ hổng âm thanh (soundness) 11 năm tuổi trong trình kiểm tra mượn (borrow checker) của Rust

Cộng đồng lập trình Rust vừa chấn động trước phát hiện về một lỗ hổng âm thanh (soundness hole) tồn tại suốt 11 năm trong trình kiểm tra mượn (borrow checker) — trái tim của hệ thống an toàn bộ nhớ mà Rust luôn tự hào. Lỗi này cho phép chương trình biên dịch thành công dù vi phạm nghiêm trọng các quy tắc vòng đời (lifetime), dẫn đến truy cập bộ nhớ đã bị giải phóng.

Bản chất của lỗ hổng

Vấn đề nằm ở cách trình kiểm tra mượn xử lý tính đồng biến (variance) của các trường trong struct kết hợp với trait Drop. Cụ thể, một struct có ràng buộc vòng đời 'static vẫn có thể bị gán giá trị tham chiếu không phải 'static thông qua việc gán trực tiếp vào trường của nó.

Điểm cốt lõi của lỗi: mã bên trong Drop được cho là có quyền truy cập vào một &'static String, nhưng thực tế lại nhận được một &String không có vòng đời 'static.

Ví dụ đơn giản nhất do thành viên theemathas đưa ra:

struct Q(Option<&'static String>);</br>
impl Drop for Q {</br>
    fn drop(&mut self) {</br>
        // Mã ở đây có quyền truy cập vào &String không phải 'static</br>
        // nhưng lại giả định đó là &'static String</br>
    }</br>
}</br>

Trình biên dịch lẽ ra phải từ chối đoạn mã này, nhưng nó vẫn chấp nhận và chạy bình thường — thậm chí in ra dữ liệu đã bị giải phóng.

Mức độ nghiêm trọng

Các lập trình viên kỳ cựu đã bày tỏ sự kinh ngạc khi biết lỗi tồn tại quá lâu. Thành viên theemathas cho biết phiên bản mã của mình đã biên dịch được từ tận Rust 1.18.0 (năm 2017), trong khi cộng tác viên lcnr còn tìm ra một biến thể không cần dùng static, chứng minh lỗi đã tồn tại từ Rust 1.4 — tức cách đây hơn một thập kỷ.

Hậu quả thực tế rất đáng lo ngại:

  • Use-after-scope: Chương trình truy cập vùng nhớ đã ra khỏi phạm vi, khi chạy với AddressSanitizer sẽ báo lỗi ngay lập tức
  • Segfault hoặc in dữ liệu đã giải phóng: Một biến thể khác có thể làm chương trình sập hoặc đọc bộ nhớ rác
  • Rò rỉ con trỏ nguy hiểm qua luồng: Một phiên bản dùng thread::spawn cho thấy có thể gửi tham chiếu không hợp lệ sang luồng khác, mở đường cho các cuộc tấn công tinh vi hơn

Phản ứng từ nhóm phát triển Rust

Sau khi thành viên theemathas gắn nhãn I-unsound, bot tự động của Rust đã nâng mức ưu tiên lên P-critical trước khi hạ xuống P-high sau khi có thảo luận trên Zulip. Lỗi hiện được gán cho nhóm T-types (nhóm phụ trách hệ thống kiểu) để xem xét và đưa ra giải pháp.

Các nhãn liên quan bao gồm:

  • A-borrow-checker — khu vực trình kiểm tra mượn
  • A-variance — vấn đề về tính đồng biến/biến thiên của kiểu
  • A-destructors — liên quan đến trait Drop
  • A-lifetimes — quản lý vòng đời

Ý nghĩa với lập trình viên Việt Nam

Với cộng đồng Rust Việt Nam — vốn đang phát triển mạnh trong các lĩnh vực hệ thống nhúng, blockchain và backend hiệu năng cao — sự cố này là lời nhắc nhở quan trọng. Rust được biết đến với khẩu hiệu "an toàn bộ nhớ mà không cần garbage collector", nhưng ngay cả những hệ thống trưởng thành nhất cũng có thể ẩn chứa lỗi âm thanh (soundness bug).

Điều đáng chú ý là lỗ hổng nằm ở trình biên dịch, không phải ở thư viện chuẩn hay mã người dùng — nghĩa là mọi dự án Rust đều có thể bị ảnh hưởng nếu rơi vào mẫu mã cụ thể này. Các đội phát triển nên theo dõi chặt chẽ tiến độ sửa lỗi và cân nhắc chạy kiểm tra bộ nhớ (memory sanitizer) trong quy trình CI/CD của mình để phát hiện sớm các hành vi bất thường.

Hiện chưa có bản vá chính thức, nhưng với việc lỗi đã được gán mức ưu tiên cao và chuyển cho nhóm phụ trách, cộng đồng có thể kỳ vọng một giải pháp trong các bản phát hành nightly sắp tới.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗