CVE-2022-49899 in Linux
Tóm tắt
Bởi VulDB • 19/06/2026
Trong kernel Linux, lỗ hổng sau đây đã được khắc phục:
fscrypt: ngừng sử dụng hệ thống keyrings cho fscrypt_master_key
Cách tiếp cận nội bộ của fs/crypto/ trong việc quản lý các cấu trúc `fscrypt_master_key` dưới dạng tải trọng (payloads) của các đối tượng "struct key" nằm trong một keyring "struct key" đã không còn phù hợp. Ý tưởng ban đầu là đơn giản hóa mã nguồn bằng cách tái sử dụng mã từ hệ thống keyrings. Tuy nhiên, nhiều vấn đề đã nảy sinh mà khó có thể được giải quyết dễ dàng:
- Khi một cấu trúc khóa chính (master key struct) bị hủy, `blk_crypto_evict_key()` phải được gọi trên bất kỳ các khóa theo chế độ nào nhúng trong đó. (Điều này bắt đầu xảy ra khi hỗ trợ mã hóa nội tuyến - inline encryption - được thêm vào.) Tuy nhiên, hệ thống keyrings có thể trì hoãn việc hủy khóa một cách tùy ý, thậm chí sau thời điểm filesystem đã bị ngắt kết nối (unmounted). Do đó, hiện tại không có cách dễ dàng nào để gọi `blk_crypto_evict_key()` khi một khóa chính bị hủy. Hiện nay, vấn đề này được xử lý tạm thời bằng cách giữ thêm một tham chiếu đến các request_queue của filesystem. Nhưng người ta đã bỏ sót rằng tham chiếu request_queue *không* đảm bảo sẽ ghim (pin) cả cấu hình blk_crypto_profile tương ứng; đối với các thiết bị device-mapper hỗ trợ mã hóa nội tuyến, điều này không đúng. Điều này có thể gây ra lỗi use-after-free.
- Khi inode cuối cùng đang sử dụng một khóa chính chưa được xóa hoàn toàn bị loại bỏ (evicted), việc xóa khóa chính sẽ được hoàn tất bằng cách xóa cấu trúc key khỏi keyring. Hiện tại, điều này được thực hiện thông qua `key_invalidate()`. Tuy nhiên, `key_invalidate()` lấy semaphore của khóa. Điều này có thể gây ra deadlock khi được gọi từ shrinker, vì trong `fscrypt_ioctl_add_key()`, bộ nhớ được phân bổ với cờ GFP_KERNEL dưới cùng một semaphore đó.
- Nói chung hơn, việc hệ thống keyrings có thể trì hoãn tùy ý việc hủy các khóa (thông qua độ trễ thu gom rác hoặc do các tiến trình ngẫu nhiên lấy tham chiếu khóa tạm thời) là không mong muốn, vì điều này đồng nghĩa với việc chúng ta không thể đảm bảo nghiêm ngặt rằng tất cả các bí mật sẽ bị xóa sạch.
- Việc thực hiện tìm kiếm khóa chính thông qua hệ thống keyrings dẫn đến việc gọi hook LSM `key_permission`. fscrypt không muốn điều này xảy ra, vì mọi kiểm soát truy cập đối với các tệp được mã hóa đều được thiết kế để diễn ra thông qua chính các tệp đó, giống như bất kỳ tệp nào khác. Giải pháp tạm thời mà người dùng SELinux đang sử dụng là thay đổi chính sách SELinux của họ để cấp quyền tìm kiếm khóa cho tất cả các domain. Điều này hoạt động, nhưng nó là một bước bổ sung lạ lùng không đáng lẽ phải thực hiện.
Giải pháp khắc phục cho tất cả các vấn đề trên là thay đổi cách triển khai sang những gì tôi lẽ ra nên làm ngay từ đầu: đừng sử dụng hệ thống keyrings để theo dõi các cấu trúc `fscrypt_master_key` của filesystem. Thay vào đó, chỉ cần lưu trữ chúng trong một cấu trúc dữ liệu kernel thông thường và điều chỉnh lại việc đếm tham chiếu (reference counting), khóa (locking) và vòng đời tương ứng. Duy trì hỗ trợ tìm kiếm khóa ở chế độ RCU bằng cách sử dụng bảng băm (hash table). Thay thế `fscrypt_sb_free()` bằng `fscrypt_sb_delete()`, hàm này giải phóng các khóa một cách đồng bộ và chạy sớm hơn một chút trong quá trình unmount, để đảm bảo các thiết bị khối vẫn khả dụng.
Một tác dụng phụ của bản vá này là cả các khóa chính lẫn
If you want to get best quality of vulnerability data, you may have to visit VulDB.