LINUX.ORG.RU

Проблема флага O_DIRECT

 , , ,

Проблема флага O_DIRECT

2

6

Даже пользователь без прав администратора способен вызвать необратимую рассинхронизацию дисков.

В Linux обнаружена серьёзная уязвимость, существующая уже более десяти лет, и связана она с механизмом программного RAID при использовании флага O_DIRECT. Проблема позволяет привести массив в несогласованное состояние, причём без каких-либо ошибок или предупреждений со стороны системы. Несмотря на то, что баг впервые был зарегистрирован ещё в 2015 году, интерес к нему вновь возрос в контексте современных задач, таких как живая миграция виртуальных машин.

Суть проблемы заключается в том, как пользовательские программы взаимодействуют с блочными устройствами при помощи O_DIRECT. Этот флаг позволяет выполнять прямой доступ к данным, минуя кеш ядра, что полезно для повышения производительности в ряде задач. Однако в случае программного RAID, такого как MD RAID, DRBD или LVM RAID, это приводит к тому, что каждый диск массива может получить разные данные, даже если они записываются с одного и того же указателя в пользовательском пространстве. В результате данные на отдельных устройствах перестают быть синхронизированными – массив остаётся «рабочим» с точки зрения системы, но фактически оказывается повреждённым.

Причём проблема не в самих данных, а в нарушении согласованности между дисками. Даже если данные представляют собой «мусор», они должны быть одинаковыми на каждом RAID-устройстве. В текущем же случае каждый диск получает свою версию этих данных. Причина в том, что каждый из драйверов нижнего уровня получает доступ к одной и той же области пользовательской памяти независимо друг от друга, что приводит к расхождениям при чтении и записи.

Уязвимость считается особенно опасной, так как может быть вызвана из пользовательского пространства без прав суперпользователя, если программа имеет доступ к файлу на RAID-массиве и использует O_DIRECT. Это означает, что RAID может быть повреждён обычным приложением, даже не подозревающим об этом эффекте. При этом никаких ошибок или предупреждений от ядра не поступает, и массив продолжает функционировать как будто ничего не произошло.

Из всех файловых систем Linux, известны только две, не подверженные этому дефекту при использовании с программным RAID – это OpenZFS и Bcachefs. Остальные решения остаются потенциально уязвимыми. Проблема до сих пор числится как открытая и не имеет официального исправления.

>>> Подробности

★★★★★

Проверено: dataman ()
Последнее исправление: hobbit (всего исправлений: 3)
Ответ на: комментарий от pekmop1024

ну хз.

у меня к zfs в целом хорошее отношение. но я с ней сталкивался почти исключительно под соляркой. ибо там без вариантов - либо ты на ней, либо хлебай «простое» амно с UFS+SVM - полной ложкой.

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

а почему ты мне это гришь?

я-то с Линусом солидарен, что это тяжкий пережиток старых UNIX и таких же старых СУБД (изначально это было придумано ради них)

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

у меня к zfs в целом хорошее отношение. но я с ней сталкивался почти исключительно под соляркой

К ZFS на солярке вопросов никаких нет, это её среда существования. А на линуксе ZFS нет, это какое-то школоподелие, которое под неё косить пытается.

Насчет готовности btrfs тоже много вопросов. У меня создалось впечатление, что эта фс позволяет легко привести себя в неработоспособное состояние неверными опциями монтирования (чего быть не должно). И это усугубляется общим оверинжинирингом и отсутствием понятия safe defaults.

pekmop1024 ★★★★★
()

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

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

Ну таки да:

so, zfs, bcachefs and btrfs seem to do right now and survive that «invalid O_DIRECT test cases»

А вдруг я Ъ?

Хорошо бы текст новости поправить.

Harliff ★★★★★
()
Последнее исправление: Harliff (всего исправлений: 2)
Ответ на: комментарий от pekmop1024

