| From bippy-1.1.0 Mon Sep 17 00:00:00 2001 |
| From: Greg Kroah-Hartman <gregkh@kernel.org> |
| To: <linux-cve-announce@vger.kernel.org> |
| Reply-to: <cve@kernel.org>, <linux-kernel@vger.kernel.org> |
| Subject: CVE-2022-49767: 9p/trans_fd: always use O_NONBLOCK read/write |
| |
| Description |
| =========== |
| |
| In the Linux kernel, the following vulnerability has been resolved: |
| |
| 9p/trans_fd: always use O_NONBLOCK read/write |
| |
| syzbot is reporting hung task at p9_fd_close() [1], for p9_mux_poll_stop() |
| from p9_conn_destroy() from p9_fd_close() is failing to interrupt already |
| started kernel_read() from p9_fd_read() from p9_read_work() and/or |
| kernel_write() from p9_fd_write() from p9_write_work() requests. |
| |
| Since p9_socket_open() sets O_NONBLOCK flag, p9_mux_poll_stop() does not |
| need to interrupt kernel_read()/kernel_write(). However, since p9_fd_open() |
| does not set O_NONBLOCK flag, but pipe blocks unless signal is pending, |
| p9_mux_poll_stop() needs to interrupt kernel_read()/kernel_write() when |
| the file descriptor refers to a pipe. In other words, pipe file descriptor |
| needs to be handled as if socket file descriptor. |
| |
| We somehow need to interrupt kernel_read()/kernel_write() on pipes. |
| |
| A minimal change, which this patch is doing, is to set O_NONBLOCK flag |
| from p9_fd_open(), for O_NONBLOCK flag does not affect reading/writing |
| of regular files. But this approach changes O_NONBLOCK flag on userspace- |
| supplied file descriptors (which might break userspace programs), and |
| O_NONBLOCK flag could be changed by userspace. It would be possible to set |
| O_NONBLOCK flag every time p9_fd_read()/p9_fd_write() is invoked, but still |
| remains small race window for clearing O_NONBLOCK flag. |
| |
| If we don't want to manipulate O_NONBLOCK flag, we might be able to |
| surround kernel_read()/kernel_write() with set_thread_flag(TIF_SIGPENDING) |
| and recalc_sigpending(). Since p9_read_work()/p9_write_work() works are |
| processed by kernel threads which process global system_wq workqueue, |
| signals could not be delivered from remote threads when p9_mux_poll_stop() |
| from p9_conn_destroy() from p9_fd_close() is called. Therefore, calling |
| set_thread_flag(TIF_SIGPENDING)/recalc_sigpending() every time would be |
| needed if we count on signals for making kernel_read()/kernel_write() |
| non-blocking. |
| |
| [Dominique: add comment at Christian's suggestion] |
| |
| The Linux kernel CVE team has assigned CVE-2022-49767 to this issue. |
| |
| |
| Affected and fixed versions |
| =========================== |
| |
| Fixed in 4.9.334 with commit 0b5e6bd72b8171364616841603a70e4ba9837063 |
| Fixed in 4.14.300 with commit 9f8554615df668e4bf83294633ee9d232b28ce45 |
| Fixed in 4.19.267 with commit 7abf40f06a76c0dff42eada10597917e9776fbd4 |
| Fixed in 5.4.225 with commit b1ad04da7fe4515e2ce2d5f2dcab3b5b6d45614b |
| Fixed in 5.10.156 with commit a8e2fc8f7b41fa9d9ca5f624f4e4d34fce5b40a9 |
| Fixed in 5.15.80 with commit 0e07032b4b4724b8ad1003698cb81083c1818999 |
| Fixed in 6.0.10 with commit 5af16182c5639349415118e9e9aecd8355f7a08b |
| Fixed in 6.1 with commit ef575281b21e9a34dfae544a187c6aac2ae424a9 |
| |
| Please see https://www.kernel.org for a full list of currently supported |
| kernel versions by the kernel community. |
| |
| Unaffected versions might change over time as fixes are backported to |
| older supported kernel versions. The official CVE entry at |
| https://cve.org/CVERecord/?id=CVE-2022-49767 |
| will be updated if fixes are backported, please check that for the most |
| up to date information about this issue. |
| |
| |
| Affected files |
| ============== |
| |
| The file(s) affected by this issue are: |
| net/9p/trans_fd.c |
| |
| |
| Mitigation |
| ========== |
| |
| The Linux kernel CVE team recommends that you update to the latest |
| stable kernel version for this, and many other bugfixes. Individual |
| changes are never tested alone, but rather are part of a larger kernel |
| release. Cherry-picking individual commits is not recommended or |
| supported by the Linux kernel community at all. If however, updating to |
| the latest release is impossible, the individual changes to resolve this |
| issue can be found at these commits: |
| https://git.kernel.org/stable/c/0b5e6bd72b8171364616841603a70e4ba9837063 |
| https://git.kernel.org/stable/c/9f8554615df668e4bf83294633ee9d232b28ce45 |
| https://git.kernel.org/stable/c/7abf40f06a76c0dff42eada10597917e9776fbd4 |
| https://git.kernel.org/stable/c/b1ad04da7fe4515e2ce2d5f2dcab3b5b6d45614b |
| https://git.kernel.org/stable/c/a8e2fc8f7b41fa9d9ca5f624f4e4d34fce5b40a9 |
| https://git.kernel.org/stable/c/0e07032b4b4724b8ad1003698cb81083c1818999 |
| https://git.kernel.org/stable/c/5af16182c5639349415118e9e9aecd8355f7a08b |
| https://git.kernel.org/stable/c/ef575281b21e9a34dfae544a187c6aac2ae424a9 |