The OpenNET Project / Index page

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



Индекс форумов
Составление сообщения

Исходное сообщение
"Уязвимость в механизме ucount ядра Linux, позволяющая повыси..."
Отправлено Ordu, 31-Янв-22 14:07 
Там же только uniq_ptr и shared_ptr, причём со всеми граблями C++'овых аналогов, типа "никаких гарантий". Например, uniq_ptr может быть NULL, то есть просто взять и разадресовать его, не проверяя на NULL -- это лишь до первого бага, который положит NULL туда, где NULL быть не должно.

Более того, насколько я вижу, эти указатели реализованы на _рантайм_ проверках, и более того эти рантайм проверки должны выполняться клиентским кодом. То есть, не, он может не проверять, и в случае ошибки в коде получит в рантайме разадресацию NULL с вытекающим из неё сегфолтом. Это _динамическая_ типизация в статически типизированном языке. В C++ тоже с этим проблемы вылезают[1]. Более того, если присмотреться[2], то проблема вытекает из свойств C и C++, которые делают невозможной move-семантику с compile-time проверками на то, что значение было перемещено, и поэтому программист, реализуя move constructor _вынужден_ обеспечивать своему типу специальное значение, которое семантически можно описать фразой "value was moved out, nothing to see here, go away", чтобы это значение можно было бы проверить в рантайме. А это означает, что uniq_ptr будет by design иметь значение NULL, и значит что если разадресовывая его ты забыл проверить на NULL, то значит ССЗБ.

[1] https://alexgaynor.net/2019/apr/21/modern-c++-wont-save-us/
[2] https://www.thecodedmessage.com/posts/cpp-move/

И это фундаментальная проблема, которая делает "умные" указатели бессмысленными в C и C++. Они не столько предотвращают ошибки, сколько снимают часть бойлерплейта, необходимого для того, чтобы избежать ошибок, и таким образом заметают потенциальные проблемы под ковёр, делают их менее заметными. Именно поэтому в ядре использовать uniq_ptr невозможно: в ядре всё в принципе по-возможности делается явным, чтобы было видно что происходит. Ядро пишется на C, и идеология написания кода ядра заточена под C: на компилятор нельзя полагаться, можно полагаться только на себя. Чтобы понять это, я могу порекомендовать Торвальдса, кормящего C++ тролля[3], где его ключевой тезис сводится к:

C++ leads to really really bad design choices. You invariably start using
the "nice" library features of the language like STL and Boost and other
total and utter crap, that may "help" you program, but causes:

- infinite amounts of pain when they don't work (and anybody who tells me
   that STL and especially Boost are stable and portable is just so full
   of BS that it's not even funny)

- inefficient abstracted programming models where two years down the road
   you notice that some abstraction wasn't very efficient, but now all
   your code depends on all the nice object models around it, and you
   cannot fix it without rewriting your app.

[3] https://harmful.cat-v.org/software/c++/linus

То есть всё сводится к тому, что пока C++ подход работает, всё хорошо, но когда он не работает, ты впарываешься в infinite amounts of pain и в rewriting your app. А подход C++ не работает довольно часто, потому что он не устраняет ни одной проблемы C, он лишь декорирует их кружевами, позволяя в 90% случаев делать вид, что это не баг, а фича. Но в оставшихся 10% тебя ждут те самые infinite amounts of pain. И смарт-поинтеры, реализованные в C, не нужны в ядре по той же самой причине. Они не снимают ни одной проблемы: тебе точно так же придётся своими глазами следить за тем, чтобы не разадресовать нечаянно указатель, который был куда-то перемещён. Сама операция перемещения dst←src, с последующим обнулением src, будет чуть проще записываться, но следить за тем, чтобы не обращаться к src после перемещения ты точно так же будешь глазами. А каждый твой фейл будет приводить к рантайм краху. Это не делает программирование проще: проследить глазами за обнулением src проще, чем за тем, чтобы он потом не использовался.

А если пытаться сделать всё хорошо и статически проверять все эти uniq_ptr, дабы не выносить проверки в рантайм, то:
> if you try to statically detect such situations, you end up with Rust.[4]

[4] https://www.foonathan.net/2017/09/destructive-move/

Упс. И статические анализаторы не спасут C и C++, потому что эти языки не кодируют в своих API тех допущений, которые необходимы этим API для работы. Теоретически можно было бы API дополнять комментами (примерно как в некоторых динамических языках запиливают статическую типизацию, описывая типы в комментах), но хмм... я не уверен, что это сработает. Теоретически -- да, должно быть возможно, но практически, мы получим две одновременно действующие системы типов, и я подозреваю, это кончится таким уродством и ногу-сломишь-в-этом-коде, что нахрен никому не нужно. Проще лишнюю рантайм проверку вставить, и выкинуть панику если NULL оказался там, где его быть не должно.

 

Ваше сообщение
Имя*:
EMail:
Для отправки ответов на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
  Введите код, изображенный на картинке: КОД
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



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

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