К ZFS на солярке вопросов никаких нет, это её среда существования. А на линуксе ZFS нет, это какое-то школоподелие, которое под неё косить пытается.

Тем не менее, на линуксе zfs вполне успешно эксплуатируют (не буду говорить за всех - лично я эксплуатирую). Не смотря на палки в колёсах.

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

не буду говорить за всех - лично я эксплуатирую

В продакшене? и на скольких серверах? И какое там железо? (не будем контролеры перечислять, просто марку сервера - типа HP-G10)

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

Да, в продакшене. Порядка 10 серверов на Proxmox.

Под журналы СУБД раньше выделял тома из lvm (поверх optane). Сейчас - когда как.

На ssd - zfs over lvm, на hdd - голый zfs.

Железо - SuperMicro (моделей не помню от древних на Xeon X5-26xx v4 до современных Epic) и Dell R470/750.

Harliff ★★★★★
()
Последнее исправление: Harliff (всего исправлений: 3)
Ответ на: комментарий от pekmop1024

Поконкретней бы критику. В идеале ещё бы и поконструктивней.

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

Proxmox, конечно, не всегда был супер-энтерпрайзом, но в целом я могу мириться/работать с их заскоками. А к ZFS какие претензии (кроме более низкой производительности, по сравнению с голым lvm)?

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

zfs over lvm

Мне кажется это какое-то избыточное нагромождение слоёв абстракции.

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

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

Ну тут-то не от root.

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

А может стоило запретить О_Директ для рейдов? Или сделать для него отдельную реализацию? Ну ладно, редкий косяк, но когда это всплывает - может стоит заняться этим?

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

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

Имеет ли это какие-то последствия шире? Ну там рейд при следующей загрузке не подмонтируется или ещё чего?

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

почему народу плевать что если от рута запустить

Потому что, пол-моему, надо быть идиотом, чтобы «запускать от рута» — это вполне очевидная для людей более-менее знающих глупость.

А вот «специально сделанная прога которая подменяет данные в потоке после синхронизации» — это опасность, не очевидная для большинства, да ещё и как-то заранее узнать надо, что оно такое может сотворить даже не «от рута»...

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

я-то с Линусом солидарен, что это тяжкий пережиток старых UNIX и таких же старых СУБД (изначально это было придумано ради них)

с чем солидарность-то? в отсутствии потенции принять тот факт, что существуют ворклоады, где ну очень бы хотелось избежать как минимум двойного кеширования данных? эти самые «старые СУБД» уже лет 10 как предоставляют возможность не раскладывать данные на файловые системы и формально устанавливаются чуть ли не со своими драйверами и файловыми системами, так что, за старые СУБД можете не переживать - переживайте лучше за «новые»

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

Поконкретней бы критику. В идеале ещё бы и поконструктивней.

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

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

что оно такое может сотворить даже не «от рута»…

Нет от рута, она это делает с данными не для рута. Юзер тоже может свой дом стереть и что?

mx__ ★★★★★
()

Чесно говоря, мне непонятна суть ошибки. Разве RAID не изображает из себя блочное устройство? Тогда как флаг O_DIRECT может повлиять на доступ?

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

Пам-пам-пам

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

no-dashi-v2 ★★★★
()
Ответ на: комментарий от kirill_rrr

ну сделай. ну займись. )))

в btrfs костыль придуман. ибо это всё сильно ухудшает общую производительность ВО ВСЕХ случаях, а O_DIRECT я лично вижу очень редко. а тем более без рекомендованного O_SYNC.

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

ты всё пропустил!

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

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

и это возникает в единственном случае - если не считать случай у liksys: Проблема флага O_DIRECT (комментарий)

  • когда включён O_DIRECT, а => в ядре выключена буферизация и предполагается, что открывший файл в таком режиме - знает, ято он делаетю
mumpster ★★★★★
()
Ответ на: комментарий от no-dashi-v2

