LINUX.ORG.RU

Как можно гарантировать, что-то вроде целостности транзакций в ФС

 


2

2

Прочитал тут про свежую найденную уязвимость в стандартной библиотеке Rust, но что-то мне кажется, подобные вещи могут быть на любом языке и даже не совсем понятно как их избегать в общем случае, то есть, случае подмены файлов за короткое время

https://www.opennet.ru/opennews/art.shtml?num=56551

Уязвимость вызвана некорректной реализацией проверки символических ссылок перед рекурсивным удалением каталогов. Вместо запрета следования по символическим ссылкам, функция remove_dir_all() вначале проверяет, является ли файл символической ссылкой. Если определена ссылка, то она удаляется как файл, а если каталог - то вызывается операция рекурсивного удаления содержимого. Проблема в том, что между проверкой и началом операции удаления имеется небольшая задержка.

В момент, когда проверка уже проведена, но операция перебора каталогов для удаления ещё не началась, атакующий может подменить каталог со временными файлами на символическую ссылку. В случае попадания в нужный момент функция remove_dir_all() обработает символическую ссылку как каталог и начнёт удаление содержимого, на которое указывает данная ссылка.

Меня заинтересовал даже не конкретный случай, а как вообще надо правильно программировать в ситуациях, когда изменение файловой системы в процессе работы с ней может быть критично важным. Например, между readdir и операцией с найденными файлами.

★★★★★

Последнее исправление: praseodim (всего исправлений: 1)

Ответ на: комментарий от anonymous

Насколько оно удобно в работе? Если происходит блокировка на заметное время, особенно если процесс подвисает и быстро не раздупляется, то как оно с этим? Особенно в Linux какие варианты?

praseodim ★★★★★
() автор топика

объединить в одной транзакции две разные функции: чтение свойств объекта (файл|директория) и удаление онного объекта.
серъезный запрос на стабильность.

pfg ★★★★★
()

Отличная тема. Потому что я тоже не так и не нашёл способа как сделать правильно, вне зависимости от языка.

anonymous-angler ★☆
()

Некоторые fs могут иметь механизмы атомарного удаления, но это специфический вопрос к конкретной fs. Насчёт новости об уязвимости - не стоит относится серьёзно, в последние годы кибербезопасность просела из-за наплыва новых людей, которые выискивают псевдоуязвимости, чтобы оправдать свою работу.

mxfm ★★
()

А std::filesystem::remove_all не подвержена?

anonymous
()
Ответ на: комментарий от mxfm

псевдоуязвимости

Так-то проблема классическая, мя ещё в стародавние времена всякое запихивал в клиент майнкрафта после проверки античитом, но до запуска >_>

izzholtik ★★★
()

Писал себе архиватор/бекапер/обновлятор. Поставил задачу макимально избегать любых неконсистентностей/race/уязвимостей вовремя процесса, в расчёте на то что параллельно кто-то ещё пользуется файловой системой и нам об этом не сообщает. Да, там надо делать много проверок на каждый чих, и всё равно не гарантируется идеальная работа (можно привести к вылету с ошибкой при желании), но от уязвимостей с неавторизованной порчей данных способами, подобными описанному, вроде избавился. Для интереса посмотрел на tar - в нём как видно особо на этот счёт не парились, уязвимости были (на тот момент - где-то 2-3 года назад, сейчас не знаю).

В целом - считаю что ошибка в теме не случилась бы, если бы библиотеку изначально писали с безопасностью в голове, а не, как это сейчас принято, «сначала сделаем функционал прямого действия, а потом добавим проверки против уязвимостей».

Меня заинтересовал даже не конкретный случай, а как вообще надо правильно программировать в ситуациях, когда изменение файловой системы в процессе работы с ней может быть критично важным. Например, между readdir и операцией с найденными файлами.

На самом деле всё не так плохо. Тут вижу единственную проблему если ты хочешь рекурсивно удалить директорию, чистишь её от того что внутри, делаешь rmdir а она уже опять не пустая т.к. в ней ещё что-то создали. Видимо надо пробовать ещё раз. Если же речь идёт о какой-то полезной обработке контента, то соображение такое: ты сделал readdir, затем обработал файлы по списку, но из-за race condition что-то пропустил. Это же могло случиться и безо всяких race: новый файл могли создать тупо после твоей обработки по списку. А если речь идёт о каком-то более интеллектуальном взаимодействии между двумя прогами - они должны взаимно заботиться о синхронизации, например с помощью lock-файлов, иначе в общем случае всё равно ничего не выйдет - файловая система же не может знать логику их работы.

