The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Вариант для распечатки  
Пред. тема | След. тема 
Форум Разговоры, обсуждение новостей
Режим отображения отдельной подветви беседы [ Отслеживать ]

Оглавление

Уязвимость в подсистеме io_uring, позволяющая получить привилегии root, opennews (ok), 01-Апр-24, (0) [смотреть все]

Сообщения [Сортировка по времени | RSS]


6. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +2 +/
Сообщение от Аноним (-), 01-Апр-24, 11:36 
Сначала подумал, что это шутка, ведь сегодня День Дурака.
А потом решил, это же use-after-free и получение рута, и с таким не шутят)

В общем классическая уязвимость "позволяющая непривилегированному пользователю получить права root в системе" да еще и с рабочим эксплойтом.
Хорошо, что это совсем-словсем не связанно с используемым языком, и возможностями по отстрела ног которые он дает.

Ответить | Правка | Наверх | Cообщить модератору

19. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  –1 +/
Сообщение от Аноним (19), 01-Апр-24, 12:17 
Да господи, язык тот тут причем?
Если программист не хочет или не может банально обнулить указатель после освобождения памяти, то увы, вина того, кто пишет
Ответить | Правка | Наверх | Cообщить модератору

23. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +2 +/
Сообщение от Аноним (-), 01-Апр-24, 12:35 
Хм, а я что сказал что "виноват язык"?
Понятно что програмер если захочет, то может сделать и один free, и два, и десять.
А потом попробовать обратиться к мертвому объекту.

Но представь у тебя есть две дороги, одна двухполосная без отбойника, а другая такая же но с отбойником. Как думаешь, где плохих аварий будет больше?

Ответить | Правка | Наверх | Cообщить модератору

26. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  –1 +/
Сообщение от Аноним (26), 01-Апр-24, 12:49 
> Да господи, язык тот тут причем?

При том, что он не должен не должен пропускать подобные банальные штуки.
Если язык не может, значит нужно использовать чекеры, санитайзеры и прочие утилиты для обнаружения детских ошибок.
Если ни язык, ни экосистема этого языка не позволяют создать 100% защиту от подобных ошибок, значит виноват язык.
Здесь часто говорят, что "проблем нет, надо просто использовать простой советский...", но что-то в больших проектах никак не найдёт способ избавиться от детских болезней. Вывод очевиден - это невозможно, и виной - язык.

Ответить | Правка | К родителю #19 | Наверх | Cообщить модератору

33. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от ИмяХ (ok), 01-Апр-24, 13:18 
>>значит нужно использовать чекеры, санитайзеры и прочие утилиты для обнаружения детских ошибок

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

Ответить | Правка | Наверх | Cообщить модератору

35. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 01-Апр-24, 13:32 
> Но почему-то никто этого не сделал перед тем, как принять код в ядро. Ни комитет, который принимает патчи, сам Линус, ни мейнтейнеры, ничего не сделали, чтобы предотвратить это. Либо делали, но намерено скрывали, чтобы продать информацию троянописателям.

Давай воспользуемся бритвой Хэнлона и попытаемся не приписывать "злому умыслу то, что вполне можно объяснить глупостью".

То, что пограмисты на СИ зачастую не пользуются санитайзерами и даже иногда не пишут тесты, это распространненная проблема.
Думаю причин тут много, начиная от лени: 'ну я уже написал код, он компилируется и даже рабоатет, чего вы от меня еще хотите!', заканчивая непомерным ЧСВ: 'СИ программмеры это же илита! они в само ядро свой код навыпрограммировали. это же профи, как они могут ошибаться!'
Еще можно вспомнить классные аргументы от самых знающих анонимов "автотесты долго бегут, я нехочу ждать даже 10 минут!", "настоящие программисты таких глупых ошибок не делают", и "я просто проверяю код и все работает" от Профессор Навигатор.

А то что это 'приняли в ведро'? Ну так у тебя есть выбор, или взять что есть, или сидеть без нужных компонентов, тк писать это некому, или писать самому.
Как ты думаешь почему драйвер от самсунг приняли? Ну тот в котором потом нашли кучу уязвимостей и который, как выяснилось, писал бедный раб с галеры, тянувший то ли 3, то ли 4 проекта одновременно.

Ответить | Правка | Наверх | Cообщить модератору

122. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от ProfessorNavigator (ok), 02-Апр-24, 12:54 
> Еще можно вспомнить классные аргументы от самых знающих анонимов "автотесты долго бегут, я нехочу ждать даже 10 минут!", "настоящие программисты таких глупых ошибок не делают", и "я просто проверяю код и все работает" от Профессор Навигатор.

Профессор всё видит. На экзамене встретимся))

А касательно проверки - единственная гарантия того, что код будет работать, как задумано - полное и тщательное тестирование всех функций и сценариев работы. Всё. Остальное никаких гарантий не даёт. Точнее даёт - что вы напихаете ещё больше ошибок. Если на тестировании код не работает, как задумывалось, и вы не может понять, в чём причина, только тогда можете воспользоваться системами автоматической проверки. Чтобы выявить проблемный участок. Затем переписать, и снова на тест. Повторять до получения приемлего результата.  