В постгресе относительно нормальные разработчики

на самом деле, таких дебилов как в постгресе нужно еще поискать

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

а постгрес - к каким СУБД по вашему мнению относится?

так-то это как раз пример «старой», но нормальной СУБД.

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

я помню легенарный и эпичный секас с оракл direct на солярке при размещении не на внутренних сказюках как DBA и ихние погромизды изначально привыкли, а когда всё в SAN начало переползать.

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

а постгрес - к каким СУБД по вашему мнению относится?

к совершенно всратым.

я помню легенарный и эпичный секас с оракл direct на солярке при размещении не на внутренних сказюках как DBA и ихние погромизды изначально привыкли, а когда всё в SAN начало переползать.

свежо предание, да верится с трудом. В прошлый раз выяснилось, что кто-то даже про номера ошибок никакого понятия не имеет: PostgreSQL 18 (комментарий), я так понимаю, что речь идет по 2000-2006 год, что там было-то со стороны linux? штабильное ядро 2.4, какие-то эксперименты со стороны RH про NPTL, переход на UTF-8 в RH9, восхождение на олимп RHAS3 (на 2.1 никто внимание не обращал), драйвера рейдов, подгружаемые с дискеты, PostgreSQL 7.4, единая тема curve в KDE и GNOME от RH, а в Solaris все просто работало.

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

Если пришел мусор - будет записан мусор.

Если пользователеь пишет мусор - мусор и записывается. А модификация буфера во время записи это классический способ показать что записывается мусор

no-dashi-v2 ★★★★
()
Ответ на: комментарий от mky

RAID1 как-то знает, где данные ФС, а где мусор?

У него битмап есть, внезапно. В котором оно отмечает какие блоки синкнуты, какие заняты, какие свободны и т.п.

no-dashi-v2 ★★★★
()
Ответ на: комментарий от pekmop1024

багу 10

Это не баг, это фича оптимизации. Идея - максимально быстрая обработка, без всяких аллокаций, копирований, кэшей и т.д.

Тот же dd например никогда с этим багом не столкнется, потому что его адекватные люди писали - и они буферы in-flight запросов не переписывают.

В drbd например чуваки пошли в обход и просто копируют данные в собственый неизменяемый буфер.

no-dashi-v2 ★★★★
()
Ответ на: комментарий от mky

И даже e2fsck -f проходит.

Потому что чуваки, которые пишут ФС, знают, что менять в полете отправленные данные нельзя. И не меняют. Поэтому у них запись метеданных консистентна. А то что хомячки этого не знают - проблема хомячков. Это примерно как если офисный клерк покупает себе пятилитровую заднеприводную фиговину или моцосикл и потом раскладывается об столб.

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

no-dashi-v2 ★★★★
()

Влом читать комментарии, защитники решета уже набежали?

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

А может стоило запретить О_Директ для рейдов? Или сделать для него отдельную реализацию? Ну ладно, редкий косяк, но когда это всплывает - может стоит заняться этим?

По-хорошему надо бы опцию монтирования добавить. И не запретить, а просто игнорировать этот флаг. Это ничего не сломает, просто софт будет работать медленней. А администратор уже сам решит, что ему важней - корректность или скорость.

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

По-хорошему надо бы опцию монтирования добавить

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

no-dashi-v2 ★★★★
()
Ответ на: комментарий от KivApple
  1. Такой файл будет при чтении выдавать разные данные, в зависимости от того, какой диск используется для чтения в данный момент. Это может приводить к очень сложно отлаживаемым проблемам, если программа с O_DIRECT делает всё это не злонамеренно, а просто в результате неаккуратного кодирования.

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

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

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

эпичный секас с оракл direct на солярке при размещении не на внутренних сказюках

а в Solaris все просто работало.

я смотрю - чукча точно не читатель!

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

так он про это и говорит )))) только в другом разрезе )))))

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

А какое отношение lvm имеет к монтированию?

