LINUX.ORG.RU

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

 , , ,

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

3

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)
Ответ на: комментарий от ValdikSS

Это почему? Виртуалка хз про раид вообще.

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

и нет причин почему в r1 и 10 это будут делать по другому чем в r5/6

Как это нет? r5 и r6 общеизвестно тормознутые, тут ничего не поделать ввиду их дизайна. r1 же может работать без лишних операций в памяти, и как итог будет то что он пишет. Я тоже именно про это первым делом подумал (из текста автора новости, как всегда у него, не особо понятно о чём конкретно речь).

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

Меня интересуют более приземлённые вопросы. У нас несколько клиентов. Среди них совершенно точно есть люди, у которых PVE на mdraid. Нам уже бегать по потолку или нужны какие-то спецусловия, чтобы баг проявился, которых у нас нет?

Я думаю, мы на следующей неделе посоветуем всем поменять режим кеширования, чисто на всякий случай.

А то, что баг есть — я не сомневаюсь.

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

В венде точно такая же херня с незапамятных времён для большинства «псевдо-RAID» карточек. Если сделать CreateFile с FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH а потом в процессе WriteFile менять буфер, (например, дописывать лог) из другого потока, то с некотрой вероятностью «псевдо-RAID» рассыпется, причём узнаешь ты об этом только через некоторое время, когда попытаешься прочитать записанное.

Лечится во всех ОС мутексом на write для файлов без кеширования/буферизации или использованием аппаратного RAID.

В линуксе, теоретически, починить можно, двойной буферизацией в md/lvm, пожертвовав производительностью, в венде - нельзя, потому что у каждого вендора свой проприетарный драйвер реализующий RAID, причём abandоned по истечении пары лет после выпуска железки.

Впрочем, не уверен, что это действительно надо чинить. Малварь из-под юзера может, например, безвозвратно удалить все данные юзера, что намного хуже чем рассинхронизированный рейд, который в общем-то можно восстановить банальным resync.

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

Ну, вероятно, стоит провести аудит их ПО и выяснить, есть ли среди этого ПО такое, которое использует O_DIRECT вообще и O_DIRECT без O_SYNC в частности.

А баг есть, да. И очень нехороший.

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

Я пока так и не понял баг. Вроде, будет рассинхрон только в блоках, куда записан мусор (через O_DIRECT). Гугл говорит, что если сделать этот самый:

echo check > /sys/block/md0/md/sync_action

то ничего страшного не происходит. Диски из зеркала не выкидывает. Даже если в /sys/block/mdX/md/mismatch_cnt не ноль. Даже если каждый месяц не ноль. Даже если там 665,000 различий. И даже e2fsck -f проходит.

И не совсем понятно, если ломать через qemu+swap, получит ли какой-то другой процесс в qemu испорченную память из swap или портятся только не используемые адреса?

Наверное, только получится, что если ты из виртуалки ломаешь mdraid хостеру, а он всё время смотрит на mismatch_cnt и запускает repair, то твоя и соседние виртуалки получат просадк по скорости I/O...

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

Что значит разваливает рейд? Она портит данные, которые пишет. Что в данной ситуации как будто бы не такое уж неожиданное поведение

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

ну в случае USB я бы поставил на то, что банально контакты виноваты: ты думал что вынул-вставил одну флешку, а на самом деле расшатал все три рядом воткнутые, задел их руками.

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

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

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

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

а линуксовый только от бедности

Или от жадности...

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

Внезапная смена линукса на макось?

И всё это потом переписать на Rust...

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

причём пользователь - ССЗБ. ибо испольузет O_DIRECT, т.е. заведомо берёт ответственность на себя.

mumpster ★★★★★
()

Для решения проблемы можно переводить страницы в RO до завершения записи. Тогда прогамма с багом просто упадёт.

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

я не боюсь, я знаю. я ту статью ещё в 1999 году прочитал. после которой и началась разработка ZFS с учётом факта. хотя тогад диски в тб выглядело жуткой фантастикой, 20ГБ ещё не начались. а dm-int. даёт тормоза .:(

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

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

уж 3008 - точно не лучше sw raid! как и Marvel m2-raid в UCS.

у hw только один большой плюс - батарейка или ионистор

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

выяснить что? почему 10 лет никто не чесался исправить?

так причину там же и озвучили. плюс я привёл мнение Линуса по этом поводу.

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

не! щаз очень мало FRU, диски давно уже у всех CRU.

но с учётом реалий - обычно это не работник компании, а outstaff.

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

решение есть и та же btrfs именно так и поступает - плюёт на O_DIRECT и буферирует. ну либо надо memcpy делать и для r1. раньше этого избегали ввиду дороговизны операции на всяких там P1. но щаз то? но опять же смысл в этом если это нужно полторы калеке?

mumpster ★★★★★
()

Вот по этому я raid-ы никогда и не использую, как только ты создаёшь raid, ты становишся рабом лампы raid-а.

PS. А DRBD это вообще неприкрытая диверсия, как только вы записываете туда какие-либо данные, можете считать их потерянными.

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

В репорте пишут, что и btrfs тоже не подвержена.

Пишут, что не подвержена теперь. Но надо ещё смотреть, в какие ядра попал патч, появившийся в начале этого года.

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

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

А расскажи мне, как решается вопрос работы драйвера устройства на нескольких ядрах? А то ahci имеет один поток и висит на одном ядре, в отличие, от, например, megasas какого-нибудь (cat /proc/interrupts). Или какие-то специальные контроллеры покупаются под софт раид?

Так-то у железного RAID один недостаток: зип нужен именно этот, а не любой. Найти бы железный RAID, чтобы диски можно было через mdadm цеплять, случись что...

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

я не боюсь, я знаю. я ту статью ещё в 1999 году прочитал. после которой и началась разработка ZFS с учётом факта. хотя тогад диски в тб выглядело жуткой фантастикой, 20ГБ ещё не начались. а dm-int. даёт тормоза .:(

Собственно, все дает примерно одинаковые тормоза. Но комбайны вроде ZFS и btrfs чаще ломаются в силу оверинжиниринга.

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

у hw только один большой плюс - батарейка или ионистор

Плюсов много, но да, если мы говорим не про SmartArray B-series :) А ионисторы у меня и в PM9A1 прям на борту есть.

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

решение есть и та же btrfs именно так и поступает - плюёт на O_DIRECT и буферирует. ну либо надо memcpy делать и для r1. раньше этого избегали ввиду дороговизны операции на всяких там P1. но щаз то? но опять же смысл в этом если это нужно полторы калеке?

Там вон Оверстрит пишет, что btrfs при определенных условиях подвержена тоже проблеме.

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

RAID1

Это про как совместить железный с mdadm? Это-то знаю, это не интересно. ;-)

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