Ответить | Правка | Наверх | Cообщить модератору

60. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (60), 01-Апр-24, 15:27 
Сам Линус как был замшалым финским студентом с версией 0.1, так и остался им на всю жизнь. Отсюда и все беды Linux. В академических осях инновации более осмысленные. Как следствие, проблемы намноооого реже. Линуса от управления разработкой ядра надо давно смещать. Сейчас в ядро тянется все подряд, а Линус, как собачка на торпеде, одобрительно на всё.
Ответить | Правка | К родителю #33 | Наверх | Cообщить модератору

90. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (65), 01-Апр-24, 19:20 
Только вот академический Minix имеет практических использований раз (IntelME)... и всё, в отличие от неакадемического.
Ответить | Правка | Наверх | Cообщить модератору

99. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 01-Апр-24, 22:19 
Подумаешь, сотни миллионов процессоров по всему миру.
Вот тебе и академический код)
А еще можно вспомнить всякие нетфликсы и амазоны.
И старую маоксь...

О, вспомнил еще про ThreadX, которая сейчас Azure RTOS - 20 лет в проде, более 12 миллиардов устройств, успешный коммерческий проект.
Это тебе не дырявое ядро впаривать.

Ответить | Правка | Наверх | Cообщить модератору

43. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Витюшка (?), 01-Апр-24, 14:16 
В ядре часто код который в main попадает тупо банально даже не компилируется!!! На это раз жаловался сам Линус. Так что до стадии "виновата С дыряшка" там просто не дошли.
Ответить | Правка | К родителю #26 | Наверх | Cообщить модератору

46. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Анонин (-), 01-Апр-24, 14:27 
> в main попадает тупо банально даже не компилируется

Серьезно?
А можно ссылки на PR или обсуждения?

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

PS: как вообще можно залить некомпилируемый код? Его же CI не пропустит.

Ответить | Правка | Наверх | Cообщить модератору

61. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +1 +/
Сообщение от User (??), 01-Апр-24, 15:27 
> PS: как вообще можно залить некомпилируемый код? Его же CI не пропустит.

Хе-хе-хе. Какой-такой си-ай хен-тай? Мы такого не знай - вон, оно в почту пролезай - фигли еще надо?!

Ответить | Правка | Наверх | Cообщить модератору

75. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Витюшка (?), 01-Апр-24, 16:40 
Естественно я сейчас не найду. Там очень много чего не работает на других архитектурах.

Те код (общий) не компилируется под какую-то архитектуру, не то что не тестируется. На это Линус и жаловался. Какая-то там архитектура не помню, но не прямо какая-то экзотическая, risc-v типа того. Он в итоге завернул этот код (он прилетел из веток linux-next или какой-то подсистемы).

Те он решил что-то сам ручками потестить, а оно даже не скомпилировалось :))

Ни про какие CI я не слышал в Linux kernel.

Ответить | Правка | К родителю #46 | Наверх | Cообщить модератору

79. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +2 +/
Сообщение от Анонин (-), 01-Апр-24, 17:33 
Спасибо за пояснение. Нашел.
То что на это сагрился сам Торвальдс всё существенно упростило))

"Your testing is seriously lacking.
This doesn't even build."
lore.kernel.org/dri-devel/CAHk-=wgPJttFz8yrdpPTN-ypMmDXHOKw9yi1nZSEq+7+tGftZA@mail.gmail.com/

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

С другой стороны, разрабы ядра люди занятые, на них большая ответственность.
Поэтому они могут ответственно сказать "LGFM" и замерджить.

Ответить | Правка | Наверх | Cообщить модератору

27. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  –3 +/
Сообщение от Аноним (27), 01-Апр-24, 12:53 
В нормальных же языках такое в принципе нельзя сделать. Памятью там управляет не программист, а сборщик мусора.
Ответить | Правка | К родителю #19 | Наверх | Cообщить модератору

32. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +4 +/
Сообщение от Аноним (22), 01-Апр-24, 13:17 
При написании ядра сборщики мусора обычно неработают.
Ответить | Правка | Наверх | Cообщить модератору

48. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (27), 01-Апр-24, 14:38 
Ответ был на фразу "да причем здесь языки вообще". Что стоит использовать или нет в ядре - это существенный вопрос конечно, но другой.
Ответить | Правка | Наверх | Cообщить модератору

34. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +2 +/
Сообщение от Аноним (11), 01-Апр-24, 13:29 
Ты хотел сказать в игрушечных языках.
Ответить | Правка | К родителю #27 | Наверх | Cообщить модератору

50. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  –2 +/
Сообщение от Аноним (27), 01-Апр-24, 14:42 
Ок, продолжайте использовать неигрушечные, позволяющие заинтерисованным лицам всегда иметь незакрытые дыры в линуксах
Ответить | Правка | Наверх | Cообщить модератору

144. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (144), 03-Апр-24, 03:47 
игрушечных? то, что они не предназначены для системного программирования/embedded/жесткого реального времени не мешает языкам со сборкой мусора доминировать во всех остальных областях, так как в абсолютном большинстве случаев конечному потребителю ПО плевать на задержки, пока они от нескольких десятков до пары сотен миллисекунд.
Ответить | Правка | К родителю #34 | Наверх | Cообщить модератору

51. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 01-Апр-24, 14:48 
Ну обнулишь ты указатель, можешь даже сделать memset(ptr, 0, len), а сишечка возьмет да и выбросит твое обнуление.
О - оптимизация.

https://wiki.sei.cmu.edu/confluence/display/c/MSC06-C.+Bewar...

Ответить | Правка | К родителю #19 | Наверх | Cообщить модератору

69. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (19), 01-Апр-24, 16:08 
Ну тогда asm volatile заинлайнить, где тупо xor делается, такое по идее не должно никакой оптимизацией аннигилироваться

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

Вообще конечно забано читать и наблюдать этот хейт в сторону си и всевозможное облизывание раста

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

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

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

Ответить | Правка | Наверх | Cообщить модератору

73. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +1 +/
Сообщение от Аноним (73), 01-Апр-24, 16:33 
> Да, это добавляет супер лоулевел зависимость от конкретной архитектуры, но не вижу в этом проблемы вообще

Странно, обычно адепты СИ просто писаются от осознания сколько платформ поддерживается и насколько код переносимый.

> Вообще конечно забано читать и наблюдать этот хейт в сторону си и всевозможное облизывание раста

А чего СИ хейтить? Это просто как рагаться на пенсионера с деменцией.
А вот тех, кто его посадил за руль автобуса..

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

Ну культуры написания кода вообще и безопасной работы с памятью, в частности, СИ программимсты не развили и за 50 лет.
Так что в худшем случае ничего не поменяется.
А в лучшем, станет меньше тупых ошибок вида "я выщел за границы буфера, вот тебе руть!"

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

Хахаха, а сейчас типа эти концепции есть?
Вот вроде каждый погромист-дыряшечник знает "выделил память, очисти, только один раз", а толку?
Одни и те же ошибки use-after-free, double-free и out-of-bounds из года в год.

> Ведь все и так работает, то в сознании большинства так будет работать и на любом другом языке

В сознании большинства компутер работает на магии)


Ответить | Правка | Наверх | Cообщить модератору

81. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 01-Апр-24, 17:47 
> если раст такое позволяет из коробки делать, то велик шанс того, что такие концепции работы с памятью вообще могут стереться из общественного сознания через пару поколений

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

Ответить | Правка | К родителю #69 | Наверх | Cообщить модератору

84. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +1 +/
Сообщение от Аноним (-), 01-Апр-24, 18:08 
> Вот я о чем: если раст такое позволяет из коробки делать, то велик шанс того, что такие концепции работы с памятью вообще могут стереться из общественного сознания через пару поколений

Они либо полезные, либо их не так уж жалко.

Родители рассказывали как картошку копать, в поездках в колхоз от университета.
Моя бабаушка рассказывала как стирать белье в проруби и как косить корм скотине.
Думаю ее родител могли бы рассказать как чистить примус или разжигать дровяную печку.
Я уже молчу про древних-древних предков, которые рассказали бы (при помощи 50 звуков и нескольких жестов) как сделать надежную палку-копалку, выбрать кремнь для каменного наконечника и как свалить мамонта.

Но мне эти навыки нафиг не упали. И я надеюсь, что и не понадобятся.

Ответить | Правка | К родителю #69 | Наверх | Cообщить модератору

98. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (98), 01-Апр-24, 21:24 
Не совсем по теме, но очень нравится, как там взяли решение из документа комитета[1], но поменяли слова "некоторые компиляторы выкидывают volatile в нарушение стандарта" на "выкидывают в строгом соответствии со стандартом".

"should work on any standard-compliant platform. There has been recent notice that some compilers violate the standard by not always respecting the volatile qualifier."
==>
"calling functions and accessing volatile-qualified objects can still be optimized out (while maintaining strict conformance to the standard)"

