В ядрото на Linux е открита уязвимост (CVE-2022-0847), позволяваща замяна на съдържанието на страницовия кеш за всякакви файлове, включително онези, които са в режим само за четене и са отворени с флаг O_RDONLY или разположени в файлови системи, монтирани в режим само за четене. Практически, уязвимостта може да се използва за инжектиране на код в произволни процеси или изкривяване на данни в отворени файлове. Например, може да се промени съдържанието на файла authorized_keys за процеса sshd. Прототип на експлойт е наличен за тестване.
На проблема е дадено кодово име Dirty Pipe, аналогично на откритата през 2016 година критична уязвимост Dirty COW. Отбелязва се, че по ниво на опасност Dirty Pipe е на същото ниво с Dirty COW, но значително по-проста за експлоатиране. Уязвимостта е открита в процеса на разглеждане на оплаквания за периодично повреждане на файлове, изтегляни по мрежата в система, зареждаща компресирани архиви от log-сервер (37 повредени файла за 3 месеца в натоварена система), при подготовката на които е използвана операцията splice() и неназовани канали.
Уязвимостта се проявява от ядрото на Linux 5.8, пуснато през август 2020 година, т.е. присъства в Debian 11, но не засяга основното ядро в Ubuntu 20.04 LTS. Ядрото RHEL 8.x и openSUSE/SUSE 15 първоначално са базирани на стари клони, но не е изключено, че проблематичната промяна е била бексторирана в тях (точни данни все още няма). Може да се проследи публикуването на ъпдейти на пакетите в дистрибутивите на следните страници: Debian, SUSE, Ubuntu, RHEL, Fedora, Gentoo, Arch Linux. Корекция на уязвимостта е предложена в версиите 5.16.11, 5.15.25 и 5.10.102. Корекцията също така е включена в ядрото, използвано в платформата Android.
Уязвимостта е причинена от липсата на инициализация на стойността «buf->flags» в кода на функциите copy_page_to_iter_pipe() и push_pipe(), когато паметта при разпределение на структурата не се изчиства, и при определени манипулации с неназовани канали в «buf->flags» може да се окаже стойност от друга операция. Използвайки това, непривилегирован локален потребител може да предизвика появата на флага PIPE_BUF_FLAG_CAN_MERGE, който позволява организирането на презапис на данни в страницовия кеш чрез просто записване на нови данни в специално подготвен неназован канал (pipe).
За атаката целевият файл трябва да бъде достъпен за четене, тъй като при запис в pipe не се проверяват правата за достъп, замяната в страницовия кеш може да се извърши и за файлове, разположени в раздели, монтирани само за четене (например, за файлове на CD-ROM). След замяната на информация в страницовия кеш, процесът при четене на данни от файла ще получи не действителни, а подменени данни.
Експлоатацията се състои в създаване на неназован канал и запълването му с произволни данни, за да се постигне поставянето на флага PIPE_BUF_FLAG_CAN_MERGE във всички свързани с него кръгови структури. След това данните се четат от канала, но флагът остава поставен във всички екземпляри на структурата pipe_buffer в кръговите структури pipe_inode_info. След това се извършва извикване на splice() за четене на данни от целевия файл в неназования канал, започвайки от желаното отместване. При записването на данни в този неназован канал, поради поставения флаг PIPE_BUF_FLAG_CAN_MERGE, данните в страницовия кеш ще бъдат презаписани, вместо да се създаде нов екземпляр на структурата pipe_buffer.
Източник: opennet.ru
