CVE-2026-98644 in Linux
Tóm tắt
Bởi VulDB • 18/10/2026
Trong kernel Linux, lỗ hổng sau đây đã được khắc phục:
bpf: Tránh tình trạng soft lockup trong __htab_map_lookup_and_delete_batch()
Hàm __htab_map_lookup_and_delete_batch() không có điểm gọi hàm lên lịch (rescheduling point). Số lượng bản ghi trong batch giới hạn số mục dữ liệu được sao chép ra, chứ không phải số bucket đã duyệt qua, do đó một lệnh gọi BPF_MAP_LOOKUP_BATCH duy nhất có thể quét toàn bộ map từ đầu đến cuối. Đường dẫn nhanh cho các bucket rỗng còn tệ hơn: nó giữ nguyên trạng thái bên trong một khối rcu_read_lock() / bpf_disable_instrumentation() liên tục đối với bất kỳ chuỗi các bucket rỗng nào.
Vấn đề này gây ra sự cố trên các map nhỏ, nhưng trở nên nghiêm trọng khi mở rộng quy mô. Trên máy chủ arm64 144 CPU chạy kernel CONFIG_PREEMPT_NONE, việc gọi định kỳ BPF_MAP_LOOKUP_BATCH lên một hash map LRU có 16.777.216 bucket đã giữ một CPU trong thao tác batch hơn 77 giây và kích hoạt watchdog soft lockup.
Commit 75134f16e7dd ("bpf: Add schedule points in batch ops") đã khắc phục vấn đề tương tự đối với các thao tác batch chung (generic), nhưng chưa áp dụng cho đường dẫn htab-native, vốn được mọi biến thể hash map dựa trên htab sử dụng cho các thao tác lookup[_and_delete] theo batch.
Hãy hoàn thiện bản sửa lỗi này tại đây. Rời khỏi khối quan trọng sau 64 bucket rỗng liên tiếp, gọi cond_resched_tasks_rcu_qs(), và tiếp tục từ con trỏ bucket đã lưu. Tại thời điểm đó không có khóa nào được giữ lại, và việc tiếp tục từ con trỏ là hành vi hiện có của hàm đối với các bucket không rỗng. Thêm cùng một lệnh gọi vào vòng lặp per-bucket sau copy_to_user(), nơi mọi khóa đều đã được thả. cond_resched_rcu() không đủ ở đây: việc ngủ khi bpf_prog_active đang tăng cao khiến các chương trình tracing trên CPU đó bỏ qua silently (im lặng) các lần thực thi của chúng.
Plain cond_resched() cũng không đủ. Nó là một lệnh gọi vô hiệu hóa (no-op) trong chế độ PREEMPT và PREEMPT_LAZY, hai mô hình mà arm64 và x86 đã cung cấp kể từ commit 7dadeaa6e851 ("sched: Further restrict the preemption modes"). Ngoài ra, nó không bao giờ là trạng thái im lặng (quiescent state) của Tasks RCU trong bất kỳ mô hình nào: việc lên lịch lại được tính là một sự ngắt tiền chế. Tác vụ đang duyệt giữ nguyên vị trí và làm tắc nghẽn mọi caller synchronize_rcu_tasks(), bao gồm cả quá trình teardown ftrace và BPF trampoline, cho đến khi syscall trả về [1].
cond_resched_tasks_rcu_qs() là công cụ thông thường để giải quyết vấn đề đó [2]. Nó báo cáo trạng thái im lặng tại mỗi lần nhường quyền (yield) và vẫn thực hiện lên lịch lại như cond_resched() làm trên các kernel PREEMPT_NONE và PREEMPT_VOLUNTARY.
If you want to get best quality of vulnerability data, you may have to visit VulDB.