[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf

Ответить | Правка | К родителю #51 | Наверх | Cообщить модератору

70. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  –1 +/
Сообщение от fidoman (ok), 01-Апр-24, 16:14 
Угу, а также найти все прочие указатели на эту область памяти, и тоже обнулить.
И ядру сказать, вот я передавал указатель при вызове асинхронной функции, его тоже обнули.
Если бы всё так просто решалось...
Ответить | Правка | К родителю #19 | Наверх | Cообщить модератору

83. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 01-Апр-24, 18:06 
> Да господи, язык тот тут причем?

В этой уязвимости я б сказал язык действительно не при чём.

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

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

Но и в целом, обнуление указателей -- это так себе защита от use-after-free, потому что он сценарий этого примерно такой:

    free(p);
    p = NULL; // давай положим в p ноль, как ты настаиваешь, чтобы не было use-after-free.
    int *next_p = get_some_buffer();
    *next_p = 42; // вот здесь этот next_p оказывается равен тому значению, которое уходило во free 3 строки назад, и вся твоя "защита" оказалась бесполезной

Это сценарий упрощённый, с тем чтобы проще понять было. В реальности же значение адреса может быть было где-то сохранено нечаянно, и оно потом будет лежать три месяца, пока вдруг процесс не решит сделать что-нибудь такое, что он раз в полгода делает, и вот тогда он то значение извлечёт и наступит на грабли use-after-free.

Чтобы не было use-after-free тебе надо перед тем, как делать free для адреса, найти _все_ указатели в памяти, хранящие этот адрес, обнулить все эти указатели кроме одного _локального_, после этого на последнем указателе вызывается free, и делается return. Последний указатель уже нет нужды обнулять.

Но найти все указатели хранящие данный адрес в общем случае может только сборщик мусора. В специальном случае программист может следить за тем, чтобы адреса такого рода хранились бы каждый в единственном экземпляре, что делает поиск ненужным. Иногда программист знает, что адрес хранится здесь и (может быть) ещё там, и соответственно он проверяет это перед free. Но когда программа работает со сложными структурами данных в памяти, и когда она ещё жмётся выделять память из кучи, и постоянно пытается обойтись указателями на существующие объекты (типа подстрок например), то _нечаянно_ от простых правил поиска всех копий адреса в памяти, можно придти к необходимости полного mark-and-sweep. Что хуже, это "нечаянно" легко может остаться незамеченным.

Ответить | Правка | К родителю #19 | Наверх | Cообщить модератору

112. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от n00by (ok), 02-Апр-24, 11:44 
> Но найти все указатели хранящие данный адрес в общем случае может только
> сборщик мусора.

В частном хватает std::shared_ptr<>.

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

Это делает std::unique_ptr<>.

А Rust что делает? unique_ptr выполняет на этапе компиляции, а в остальных случаях просто бьёт по руками и не позволяет написать код? Или там свой std::shared_ptr<> для неопределённого на этапе трансляции количества указателей?

Ответить | Правка | Наверх | Cообщить модератору

118. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 02-Апр-24, 12:26 
> unique_ptr выполняет на этапе компиляции

Если очень-очень упрощенно - то да. Только unique_ptr нужно проверять на empty, а тут не нужно.

> а в остальных случаях просто бьёт по руками

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

> и не позволяет написать код

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

Но у раст есть свои аналоги shared_ptr:
Rc - Single-threaded reference-counting pointer (doc.rust-lang.org/std/rc/struct.Rc.html)
Arc - Thread-safe reference-counting pointer (doc.rust-lang.org/std/sync/struct.Arc.html)

Ответить | Правка | Наверх | Cообщить модератору

123. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от n00by (ok), 02-Апр-24, 13:02 
>> и не позволяет написать код
> Не позволяет писать заведомо невалидируемый код.
> Но у раст есть свои аналоги shared_ptr:
> Rc - Single-threaded reference-counting pointer (doc.rust-lang.org/std/rc/struct.Rc.html)

Не подходит, код ядра выполняется в произвольном потоке.

> Arc - Thread-safe reference-counting pointer (doc.rust-lang.org/std/sync/struct.Arc.html)

The type Arc<T> provides shared ownership of a value of type T, allocated in the heap.

В ядре в общем случае нет кучи.

If you need to mutate through an Arc, use Mutex, RwLock, or one of the Atomic types.

То есть выбор сводится к:
1. Написать заведомо невалидируемый код.
2. Висеть в примитивах синхронизации, как и в наивной реализации std::shared_ptr.

Ответить | Правка | Наверх | Cообщить модератору

125. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 02-Апр-24, 14:51 
Для ядра возможно есть специальные конструкции.
Но какие именно не скажу, это нужно лезть в соответствующую ветку rust-for-linux и смотреть что нового.
Или в ядро, если кода уже перенесли.
Но т.к. я ни разу не ядерщик, то умываю руки)
Ответить | Правка | Наверх | Cообщить модератору

137. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от n00by (ok), 02-Апр-24, 17:49 
Суть в том, что если всё это переносится в рантайм, то преимущества перед плюсами теряются. Да и на плюсах пришлось бы писать в стиле Си с голыми указателями, когда важна скорость и минимум блокировок. По-хорошему, следует архитектуру пересматривать, но ещё не известно, что из этого получится. Микрософт вон закопала Singularity.
Ответить | Правка | Наверх | Cообщить модератору

139. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Анонин (?), 02-Апр-24, 18:17 
> когда важна скорость и минимум блокировок

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

Ответить | Правка | Наверх | Cообщить модератору

140. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от n00by (ok), 02-Апр-24, 18:59 
А главное, что комментировать новость может всякий. Даже не имея представления, когда возможно использовать мютексы, а когда остаётся лишь спинлок, и то, если никто не увидит и не настучит по рукам.
Ответить | Правка | Наверх | Cообщить модератору

142. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 02-Апр-24, 20:07 
> Не подходит, код ядра выполняется в произвольном потоке.

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

>> Arc - Thread-safe reference-counting pointer (doc.rust-lang.org/std/sync/struct.Arc.html)
> The type Arc<T> provides shared ownership of a value of type T, allocated in the heap.

Ага, это аналог atomic<shared_ptr<T>>

> В ядре в общем случае нет кучи.

1. А в ядре никто и не использует std. Под ядро написана замена std, которая во многом похожа, но всё же заметно различается, например Vec::new() возвращает Result<Vec, _>, а не Vec. Я не разглядывал её, но подозреваю что все эти разговоры про Rc и Arc туда слабо применимы, потому что в ядре очень востребованы обёртки над сишными типами с рефкаунтами, и для создания таких обёрток Rc и Arc бесполезны.

2. Если в ядре нет кучи, то нет никакого смысла говорить про shared_ptr, use-after-free, и пр. Когда троллишь, следи за толщиной, потому что тут ты явно перебрал.

> То есть выбор сводится к:
> 1. Написать заведомо невалидируемый код.
> 2. Висеть в примитивах синхронизации, как и в наивной реализации std::shared_ptr.

Да, он в C++ сводится к тому же, если код пишет вменяемый программист. Потому что мутабельный конкуретный доступ к данным -- это гарантия получить пачку дата-рейсов. Бывают иногда ситуации, когда разумные люди на это идут сознательно, но простите в таких случаях они пишут на ассемблере, выверяя чёткую последовательность команд для каждой конкретной архитектуры. На C/C++/Rust нельзя полагаться в этих ситуациях, потому что те когда оптимизируют творят такую хрень, что чёткую последовательность команд получиться не удастся никак.

Подход раста в этом отношении отличается от подхода C++ только тем, что он не позволяет неразумным программистам организовать датарейс несознательно. Неразумный споткнётся об ошибки компиляции, которые он может одолеть при помощи unsafe, но это, простите, уже случай сознательного и целенаправленного создания датарейса. Никакие аппеляции к бритве Хэнлона не позволят ему отмазаться после такого.

Ответить | Правка | К родителю #123 | Наверх | Cообщить модератору

146. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от n00by (ok), 03-Апр-24, 11:44 
>> Не подходит, код ядра выполняется в произвольном потоке.
> Это может быть не важно, в каком потоке он выполняется. Главное чтобы
> к Rc не было бы попыток конкурентного доступа из разных потоков.

Такие попытки как раз и будут. Приложение вызвало syscall, далее поток работает в ядре и лезет куда-то в структуры примонтированной ФС. Они общие для всех? Сколько ещё других приложений делают тот же syscall - неизвестно.

>[оверквотинг удален]
> 1. А в ядре никто и не использует std. Под ядро написана
> замена std, которая во многом похожа, но всё же заметно различается,
> например Vec::new() возвращает Result<Vec, _>, а не Vec. Я не разглядывал
> её, но подозреваю что все эти разговоры про Rc и Arc
> туда слабо применимы, потому что в ядре очень востребованы обёртки над
> сишными типами с рефкаунтами, и для создания таких обёрток Rc и
> Arc бесполезны.
> 2. Если в ядре нет кучи, то нет никакого смысла говорить про
> shared_ptr, use-after-free, и пр. Когда троллишь, следи за толщиной, потому что
> тут ты явно перебрал.

Я использовал в ядре умные указатели, потому и говорю об этом. placement new не нужна куча. Вопрос в том, как именно реализовать shared_ptr - на двусвязном списке, со счётчиком ссылок или придумать что-то с lock-free.

>> То есть выбор сводится к:
>> 1. Написать заведомо невалидируемый код.
>> 2. Висеть в примитивах синхронизации, как и в наивной реализации std::shared_ptr.
> Да, он в C++ сводится к тому же, если код пишет вменяемый
> программист. Потому что мутабельный конкуретный доступ к данным -- это гарантия
> получить пачку дата-рейсов. Бывают иногда ситуации, когда разумные люди на это
> идут сознательно, но простите в таких случаях они пишут на ассемблере,
> выверяя чёткую последовательность команд для каждой конкретной архитектуры. На C/C++/Rust
> нельзя полагаться в этих ситуациях, потому что те когда оптимизируют творят
> такую хрень, что чёткую последовательность команд получиться не удастся никак.

Можно ставить барьер.

> Подход раста в этом отношении отличается от подхода C++ только тем, что
> он не позволяет неразумным программистам организовать датарейс несознательно. Неразумный
> споткнётся об ошибки компиляции, которые он может одолеть при помощи unsafe,
> но это, простите, уже случай сознательного и целенаправленного создания датарейса. Никакие
> аппеляции к бритве Хэнлона не позволят ему отмазаться после такого.

Так вот проблема в том, что неразумным программистам в ядре делать вообще нечего, кроме как что-то сломать. С одной стороны Rust - это хорошо, а с другой, хорошо бы как-то отсеять неразумных. Когда Линус называл программистов на плюсах нетолерантным словом, он как раз это и делал.