firkax ★★★★★
()
Ответ на: комментарий от anonymous-angler

заблокировать файл перед проверкой, чтобы между проверкой и удалением никто ничего с ним не смог сделать. но все зависит от реализации блокировок файлов в файловой системе.
и это не транзакция.

pfg ★★★★★
()
Последнее исправление: pfg (всего исправлений: 1)
Ответ на: комментарий от mxfm

Думаю нет потому что рустом никто не пользуется.

firkax ★★★★★
()
Ответ на: комментарий от anonymous

Нет. Но можно как систему контроля версий ещё использовать.

firkax ★★★★★
()
Ответ на: комментарий от pfg

Там как раз описывается рекомендательная блокировка. Их сейчас три способа сделать есть: fcntl, flock, lockf. Ни один из них не блокирует саму запись, это только межпроцессные флажки «занято», которые при желании можно проверять.

Про обязательную блокировку в современных манах ничего нет.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)

ну всё

В следующем выпуске федоры ждём systemd-fsyncd

на каждую файловую операцию будет создаваться отдельный контейнер podman в нём эта операция выполняется, потом пытаются смержить с реальной фс, при конфликте появляется окошко для пользователя что делать...

потом и другие дистрибутивы подтянутся

Bad_ptr ★★★★★
()
Ответ на: комментарий от firkax

хех, тогда протолкни системную функцию полной блокировки файла в VFS. посмотреть на эту бурю в стакане воды будет интересно…

pfg ★★★★★
()

даже не совсем понятно как их избегать в общем случае, то есть, случае подмены файлов за короткое время

rw - блокировки, и например вводить «эпоху изменений» обьекта. при любом изменении обьекта(запись, переименование и прочее) эпоха увеличивается на +1.

если проверка была сделана для обьекта с эпохой X, а удаление делается для обьекта с новой его эпохой - значит кто-то влез между операциями и изменил его, что есть место возможной некорректности

alysnix ★★★
()
Ответ на: комментарий от alysnix

Это все хорошо, но как-то не очень поддержано на уровне файловых операций.

praseodim ★★★★★
() автор топика
Ответ на: комментарий от alysnix

это конечно все красивое, но только теоритически, ибо опять же не атомарно.
отдельная операция чтения свойств файла и отдельная операция изменения файла.
вполне можно впихнуться между двумя функциями и изменить файл. т.е. те же яйтца, только вид сбоку.
только вариант функции изменения с проверкой эпохи. т.е. сделать изменение, только если эпоха соответствует эпохе, полученной в предыдущей функции.

pfg ★★★★★
()

Делаешь readdir, получаешь имя записи каталога. Делаешь fstatat на это имя с флагом AT_SYMLINK_NOFOLLOW. Если это каталог, то открываешь его open с флагами O_DIRECTORY+O_NOFOLLOW. Делаешь fstat на полученный файловый дескриптор. Сравниваешь статы. Если равны, cоздаешь енумератор fdopendir.

iliyap ★★★★★
()

У тебя целый линь это одна огромная дырень позволяющая любому, запущенному тобой, процессу делать что угодно с твоей домашней директорией. Я уже не говорю про убунты, которые по умолчанию дают доступ на чтение всем остальным пользователям/процессам к твоему домашнему каталогу.

И в таком ёб..м мире ты паришься, что кто-то там может подменить символическую ссылку?

foror ★★★★★
()
Последнее исправление: foror (всего исправлений: 1)

Могу ошибаться, но мне кажется BTRFS должен быть по замыслу очень надежен. Вообще, в целом, распространенные ФС в линуксе очень надежны.

целостность

  • Формально
    • sync?
    • git
    • hashes
anonymous
()

В этих ваших юниксах нет блокировки, но есть сохранение валидности fd открытого файла. Так что надо открыть, а потом работать не через имя файла, а через fd, не закрывая последний. Как-то так.

khrundel ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.