Vulnerability in the Linux kernel that allows corruption of read-only files

A vulnerability has been identified in the Linux kernel (CVE-2022-0847) that allows overwriting the contents of the page cache for any files, including those in read-only mode, opened with the O_RDONLY flag, or located on file systems mounted in read-only mode. On the practical side, the vulnerability could be used to inject code into arbitrary processes or corrupt data in opened files. For example, you can change the contents of the authorized_keys file for the sshd process. A prototype exploit is available for testing.

The problem was given the code name Dirty Pipe, by analogy with the Dirty COW critical vulnerability identified in 2016. It is noted that Dirty Pipe is on the same level as Dirty COW in terms of danger, but is much easier to operate. The vulnerability was identified during the analysis of complaints about periodic damage to files downloaded over the network in a system that downloads compressed archives from a log server (37 damages in 3 months on a loaded system), which were prepared using the splice() operation and unnamed pipes.

The vulnerability has been manifesting since the Linux 5.8 kernel, released in August 2020, i.e. is present in Debian 11 but does not affect the base kernel in Ubuntu 20.04 LTS. RHEL 8.x and openSUSE/SUSE 15 kernels are originally based on old branches, but it is possible that the change causing the problem was backported to them (no exact data yet). You can follow the publication of package updates in distributions on these pages: Debian, SUSE, Ubuntu, RHEL, Fedora, Gentoo, Arch Linux. A fix for the vulnerability was proposed in releases 5.16.11, 5.15.25, and 5.10.102. The fix is ​​also included in the kernel used in the Android platform.

The vulnerability is caused by the lack of initialization of the “buf->flags” value in the code of the copy_page_to_iter_pipe() and push_pipe() functions, despite the fact that the memory is not cleared when the structure is allocated, and with certain manipulations with unnamed pipes, “buf->flags” may contain a value from another operation. Using this feature, an unprivileged local user can achieve the appearance of the PIPE_BUF_FLAG_CAN_MERGE value in the flag, which allows you to overwrite data in the page cache by simply writing new data to a specially prepared unnamed pipe (pipe).

For an attack, the target file must be readable, and since access rights are not checked when writing to a pipe, replacement in the page cache can be made, including for files located in partitions mounted read-only (for example, for files c CD-ROM). After replacing the information in the page cache, the process, when reading data from the file, will receive not the actual, but the replaced data.

Operation comes down to creating an unnamed pipe and filling it with arbitrary data in order to achieve the setting of the PIPE_BUF_FLAG_CAN_MERGE flag in all ring structures associated with it. Next, the data is read from the pipe, but the flag remains set in all instances of the pipe_buffer structure in the pipe_inode_info ring structures. Then a splice() call is made to read data from the target file into an unnamed pipe, starting at the required offset. When data is written to this unnamed pipe, the PIPE_BUF_FLAG_CAN_MERGE flag will overwrite the data in the page cache instead of creating a new instance of the pipe_buffer structure.

Source: opennet.ru

Add a comment