Ответить | Правка | Наверх | Cообщить модератору

150. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 03-Апр-24, 15:40 
> Такие попытки как раз и будут. Приложение вызвало syscall, далее поток работает в ядре и лезет куда-то в структуры примонтированной ФС. Они общие для всех? Сколько ещё других приложений делают тот же syscall - неизвестно.

Представь себе ситуацию:

let global_structures = Mutex::new(GlobalStructures::new());

Если твой обработчик сделал:

if let Ok(gs) = global_structures.lock() {
    // то здесь у него есть эксклюзивный доступ к этим структурам через gs
}

Подобный подход наверное не очень хорош, когда речь идёт о файловой системе, но файловая система это лишь один из возможных примеров. А если ты уже получив гарантии эксклюзивности доступа будешь использовать атомарный Arc, вместо Rc, то тебе наплевать на производительность щтоле?

> placement new не нужна куча.

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

Но для ясности, давай заменим слово "куча" на динамический аллокатор памяти, будь он кучей, ареной, или чем ещё.

> Можно ставить барьер.

Как один из способов, да.

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

Это наивный идеализм, закрывающий глаза на реальное положение дел, при котором неразумные программисты встречаются везде. В частности потому, что ряд задач решаемых программистом упираются в проблему останова, и поэтому сколько бы он не думал о коде, он никогда не может быть уверен в том, что код безбажен. Программисты выходят из этой ситуации накладывая ограничения на код, так чтобы проблемы останова не возникало, чтобы можно было бы доказать про код его безбажность (пускай и неформальной логикой), но эти ограничения отличаются тем, что они вовсе не очевидны по коду, нет способа получить для каждой строки кода список действий запрещённых для этой строки. В таких условиях 100% разумным может быть только Бог, потому что только он всеведущий.

> хорошо бы как-то отсеять неразумных

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

Ответить | Правка | Наверх | Cообщить модератору

153. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от n00by (ok), 03-Апр-24, 19:39 
>[оверквотинг удален]
> let global_structures = Mutex::new(GlobalStructures::new());
> Если твой обработчик сделал:
> if let Ok(gs) = global_structures.lock() {
>     // то здесь у него есть эксклюзивный доступ
> к этим структурам через gs
> }
> Подобный подход наверное не очень хорош, когда речь идёт о файловой системе,
> но файловая система это лишь один из возможных примеров. А если
> ты уже получив гарантии эксклюзивности доступа будешь использовать атомарный Arc, вместо
> Rc, то тебе наплевать на производительность щтоле?

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

>> placement new не нужна куча.
> А, ты хвастаться знаниями пришёл и докапываешься к словам, ожидая когда я
> начну комплименты твоему интеллекту и познаниям отпускать? Ты очень умный. И
> много знаешь. Молодей чувак, круто.
> Но для ясности, давай заменим слово "куча" на динамический аллокатор памяти, будь
> он кучей, ареной, или чем ещё.

Мне пока не ясно, зачем вообще аллокатор. На этом "ещё чём" хранится счётчик ссылок и голый указатель на объект? Или объект рядом со счётчиком ссылок? Для shared_ptr такая реализация не обязательна.

>[оверквотинг удален]
> программисты встречаются везде. В частности потому, что ряд задач решаемых программистом
> упираются в проблему останова, и поэтому сколько бы он не думал
> о коде, он никогда не может быть уверен в том, что
> код безбажен. Программисты выходят из этой ситуации накладывая ограничения на код,
> так чтобы проблемы останова не возникало, чтобы можно было бы доказать
> про код его безбажность (пускай и неформальной логикой), но эти ограничения
> отличаются тем, что они вовсе не очевидны по коду, нет способа
> получить для каждой строки кода список действий запрещённых для этой строки.
> В таких условиях 100% разумным может быть только Бог, потому что
> только он всеведущий.

Реальное положение дел таково, что ядро разрослось и теряется контроль, от чего многие ядерщики вдруг хором заговорили про выгорание, а новых почему-то прибавляется несоизмеримо росту сложности мало. Например, потому что Си вышел из моды в прошлом веке. Этот вопрос принялись решать вполне понятным способом - привлечь свежие силы модным языком. На какое-то время это даст видимый подъём, но далее выгорание у первых ускорится, и учить окажется некому. Это пессимистичный сценарий, но вероятный. Может быть, там дальше в планах появление перспективного ученика самого Линуса со словами "смотрите, я тут переписал ключевые подсистемы на Rust", что спасёт положение.

>> хорошо бы как-то отсеять неразумных
> Это контрпродуктивно, потому что единственный долгосрочно работающий способ получать
> разумных программистов, это брать неразумных и воспитывать в них разум. Надеясь
> на то, что они сами наплодятся и придут тебе помогать, ты
> рискуешь остаться один. Рано или поздно ты останешься один, последним из
> могикан.