Она приводит к появлению неконсистентного блока в рейд-массиве. Это называется рейд развалился.

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

Там вон Оверстрит пишет, что btrfs при определенных условиях подвержена тоже проблеме.

Судя по https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-6.17.y&id=968f19c5b1b7d5595423b0ac0020cc18dfed8cb5 исправление про btrfs попало в 6.17, а вот что по поводу остальных...

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

их ВМ ты можешь испортить только свои данные.

Не распарсил.

но вам оно не понравится.

Разумеется. Я бы вобще предпочёл, чтобы все накопители можно было переформатировать в 520-528 байт. Или чтобы обычные ФС могли работать с блоками с размером не кратным 512 байт.

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

зип нужен именно этот, а не любой.

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

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

И не факт, что зип поможет.

Тут я про смерть контроллера. ЗИП безусловно поможет.

Если железный raid пометил диск как выбывший, то всё, флага assume-clean нет.

Вообще-то у Intel точно есть, как минимум на SRCU31 (древний SCSI, сам когда-то так попадал и снимал метку «битый»). На Intel RS25DB080 (MegaRAID SAS 2208) вовсе была ситуация c плохим сектором на втором HDD в RAID5 (не надо писать про RAID6, бакапы и т.п., это я сам умею писать ;-) ). То есть один отпал с концами, а RAID не перестраивался из-за ещё одного. dd с игнорированием, надежда на то, что плохой блок в ненужном файле или на пустом месте (оправданная, так как всё читалось), и всё восстановилось. Так что надежда и с железным умирает последней.

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

А должно быть безусловное зеркалирование всего что пишется идентично на оба диска. Может быть с поправкой на некий лаг, но всё таки безусловно зеркально.

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

ЗИП безусловно поможет.

Я в контексте: «быстро восстановить работу сервера». Если контроллер выкинул диски или как-то ещё запорол суперблок, и новый не принимает диски в массив, то пересбор, и т.д., долго. И, получается, уже без разницы, именно эта модели или другая.

SRCU31  — это же ICP vortex, который продали Adaptec, который тоже купили и где они сейчас...

А с dd и MegaRAID я не понял, как dd с диска метку, что он битый. Если сектор не читался, то диск должно было выкинуть и с концом. А с учётом того, что LSI в своё время покупал 3ware технологию, то вобще не предсказуемо, что будет сейчас под маркой Intel.

mky ★★★★★
()

chatgpt говорит что монтирование ext4 с опцией data=journal решает описанную проблему для связки soft raid + ext4

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

я и так эту связку много лет использую, так что да буду и дальше

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

Я в контексте: «быстро восстановить работу сервера».

Я имел ввиду «контроллер сам помер». С mdadm-то где угодно всё это можно подцепить.

А с dd и MegaRAID я не понял, как dd с диска метку, что он битый. Если сектор не читался, то диск должно было выкинуть и с концом.

Не успело. До того выкинуло другой, RAID5 был в деградированном режиме и перестраивался, когда наткнулся на плохой сетор. Метка не ставилась, всё просто по halt вставало. Вот на другом компьютере этот hdd и был скопирован с «conv=noerror,sync», вставлен в RAID, RAID был оживлён в деградированном режиме, потом был добавлен новый hdd на замену совсем помершему.

Хотя вот сейчас думаю, а может это тоже на SRCU31 было... Что-то сомневаться начал.

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

However, there is also the data=journal option, which means that

"All data are committed into the journal prior to being written into the main file system. Enabling this mode will disable delayed allocation and O_DIRECT support."
cdtemp
()
Ответ на: комментарий от kirill_rrr

ты вообще читал обсуждение?

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

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

технически все НЖМД могут работать с размером сектора больше своего стандартного, у CLARiiON он и был 520 байт, инфа - сотка! а два байта из дополнительных 8 были для гарантии целостности R5, туда временная метка писалась.

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

так о том и речь - если O_DIRECT включаешь - то ССЗБ.

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

была подвержена - так правильней.

и да - она только-только стала годна для работы

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