LINUX.ORG.RU

В C++ добавят Rust

 , , ,


2

4

Привет, ЛОР! Я тебе покушать принёс.

Опубликован черновик расширения Safe C++, представляющего собой надмножество языка с возможностью отключать в коде Undefined Behaviour и прочие небезопасные штуки. Safe C++ добавляет в язык также borrow checker, pattern matching и другие функции, знакомые и любимые программистами на Rust. unsafe блоки входят в комплект.

Пример кода:

#feature on safety
#include <std2.h>

int main() safe {
  std2::vector<int> vec { 11, 15, 20 };

  for(int x : vec) {
    // Ill-formed. mutate of vec invalidates iterator in ranged-for.
    if(x % 2)
      mut vec.push_back(x);

    std2::println(x);
  }
}

Ошибка при сборке этого кода:

$ circle iterator.cxx -I ../libsafecxx/single-header/
safety: during safety checking of int main() safe
  borrow checking: iterator.cxx:10:11
        mut vec.push_back(x);
            ^
  mutable borrow of vec between its shared borrow and its use
  loan created at iterator.cxx:7:15
    for(int x : vec) {

Чтение за пределами обычных массивов также станет невозможным:

#feature on safety
#include <cstdint>

int main() safe {
  int array[4] { 1, 2, 3, 4 };
  size_t index = 10;

  // Panic on out-of-bounds array subscript.
  int x = array[index];
}

Результат:

$ circle subscript_array.cxx
$ ./subscript_array
subscript_array.cxx:9:17
int main() safe
subscript is out-of-range of type int[4]
Aborted (core dumped)

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

Ссылка: https://safecpp.org/draft.html

★★★★★

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

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

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

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

Индекс проверять надо если программист решил что тут есть шанс того, что он окажется некорректным. Проверять его просто так - не надо, да. А уязвимости не от этого, а от некомпетентных программистов, но их лучше к Си вообще не подпускать и давать им пхп-подобные языки, где даже после жёсткого бага в логике (а не какой-то там индекс) есть шанс продолжить работу относительно адекватно.

Зато на ламповых лаптях из 70-х не тормозит.

Опять ты за своё... Ты написал некую функцию и в общем случае не знаешь, как и сколько раз её будут вызывать в т.ч. через 50 лет. Где-то она сделает разницу в требованиях с 100мгц до 1000мгц, где-то - с 1 ядра 3ггц до 10 ядер 3ггц, а где-то - с 50 ядер до 500 ядер. Поэтому надо просто писать так, чтобы требования не раздувались. И тогда тебя не будет проклинать кто-то через десятки лет, когда какой-то незначительный компонент большой программы с твоим кодом внутри станет узким местом т.к. ты не знал что его будут вызывать миллион раз в секунду в каким-то сценарии использования.

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

если программист решил

Бгг, святая наивность. Один решил, а другой через год выше по стеку вызовов не решил и что-то поменял в логике. В итоге твой подход «всё держим в голове» высирает уязвимость.

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

А уязвимости не от этого, а от некомпетентных программистов, но их лучше к Си вообще не подпускать

А где они эти компетентные си программисты водятся? В ядре нет, в юзерспейсе их тоже нет. В сказках и в программах класса hello world?

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

А где они эти компетентные си программисты водятся? В ядре нет, в юзерспейсе их тоже нет.

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

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

Не ври, есть и там и там.

Имён, я так понимаю, не будет? Хорошо, тогда давай я попробую.

Например Тед Цо, мейнтейнер так любимой тобой ext4. На своём сайте он говорит, что

I’ve worked on the Linux kernel since 1991, and am probably the first Linux Kernel developer in North America. I am the maintainer for the ext4 file system, and created the gce-xfstests and kvm-xfstests test appliance system which automates testing the Linux kernel’s file systems.

Самый что ни на есть дедовский дед. Он у тебя в каком списке? Компетентный или нет? Потому что например в 2013 году он закоммитил вот такую портянку.

Через 9 лет (2022 год) тысячи глаз наконец-то рассмотрели там уязвимость CVE-2022-1184.

Которую смогли исправить только со второй попытки: первая вторая.

ext4: check if directory block is within i_size

Бгг. Видимо Теодорчик решил, что в его коде всё within, ведь "индекс проверять надо если программист решил что тут есть шанс того, что он окажется некорректным", а оказалось, что не within. Это какое-то шанс-ориентированное программирование. Сишник к успеху шёл, не получилось, не фартануло.

Ещё список уязвимостей в ext4 от анонима с opennet:

CVE-2023-2513 use-after-free - allow a privileged local user to cause a system crash
CVE-2024-0775 use-after-free - user to cause an information leak problem while freeing the old quota file names
CVE-2024-43828 integer overflow - may happen causing an infinite loop in this function, easily reproducible using fstest generic/039.
CVE-2018-10880 - stack-out-of-bounds write - cause a system crash and a denial of service.

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

Имён, я так понимаю, не будет? Хорошо, тогда давай я попробую.

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

Например Тед Цо, мейнтейнер так любимой тобой ext4

Я не знаю его и я не говорил что ext4 моя любимая фс. Ну, судя по описанному тобой у него есть проблемы.

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

А уязвимости не от этого, а от некомпетентных программистов, но их лучше к Си вообще не подпускать

А почему компетентные программисты на C не участвуют в написании больших и сложных программ типа браузеров, ядер ОС и т.д.?

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

Теодорчик решил, что в его коде всё within, ведь «индекс проверять надо если программист решил что тут есть шанс того, что он окажется некорректным»

там вроде вообще не про индекс, а про порушенный i_size на диске вроде.

Currently ext4 directory handling code implicitly assumes that the
directory blocks are always within the i_size. In fact ext4_append()
will attempt to allocate next directory block based solely on i_size and
the i_size is then appropriately increased after a successful
allocation.

However, for this to work it requires i_size to be correct...

но если на диске (или в памяти?) рушатся данные, то ничто уже не спасет.

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

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

70% дыр в сишноплюсовом коде – это вот такая ошибка. Т.е. запись за границу массива. Других плюсистов до сих пор не вывели, хотя селекционеры стараются уже лет 30. Дарвина на них нет!

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

порушенный i_size на диске вроде

Т.е. если badblock попадёт на i_size и из-за этого прочитается мусор, то файловая система начнёт руинить всё остальное, даже не затронутое badblock’ом?

но если на диске (или в памяти?) рушатся данные, то ничто уже не спасет.

В памяти да, а на диске нет. Если я воткну в компьютер флешку с испорченной ext4, то драйвер не должен слепо доверять данным с флешки и идти переписывать память ядра, потому что считал неправильный i_size и не проверил его.

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

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

ну вот увидели люди, что некий инвариант ТЕОРЕТИЧЕСКИ может не выполняться. и просто огородили это место проверкой.

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

Ну я например компетентный.

Рад за тебя. Уверенность в себе это важно. Вопросов больше не имею.

Я не знаю его и я не говорил что ext4 моя любимая фс.

Поиск по ext4 в твоих сообщениях на лоре говорит об обратном. Ты её постоянно рекомендуешь.

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

одно современное ядро на 100мгц как бы не быстрее 4 старых по 3ггц

Ээээ.. нет. Ну то есть, вообще нет. Плюс, современные процы ниже 400-600МГц не тормозятся, я пытался.

Но @firkax всё равно гонит. C++ не спасает от оверхеда, хотя бы потому что здоровая часть оверхеда написана на этом самом C++ (и C). Доказано хромогом. Тормозы UI у нас сейчас во многом из-за дикого количества кода в фреймворках и в необходимости в десятках переключений контекста в ядро, потому что даже отрисовка сраного калькулятора на GTK требует граф.ускорения.

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

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

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

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

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

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

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

Типичная сишная шизофрения.

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

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

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

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

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

70% дыр в сишноплюсовом коде – это вот такая ошибка. Т.е. запись за границу массива.

Безотносительно ущербности Си, C++, криворукости сишников и сиплюсплюсников, но ведь выбор же простой:

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

Как бы из областей, где производительность не важна, Си и C++ уже давно выперли (и хвала небесам за это). Но там, где производительность все еще имеет значение, то какой выход?

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

либо проверки на каждое обращение и тогда прощай производительность,

Чувак, ты современный софт вообще видел? Там нет (неявных) проверок и при этом производительность в полной жопе. То есть, код от современных говнокодеров на C++ от вот этого safecpp медленнее явно не станет, потому что он УЖЕ медленный.

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

Чувак, ты современный софт вообще видел?

Дайте подумать… Ну вот, например, Telegram, Chrome, KDE, gcc, clang, VLC, временами cl из VC++ (еще реже Visual Studio, в которой от C++ мало что осталось), иногда Opera. На ноуте жены еще антивирус Касперского крутится.

Это из общедоступного.

Что из этого и где тормозит? И что можно посмотреть из аналогов не на C++, которые не тормозят.

То есть, код от современных говнокодеров на C++ от вот этого safecpp медленнее явно не станет, потому что он УЖЕ медленный.

Ну как бы хотелось примеров. Типа вот здесь наговнокодили на C++ и оно тормозит, а вот здесь сделали тоже самое на Java с проверками и оно летает.

Тем не менее, я бы хотел услышать ответ на свой вопрос. Ничего внятного вы пока не сказали.

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

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

Например?

Мне вот сходу вспоминаются range for, который позволяет обойтись без индексов или итераторов. Ну и новые ranges из C++20, в которых можно написать: std::ranges::sort(container) вместо std::sort(container.begin(), container.end()). При том, что C++20 еще далеко не во всех проектах разрешено использовать.

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

вот этих двух мало, что ли?

Давайте конкретно с цифрами и примерами, мол, вот в Chrome на C++ имеем вот такие показатели, а в X на Java/C#/OCaml/Haskell/whatever – вот такие.

Аналогично и про KDE. А то я года три или четыре как перешел с Gnome на KDE и не могу припомнить, чтобы Gnome летал. Или чтобы Windows летал (хотя Windows тоже на C++, да).

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

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

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

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

Но firkax всё равно гонит
C++ не спасает от оверхеда

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

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

Руст не упадёт на выходе за границу массива в оперативной памяти, я так понимаю. То есть корректно оно работать не будет, но по крайней мере не запорет тебе тайком ещё что-то.

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

Сравни KDE6 и KDE2. Ну или запусти свежий KDE на ляптопе 10-летней давности. Результат тебе не понравится. Кстати, Cosmic, который на Rust, довольно скоростной пока что.

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

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

Руст не упадёт на выходе за границу массива

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

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

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

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

на самом деле это значит - «объявляется константный указатель на int». и потому ты не сможешь присвоить один массив другому автоматом, через выражение a = b. а будешь ручками копировать массив.

то, что в других языках объявляется как «встроенный массив», это std::array в с++.

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

на самом деле это значит - «объявляется константный указатель на int». и потому ты не сможешь присвоить один массив другому автоматом, через выражение a = b. а будешь ручками копировать массив.

Какими ручками? В C++ есть std::copy, который применим для вообще всего.

  int a[4] { 1,2,3,4 };
  int b[4];

  std::copy(std::begin(a), std::end(a), std::begin(b));

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

int f(int sz, int a[restrict sz]) {
  ...
}

Указатель? Или таки массив?

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

int f(int sz, int a[restrict sz]) {

что такое тут restrict? это какой язык? я говорю про с++

если писать там явный массив навроде ff(int a[10]) - то будет указатель пихаться на стек (ну или в регистр), при вызове ff.

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

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

что такое тут restrict? это какой язык? я говорю про с++

Это C. Напомню, парой комментов выше ты писал:

в си и плюсах вообще нет массива. нет такого типа.

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

А лол да, я тупанул под вечер уже :DD

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

Ну или запусти свежий KDE на ляптопе 10-летней давности.

У меня в офисе старый ноутбук на 2-ядерном Intel Pentium 1.4Ghz с 4GiB RAM. Он был откровенно дохлым еще в 2012-ом году, когда я его покупал в качестве дешевой «печатной машинки» для командировок. Сейчас регулярно использую его для прослушивания музыки.

На днях обновил Kubuntu с 22.04 до 24.04. Полет нормальный.

То, что нативное и на C или C++ (типа tar, 7z, konsole, kate, okular, vlc и даже Chrome) работает нормально и отзывчиво. Там где под Qt-шной мордой спрятан какой-нибудь Python или JavaScript, там да, тормозит. Но, рискну предположить, не C++ в этом виноват.

Я тут о том пишу, что в мире C++ всё плохо и добавив немного безопасности хуже явно уже не сделать.

Ну и выглядит написанное вами как откровенная херня.

Сейчас нет смысла писать на C++, если нет задачи экономить память и выжимать максимум производительности. А если уж C++ взяли (предполагаем, что это был разумный выбор, а не «я больше ничего не знаю» или «а мне C++ просто нравится»), то навешивать на себя стоимость проверки при каждом обращении к массиву во время обработки больших объемов данных… Ну такое себе.

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

Сейчас нет смысла писать на C++, если нет задачи экономить память и выжимать максимум производительности.

Берут и пишут, и что ты сделаешь, кексперт?

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

Сейчас нет смысла писать на C++, если нет задачи экономить память …

Ради эксперимента написал мелкое консольное приложение «таймер» на c++ и lua. Реализация на lua использует меньше памяти по показаниям htop.

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

Выигрывает по всем (трём) типам памяти: virt, rss, shared.

Основной источник расхода памяти - стандартная библиотека с iostream, string, container, которые дополнительно тянут exceptions, rtti и тп. А если еще с++20 с ranges подтянуть…

Если их убрать и писать на Си с метапрограммированием, то можно сравняться.

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

anonymous
()