Так это надо на Си учить писать и бить по рукам линейкой, что ли? Вон в новости прилетела очередная. А народ говорит, давайте её уберём. Или есть, кому учить на Rust? Из Redox перетянули людей?

Ответить | Правка | Наверх | Cообщить модератору

141. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 02-Апр-24, 19:44 
> В частном хватает std::shared_ptr<>.

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

Если первое, то там оно не решается при помощи shared_ptr. Там память была освобождена, но не была отмаплена.

Если второе, то да, иногда shared_ptr помогает, а иногда оказывается таким тормозом, постоянно сбрасывая кеши, то лучше бы его и не было.

> А Rust что делает? unique_ptr выполняет на этапе компиляции

Неее... В расте есть аналог shared_ptr -- то ли Rc, то ли Arc, я не уверен, не знаю как себя shared_ptr ведёт в многопоточном окружении. Но вот аналога unique_ptr в расте нет. Есть что-то похожее на это, но это только если смотреть жопой и с большого расстояния.

Если тип не Copy (что дефолтом вешается на новые типы), то он как бы позволяет иметь не больше одного mutable указателя на значение. Во всяком случае, если верить маркетингу. Реально ситуация сложнее, глянь на код:

fn foo(v_foo: &mut Vec) { ... }
fn bar(v_bar: &mut Vec) { foo(v_bar); }
fn main() {
    let mut v = Vec::new();
    bar(&mut v);
}

Когда на стеке оказывается стековый фрейм foo, одновременно существуют три указателя на этот несчастный Vec. Точнее в main он как бы и не указатель вовсе, он присутствует значением (в отличие от unique_ptr, который именно что ptr), но тем не менее это мутабельная переменная позволяющая менять Vec, и в стековых фреймах foo и bar в каждом по мутабельному указателю. Три мутабельных ссылки на одно значение!

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

Ещё пачка отличий unique_ptr от положения дел в расте вызвана тем, что в расте move'ы просчитываются статически, в C++ они насквозь динамичны, они по-определению shallow copy, и хрен заставишь оптимизатор выкинуть все эти ненужные копирования.

Ответить | Правка | К родителю #112 | Наверх | Cообщить модератору

147. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от n00by (ok), 03-Апр-24, 12:23 
>>> Но найти все указатели хранящие данный адрес в общем случае может только
>>> сборщик мусора.
>> В частном хватает std::shared_ptr<>.
> Ты сейчас говоришь про случай описанный в новости, или просто произносишь общую
> фразу о том, что иногда все эти сложности решаются при помощи
> shared_ptr?

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

> Если первое, то там оно не решается при помощи shared_ptr. Там память
> была освобождена, но не была отмаплена.

Значит решается другим частным случаем RAII, где освобождение всех ресурсов происходит в одной точке?

> Если второе, то да, иногда shared_ptr помогает, а иногда оказывается таким тормозом,
> постоянно сбрасывая кеши, то лучше бы его и не было.

Это понятно, особенно если он внутри косвенный и с подсчётом ссылок (что не является единственно возможной реализацией).

>> А Rust что делает? unique_ptr выполняет на этапе компиляции
> Неее... В расте есть аналог shared_ptr -- то ли Rc, то ли
> Arc, я не уверен, не знаю как себя shared_ptr ведёт в
> многопоточном окружении.

Arc, судя по соседней ветке, точно так же тормозит как и shared_ptr. Как его вообще можно сделать, что бы не тормозил?)

> Но вот аналога unique_ptr в расте нет. Есть что-то
> похожее на это, но это только если смотреть жопой и с
> большого расстояния.

Его там и не должно быть, насколько понимаю гарантии с передачей владения. Грубо говоря, unique_ptr засунули в borrow checker.

>[оверквотинг удален]
> fn main() {
>     let mut v = Vec::new();
>     bar(&mut v);
> }
> Когда на стеке оказывается стековый фрейм foo, одновременно существуют три указателя на
> этот несчастный Vec. Точнее в main он как бы и не
> указатель вовсе, он присутствует значением (в отличие от unique_ptr, который именно
> что ptr), но тем не менее это мутабельная переменная позволяющая менять
> Vec, и в стековых фреймах foo и bar в каждом по
> мутабельному указателю. Три мутабельных ссылки на одно значение!

Это без оптимизации. С оптимизацией bar() в принципе должна исчезнуть.

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

Маркетингу стоит добавить бззворды типа control flow и data flow.)

> Ещё пачка отличий unique_ptr от положения дел в расте вызвана тем, что
> в расте move'ы просчитываются статически, в C++ они насквозь динамичны, они
> по-определению shallow copy, и хрен заставишь оптимизатор выкинуть все эти ненужные
> копирования.

В аналогичном варианте с std::vector оптимизатор плюсов всё выкидывал ещё во времена MSVC 7-й версии, но иногда приходилось его пинать и писать __forceinline.

Ответить | Правка | Наверх | Cообщить модератору

151. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (-), 03-Апр-24, 16:12 
>> Если первое, то там оно не решается при помощи shared_ptr. Там память
>> была освобождена, но не была отмаплена.
> Значит решается другим частным случаем RAII, где освобождение всех ресурсов происходит в одной точке?

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

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

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

> Это без оптимизации. С оптимизацией bar() в принципе должна исчезнуть.

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

> Маркетингу стоит добавить бззворды типа control flow и data flow.)

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

> В аналогичном варианте с std::vector оптимизатор плюсов всё выкидывал ещё во времена MSVC 7-й версии, но иногда приходилось его пинать и писать __forceinline.

Я тут связался с C++ кодом, и чёт меня дёрнуло builder pattern присобачить. Типа:

let mytype = MyType::builder()
   .size(42)
   .color(Color::Green)
   .kind(Engine::Diesel)
   .build();

Я до сих пор не уверен, что мне удалось избавиться от _всех_ семантически подразумеваемых shallow copy всех мувов. Я поленился отдельный минимальный пример создавать, и поэтому приходилось продираться через наслоения asm'а, и вроде я избавился от большинства копирований, но у меня там флаг был в одной структуре и (согласно комментам -fverbose-asm) в него значение клалось дважды.

move-конструктор в C++ получает ДВА указателя, и работает с обоими. Чтобы эти копии выкинуть, оптимизатор должен быть в состоянии отследить весь контрол-флоу, понять что память из под старого значения не используется больше, вернутся назад и повторно использовать память. И из-за этого невозможно просто присунуть в деструктор отладочную печать, и потом считать сколько раз деструктор вызывается, потому что наличие отладочной печати показывает оптимизатору, что память используется потом, и он не оптимизирует. Арггх, я ненавижу C++, его идея смешивать семантику с оптимизациями -- это просто слов у меня нет для описания идиотизма тех, кто это придумал. Они явно на каких-то тяжёлых веществах сидели в этот момент.

Ответить | Правка | Наверх | Cообщить модератору

152. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от n00by (ok), 03-Апр-24, 18:46 
>[оверквотинг удален]
> в любой реализации кучи, которая отдельно следит за маппингом памяти, отдельно
> за занятыми виртуальными адресами.
> В данном частном случае, я отмечу, всё было сделано так, что в
> момент, когда страницы надо было анмапить, было невозможно решить надо ли
> анмапить или не надо, потому что владельцем этих страниц мог быть
> юзерспейс, если он мапил, или кернелспейс, если мапил он.
> То есть в ядре было понятно, что можно (и нужно) реклаймить виртуальную
> память из-под буферов и помечать свободной, а вот что делать с
> физической памятью уже было не ясно, потому что ключевая для принятия
> решения информация была утеряна к тому моменту.

Вот эту последнюю проблему и решает RAII. Всё освобождается в одном месте - деструкторе (а что именно освобождается - это вообще дело десятое). Но может так оказаться, что всё это затруднительно завернуть в одну обёртку. Потому что архитектуру проектировали под язык Си и без расчёта на такое. То есть я веду вовсе не к тому, что плюсы чудесным образом смогут гарантировать отсутствие ошибок. А к тому, что ради возможности обеспечения таких гарантий придётся переписывать вообще всё. И это язык очень близкий к Си технически, но вот такой нюанс немножко всё портит. Я не знаю, насколько верно из этого частного случая индуцировать обобщение на Rust, но оптимизма по этому поводу у меня нет. Особенно после того как местные знатоки языка честно признаются "а как в ядре, я не знаю".

>> Это без оптимизации. С оптимизацией bar() в принципе должна исчезнуть.
> Может исчезнуть, но может и нет. В данном примере код написан так,
> что он заинлайнится. Но не весь код инлайнится. Плюс оптимизации --
> это оптимизации, они не меняют семантики, а семантически есть промежуток времени
> выполнения, когда три валидные мутабельные ссылки мирно сосуществуют.

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

>[оверквотинг удален]
> move-конструктор в C++ получает ДВА указателя, и работает с обоими. Чтобы эти
> копии выкинуть, оптимизатор должен быть в состоянии отследить весь контрол-флоу, понять
> что память из под старого значения не используется больше, вернутся назад
> и повторно использовать память. И из-за этого невозможно просто присунуть в
> деструктор отладочную печать, и потом считать сколько раз деструктор вызывается, потому
> что наличие отладочной печати показывает оптимизатору, что память используется потом,
> и он не оптимизирует. Арггх, я ненавижу C++, его идея смешивать
> семантику с оптимизациями -- это просто слов у меня нет для
> описания идиотизма тех, кто это придумал. Они явно на каких-то тяжёлых
> веществах сидели в этот момент.

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

Ответить | Правка | Наверх | Cообщить модератору

103. "Уязвимость в подсистеме io_uring, позволяющая получить приви..."  +/
Сообщение от Аноним (103), 02-Апр-24, 00:16 
Шутите? Это вина только языка. Язык такие вещи должен как минимум предотвращать, как максимум не требовать. А C - это по современным меркам и не яп вовсе.
Ответить | Правка | К родителю #19 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру