A vulnerability has been identified and resolved in the Linux kernel involving the io_worker->flags structure. This structure is accessed through various data paths, leading to concurrency issues. KERNEL Thread SANitizer (KCSAN) reveals data races occurring in the io_worker_handle_work and io_wq_activate_free_worker functions. To address this vulnerability (CVE-2024-39508), it is recommended to use set_bit() and test_bit() on worker->flags within io_uring/io-wq.

Original References

The original patch addressing this vulnerability can be found at the Linux Kernel Mailing List (LKML) archives [1]. Additionally, the Linux kernel source code repository provides further details on the vulnerability and the solution implemented [2].

Exploit Details

As demonstrated in the code snipplet below, data races occur due to concurrent access to io_worker->flags:

BUG: KCSAN: data-race in io_worker_handle_work / io_wq_activate_free_worker
 write to xffff8885c4246404 of 4 bytes by task 49071 on cpu 28:
 io_worker_handle_work (io_uring/io-wq.c:434 io_uring/io-wq.c:569)
 io_wq_worker (io_uring/io-wq.c:?)
<snip>

 read to xffff8885c4246404 of 4 bytes by task 49024 on cpu 5:
 io_wq_activate_free_worker (io_uring/io-wq.c:? io_uring/io-wq.c:285)
 io_wq_enqueue (io_uring/io-wq.c:947)
 io_queue_iowq (io_uring/io_uring.c:524)
 io_req_task_submit (io_uring/io_uring.c:1511)
 io_handle_tw_list (io_uring/io_uring.c:1198)
<snip>

Line numbers are provided against commit 18daea77cca6 ("Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm").

To mitigate this issue, refactoring the code to use atomic operations such as set_bit(), test_bit(), and clear_bit() should be done instead of basic "and" and "or" operations. This ensures thread-safe manipulation of worker flags and resolves the vulnerability.

Moreover, the create_index variable should be moved to avoid holes in the structure.

Conclusion

The Linux kernel was found to be vulnerable due to data races in the io_uring/io-wq subsystem. The vulnerability, identified as CVE-2024-39508, has now been resolved by using atomic operations set_bit() and test_bit() on worker->flags. Further information and links to the original references have been provided to give more context about the specific vulnerability and fix.

[1] https://lore.kernel.org/lkml/
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/

Timeline

Published on: 07/12/2024 13:15:13 UTC
Last modified on: 12/19/2024 09:07:32 UTC