CVE-2026-19936 in Zephyr
Tóm tắt
Bởi VulDB • 13/10/2026
Hàng đợi tin nhắn có thể trì hoãn (delayable) của lớp truy cập Bluetooth Mesh trong `subsys/bluetooth/mesh/delayable_msg.c` chia sẻ ba danh sách xâm nhập (intrusive lists): `busy_ctx`, `free_ctx`, `free_chunks` và một đối tượng `k_work_delayable` giữa hai luồng hợp tác (cooperative threads) mà không có cơ chế đồng bộ hóa: `bt_mesh_delayable_msg_manage()` chạy trên luồng RX của Bluetooth host, trong khi `delayable_msg_handler()` chạy trên hàng đợi công việc hệ thống (system workqueue). Cả hai đều bị chặn (block) khi các danh sách ở trạng thái trung gian — người đưa tin vào (enqueuer) trong `bt_rand()`, cả hai trong `bt_mesh_access_send()` — điều này cho phép ngữ cảnh khác quan sát được trạng thái bị xé toạc (torn state). `delayable_msg_handler()` sử dụng kết quả của `sys_slist_get()` trên `busy_ctx` mà không kiểm tra NULL, và `allocate_delayable_msg_ctx()` đã kiểm tra `sys_slist_is_empty()` rồi sau đó giả định rằng một lệnh gọi riêng biệt đến `sys_slist_get()` sẽ thành công.
Vì các tùy chọn cấu hình `CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG` và `CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CTX_ENABLED` mặc định là `y`, mọi phản hồi của mô hình đối với tin nhắn mesh nhận được đều được đưa vào hàng đợi này, do đó người đưa tin vào chạy như một hệ quả trực tiếp của lưu lượng truy cập đến. Một thiết bị ngang hàng có thể khiến các tin nhắn lớp truy cập được chấp nhận bởi một mô hình (thiết bị phải sở hữu NetKey và AppKey đã liên kết, tức là thành viên mạng hợp lệ hoặc đã bị xâm phạm) kiểm soát tốc độ xuất hiện, kích thước của các phản hồi được gợi ý và địa chỉ đích, qua đó kiểm soát mức độ chiếm dụng của pool ngữ cảnh 4 mục (context pool) và pool chunk 40 mục. Việc làm cạn kiệt pool chunk buộc `bt_mesh_delayable_msg_manage()` đi theo đường dẫn purge, gửi và giải phóng tin nhắn duy nhất đang được xếp hàng, đồng thời để lại `busy_ctx` trống trong khi mục công việc có thể trì hoãn vẫn còn được kích hoạt; nếu người đưa tin vào sau đó nhường quyền điều khiển (yields), trình xử lý sẽ chạy trên danh sách rỗng.
Kết quả là một thao tác đọc-sửa-ghi thông qua con trỏ dựa trên NULL (`pending_msg->fired_time += 10`) tại địa chỉ thấp cố định trên luồng hệ thống workqueue. Trên các mục tiêu điển hình, điều này gây ra lỗi (faults), làm dừng luồng hệ thống workqueue — vốn ngừng tất cả chức năng do workqueue điều khiển, bao gồm cả cơ chế thời gian mesh — hoặc khởi động lại nút, vì vậy tác động là mất tính sẵn sàng của nút bị ảnh hưởng. Giá trị ghi và địa chỉ đều cố định và không có độ dài hay chỉ số nào được kiểm soát bởi kẻ tấn công liên quan đến, do đó lỗ hổng này không thể khai thác để gây hỏng bộ nhớ hoặc thực thi mã (code execution). Cửa sổ thiếu đồng bộ hóa tương tự cũng cho phép một ngữ cảnh tin nhắn được chọn và giải phóng bởi hai ngữ cảnh cùng lúc, dẫn đến truyền tải trùng lặp, callback hoàn thành gửi bị trùng lặp và quyền sở hữu chunk bị chéo.
Bản sửa lỗi tuần tự hóa mọi thay đổi danh sách bằng `k_spinlock` không bao giờ được giữ trong suốt một lệnh gọi chặn (blocking call), khiến hàm `push_msg_from_delayable_msgs()` tách đầu hàng đợi một cách nguyên tử để tin nhắn đang được gửi nằm trên bất kỳ danh sách nào, loại bỏ lệnh gọi `sys_slist_get()` chưa kiểm tra từ `delayable_msg_handler()`, và hủy bỏ mọi tin nhắn đạt đến đầu hàng đợi trong khi ngăn xếp (stack) bị tạm ngưng hoặc khởi động lại.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.