CVE-2022-49767

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
01/05/2025
Last modified:
02/05/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> 9p/trans_fd: always use O_NONBLOCK read/write<br /> <br /> syzbot is reporting hung task at p9_fd_close() [1], for p9_mux_poll_stop()<br /> from p9_conn_destroy() from p9_fd_close() is failing to interrupt already<br /> started kernel_read() from p9_fd_read() from p9_read_work() and/or<br /> kernel_write() from p9_fd_write() from p9_write_work() requests.<br /> <br /> Since p9_socket_open() sets O_NONBLOCK flag, p9_mux_poll_stop() does not<br /> need to interrupt kernel_read()/kernel_write(). However, since p9_fd_open()<br /> does not set O_NONBLOCK flag, but pipe blocks unless signal is pending,<br /> p9_mux_poll_stop() needs to interrupt kernel_read()/kernel_write() when<br /> the file descriptor refers to a pipe. In other words, pipe file descriptor<br /> needs to be handled as if socket file descriptor.<br /> <br /> We somehow need to interrupt kernel_read()/kernel_write() on pipes.<br /> <br /> A minimal change, which this patch is doing, is to set O_NONBLOCK flag<br /> from p9_fd_open(), for O_NONBLOCK flag does not affect reading/writing<br /> of regular files. But this approach changes O_NONBLOCK flag on userspace-<br /> supplied file descriptors (which might break userspace programs), and<br /> O_NONBLOCK flag could be changed by userspace. It would be possible to set<br /> O_NONBLOCK flag every time p9_fd_read()/p9_fd_write() is invoked, but still<br /> remains small race window for clearing O_NONBLOCK flag.<br /> <br /> If we don&amp;#39;t want to manipulate O_NONBLOCK flag, we might be able to<br /> surround kernel_read()/kernel_write() with set_thread_flag(TIF_SIGPENDING)<br /> and recalc_sigpending(). Since p9_read_work()/p9_write_work() works are<br /> processed by kernel threads which process global system_wq workqueue,<br /> signals could not be delivered from remote threads when p9_mux_poll_stop()<br /> from p9_conn_destroy() from p9_fd_close() is called. Therefore, calling<br /> set_thread_flag(TIF_SIGPENDING)/recalc_sigpending() every time would be<br /> needed if we count on signals for making kernel_read()/kernel_write()<br /> non-blocking.<br /> <br /> [Dominique: add comment at Christian&amp;#39;s suggestion]

Impact