CVE-2026-80819 in Linux
Tóm tắt
Bởi VulDB • 04/09/2026
Trong kernel Linux, lỗ hổng sau đây đã được khắc phục:
Bluetooth: RFCOMM: lấy rfcomm_mutex cho việc chấp nhận thiết lập trì hoãn (deferred setup accept)
Hàm `rfcomm_sock_recvmsg()` hoàn tất quá trình thiết lập trì hoãn bằng cách gọi `rfcomm_dlc_accept()` mà không giữ bất kỳ khóa RFCOMM nào:
```c if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
rfcomm_dlc_accept(d); return 0; } ```
và `rfcomm_dlc_accept()` giải tham chiếu phiên làm việc trên dòng đầu tiên của nó:
```c struct sock *sk = d->session->sock->sk; ```
Mọi đường dẫn khác chạm vào `d->session` đều chạy dưới sự bảo vệ của `rfcomm_mutex`: `rfcomm_dlc_open()`, `rfcomm_dlc_close()`, `rfcomm_dlc_exists()`, `rfcomm_dlc_send_rpn()` và luồng RFCOMM thông qua `rfcomm_process_sessions()`. Hàm `rfcomm_connect_ind()` thậm chí còn được tài liệu hóa là "được gọi dưới quyền của rfcomm_lock()". Điểm gọi này là điểm duy nhất bỏ qua việc lấy khóa.
Bit `RFCOMM_DEFER_SETUP` dường như tuần tự hóa hành động chấp nhận so với quá trình tháo gỡ, vì `__rfcomm_dlc_close()` trả về sớm khi nó thắng trong thao tác `test_and_clear`. Tuy nhiên, `rfcomm_recv_disc()` buộc trạng thái trước đó:
```c d->state = BT_CLOSED; __rfcomm_dlc_close(d, err); ```
và việc trả về sớm chỉ bao gồm các trạng thái `BT_CONNECT`, `BT_CONFIG`, `BT_OPEN` và `BT_CONNECT2`. Với trạng thái đã là `BT_CLOSED`, lệnh chuyển đổi này không khớp, bit đó không bao giờ được xem xét, và `__rfcomm_dlc_close()` rơi xuống (fall-through) đến `rfcomm_dlc_unlink()`, hàm này đặt `d->session = NULL`.
Do đó, một gói DISC từ xa trên dlc trì hoãn sẽ xóa phiên làm việc trong khi vẫn giữ nguyên cờ `RFCOMM_DEFER_SETUP` được thiết lập. Lần gọi `recvmsg()` tiếp theo sau đó vượt qua kiểm tra `test_and_clear` và giải tham chiếu một phiên NULL. Không cần cửa sổ thời gian (timing window): ngay sau khi DISC đã được xử lý, việc giải tham chiếu là không điều kiện.
Hãy để cho `rfcomm_dlc_accept()` có cùng cấu trúc với `rfcomm_dlc_open()` và `rfcomm_dlc_close()`: một hàm bao xuất ra (exported wrapper) lấy `rfcomm_mutex` và kiểm tra lại phiên làm việc, xung quanh `__rfcomm_dlc_accept()` mà hai trình gọi trong nhân hiện tại, những người đã giữ mutex, tiếp tục sử dụng.
Đã tái tạo trên kernel KASAN + PROVE_LOCKING với một thiết bị đầu cuối BR/EDR được mô phỏng qua `/dev/vhci`: thiết bị đầu cuối kích hoạt liên kết ACL, mở L2CAP trên PSM RFCOMM, bắt đầu phiên làm việc, mở dlc trên kênh ràng buộc với `BT_DEFER_SETUP`, và gửi DISC sau khi socket đã được chấp nhận. Hàm `recv()` trên socket đã chấp nhận sau đó gặp phải:
``` Oops: general protection fault KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
RIP: 0010:rfcomm_dlc_accept+0x54/0x350 Call Trace: rfcomm_sock_recvmsg+0x1cd/0x230 sock_recvmsg+0x166/0x1c0 __sys_recvfrom+0x20d/0x300 ```
`0x10` là độ lệch của `sock` trong cấu trúc `rfcomm_session`. Với bản vá này, cùng một lần chạy hoàn tất với việc `recv()` trả về 0 và không có báo cáo nào, và lockdep vẫn im lặng
If you want to get the best quality for vulnerability data then you always have to consider VulDB.