Почему по умолчанию так не монтируется - видимо это даёт ощутимые накладные расходы, которые в большинстве случаев людям не нужны. Я эту опцию сам не тестировал и вообще про неё только что узнал.

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

Если я правильно понял ихние маны, то этот флаг включает Direct I/O для всех файлов на смонтированной файловой системе, по умолчанию. А без этого флага приложение по прежнему может включать Direct I/O при открытии для нужного флага.

А я говорю про флаг, который бы заставлял драйвер файловой системы просто игнорировать флаг O_DIRECT при открытии файла, будто его нет. Ну или выдавать ошибку, или сделать возможность настраивать поведение, но главное - не разрешать использовать Direct I/O ни при каких обстоятельствах.

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

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

no-dashi-v2 ★★★★
()
Ответ на: комментарий от vbr

о главное - не разрешать использовать Direct I/O ни при каких обстоятельствах.

А еще можно себе кое-что отрезать, чтобы случайно никого не изнасиловать.

no-dashi-v2 ★★★★
()
Ответ на: комментарий от vbr

так ты читай ман полностью:

If forcedirectio is specified and supported by the file system, then for the duration of the mount, forced direct I/O will be used. If the filesystem is mounted using forcedirectio, data is transferred directly between user address space and the disk. If the filesystem is mounted using noforcedirectio, data is buffered in kernel address space when data is transferred between user address space and the disk. forcedirectio is a performance option that is of benefit only in large sequential data transfers. The default behavior is noforcedirectio.

т.е. проще всего выдать ошибку при попытке открыть файл с O_DIRECT и без O_SYNC. «This feature is not supported» и досвидос!

ref:

O_DIRECT is still a bad interface, with all sorts of performance and usage issues that have only gotten marginally better with time.

Linus wasn’t saying that O_DIRECT was pointless, he was just pointing out that the implementation is terrible even for its stated purpose. There’s a long compilation of emails elaborating on this point here: http://yarchive.net/comp/linux/o_direct.html

я тебе больше того скажу, ты можешь даже сам себе в ногу выстрелить как и автор по ссылке:

Thread #1:

int fl1 = open(filename, O_RDWR | O_DIRECT); … lseek(fl1, somewhere, SEEK_SET); write(fl1, data1, data_length);

Thread #2:

int fl2 = open(filename, O_RDONLY); … lseek(fl2, somewhere, SEEK_SET); read(fl2, data2, data_length);

и начать писать и читать как попало. а потом начать орать что де линукс плох и ваще решето!

технически btrfs в данном случае имеет костыль.

предложение твоё хорошее, иметь option. ведь технически можно подсовывать свою libc где O_DIRECT просто игнорируется, но злой хацкирь опять же тоже может свою libc иметь.

так что я солидарен с esi_y:

https://forum.proxmox.com/threads/mdraid-o_direct.156036/

и насколько я понял, там с PVE мутки были, нестандартные настройки включая тот самый O_DIRECT. ЕМНИП qemu в обычном режиме без о-директа всё открывает

mumpster ★★★★★
()
Ответ на: комментарий от no-dashi-v2

Это не баг, это фича оптимизации

Под «багом» имеется в виду «тикет». Так-то я примерно то же самое написал, что и ты.

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

я не большой знаток proxmox и про это прочитал по ссылкам.

насколько я понял, текущее обострение началось примерно с указанного обсуждения и PVE имели cache=none, эффективно включая O_DIRECT для ВМок.

возможно кончится тем, что они вот на это перейдут:

В ядро Linux добавлена возможность буферизированной работы с ФС без кеширования

patches adding support for RWF_UNCACHED, as a way to do buffered IO that isn’t page cache persistent. The approach back then was to have private pages for IO, and then get rid of them once IO was done. But that then runs into all the issues that O_DIRECT has, in terms of synchronizing with the page cache.

mumpster ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.