Pull to refresh

Comments 165

Да и реверсить C/C++ сложнее описанных, зачем АНБ лишняя работа ))

Ващет си реверсить не сложно. Плюсы сложнее, да.

Все относительно, в ручную C реверсить условно не сложно, но на объеме дорого. А автоматизировать этот процесс (транслировать машинный код в псевдокод) довольно сложно, хотя бы из за большого количества компиляторов помноженное на разные их версий и опций оптимизации. Под другие языки вариаций сильно меньше из за чего есть обилие инструментов для реверса. Ruby вообще интерпретируемый, а например в Go очень сложно избавиться от всей отладочной информации.

А автоматизировать этот процесс (транслировать машинный код в псевдокод) довольно сложно

Может и сложно, но автоматизировали-таки. Проблемы в декомпиляции бывают даже с высокоуровневой Java, но они вполне решаемы.

В Расте тоже самое все и оптимизации и разные версии компилятора, которые портят ранее созданые сигнатуры. И все по новой.

Даже с -lto? Порой один цикл на С может породить гору кода. Версионирование тела, для учитывания выравнивания или инвариантного условия, пиллинг, отдельный остаток при векторизайции. А потом все замешаем, заинлайним насквозь и выкинем всю информацию о типах. Ну отлично ж реверсится.

Я говорю о нормальных случаях, а не о больной одержимости

Пореверьсте пожалуйста стрипнутый раст, и потом расскажите как вам понравилось)

Раст — цветочки после хаскеля. Скомпилированная ленивость выглядит ну очень неприятно.

А как именно выглядит, хотя бы в двух словах? Интересно.

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

Как раз ковырять и модифицировать написанное на Си — легко и удобно (без всяких шуток). С++ посложнее но тоже можно

Помимо безопасности еще существует проблема производительности, так что кресты будут всегда)

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

Хорошая попытка, но мы ещё не успели забыть log4shell, text4shell в супер-безопасной java

Статью не читай @ беги комментировать

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

Неверно. Я хотел подчеркнуть, что и кроме проблем с памятью хватает и прочих, гораздо более опасных проблем.
С ошибками памяти бороться уже научились, причем вполне эффективно. Это W^X, стековые канарейки, рандомизацич АП, рандомизация кучи, ксорка указателей блоков в куче (препятствие перезаписи), CFI, анти ROP/JOP приемы, подпись указателей, и т.д. В сухом остатке, даже если баг есть, в очень большом % случаев (99% ?) его эксплуатация невозможна.

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

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

например, в веб-движках основной косяк как раз в логических ошибках, типа можно вызвать какой-нить скрипт с нужным параметром без авторизации или прочитать файл, например. Там никакие типы не помогут, это чисто косяк архитектора. И по количеству взломов такие косяки могут перетянуть всю статистику на себя.
Другое дело, что АНБ не беспкоит дырявый вордпресс, его беспокоит, то даже новые информационные системы для бизнеса и органов власти пишутся на инструменте, который легко позволяет выстрелить себе в ногу. А человек слаб: "там шпионки с крепким телом, ты их в дверь, они в окно" - чуть расслабился и вот уже у тебя к коде сложнообнаруживаемый RCE. Попробуй устроить RCE в голанге или жабе, да это прям целенаправленно нужно работать в этом направлении. А на плюсах, это просто моргнуть.
Анб не может написать петицию: вот так и так делайте и у вас не будет логических ошибок, потому что они не в курсе такой методологии, и никто не в курсе. Продвинутые системы типов, это маленький кейс огромного поля возможных вариантов логических ошибок. А вот продвигать "не используйте методолгию "пистолет-нога"" это разумно. Хороший пример меча и кинжала с логическими ошибками это обход авторизации цифровой или узорной авторизации и отвязка андроида от аккаунта владельца. там драма в 100500 частях, недавно статья на хабре была, как чувак через смену симки новый андроид пофакал, по слухам ему дали бочку варенья и корзину печенья.

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

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

> очень печально (хотя и ожидаемо), что всякие эти АНБ про них не упоминают

за последние 5 лет nsa выпустила порядка 300 документов этого типа (только открытых), чтобы совсем печаль развеять оформляйте CAC,

см https://www.cac.mil/

С ошибками памяти бороться уже научились, причем вполне эффективно

То-то приличная доля уязвимостей — особенно с RCE — до сих пор растёт из нативного кода.

Формально RCE, а по-факту нифига

А какое отношение баги в библиотеках имеют отношение к языку? В библиотеках для плюсов что-ли их нет?

Наверное такое, что это не ошибка памяти, да ещё и язык безопасный ?

Это всё библиотеки и фреймворки, и понятное дело у них свои болячки. Кто-то может выбрать другую либу для логирования, ту же java.util.logging, где, вроде как, проблем пока не особо нашли.

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

Хотя в конечном счёте, это всё напускное и c++ вряд ли кто-то заменит учитывая объемы кода, которые уже написали на нём.

Вроде бы все логично, но когда такое говорит АНБ США начинаешь искать в чем подвох и где тебя ... обманули)))

Наверное у них есть знание, где протекают «безопасные» языки у «кривых» программистов. :)

Думаю, у них есть понимание, что у "безопасных" языков ниже порог входа и требования к уровню квалификации программистов, что играет АНБ на руку.

У Си порог входа явно ниже, чем у Раста.

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

Можете показвть какие программы на Си собираемые из исходников с Github на железе пользователя — этому подвержены?

Просто в АНБ закончились люди, которые умеют в С/С++...

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

А может у них експлоиты уже готовые есть для .net, java машины и т.д., а вот с полностью нативными языками сложна.

А раст почему советуют тогда?

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

Нет там вм и сборщика мусора.

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

а раст разве не встраивает свою вм в бинарь как и go ?

Go не "встраивает свою вм" в бинарь, у Go нет никакой VM. Go генерирует нативный код (который включает в себя код сборщика мусора и диспетчера корутин).

если есть сборщик мусора значит уже вместе с вашим кодом в бинаре есть и код от раста.

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

Рекомендации АНБ пишутся в первую очередь для правительственных учреждений США. Не думаю что они хотят стрелять себе в ногу.
Так же хочу напомнить про прекрасную историю с S-boxes в алгоритме DES: https://en.wikipedia.org/wiki/Data_Encryption_Standard#NSA's_involvement_in_the_design

Если кратко, то АНБ предложили свою версию таблицы перестановок, которая была надежнее чем то что выбрали авторы алгоритма. А все потому что АНБ уже тогда знало о дифференциальном криптоанализе (о котором публично напишут только через 15 лет) и выбрала такие таблицы, чтобы шифр был устойчив к этому самому анализу.

Значит хорошие языки, надо брать (с)

Парадоксально, что язык C++, в котором намерениями авторов наворочена огромная и сложная система статического контроля типов с целью обеспечения надёжности кода, по факту оказывается наиболее небезопасным. Кто-то где-то нас дурит.

Никакого парадокса: чем больше и сложнее система, тем проще допустить ошибку при ее использовании

Попробуйте допустить ошибку при использовании агды или кока. Я бы на это с интересом посмотрел.

Даже Ксавье Леруа допускает ошибки, программируя в Коке https://sf.snu.ac.kr/sepcompcert/compcertbugs/. Куда уж нам, простым смертным? Всегда можно накосячить в аксиомах, описывающих предметную область, в данном случае - модель памяти.

Так это ошибка уровня «описали не то, что хотели», а не «запутались во внутренней сложности языка».

Огромная и сложная система статического контроля кода обеспечивает надежность, но разбивается о суровую действительность: примерно половина (и хорошо, если не больше) общепринятых библиотек написана на чистом C (из-за большей универсальности), вдобавок многие разработчики по-прежнему пишут на C++ в стиле "Си с классами", почти не пользуясь мощной системой типов, шаблонами, и умными указателями. Привет, undefined behavior...

мощной системой типов, шаблонами, и умными указателями

вся эта хрень потом не читаема даже для самого создателя программы

Как раз-таки по-нормальному написанная программа на современном C++ гораздо более читаема, чем "С с классами". Как пример, из сегодняшенго stack overflow: реализация питоновской функции title() которая делает первые буквы слов заглавными.

Версия "С с плюсами":

std::string title(const std::string A) {
    char First_capital = static_cast<int>(A[0]) - 32;
    std::string B;
    B = First_capital; 

    for ( int i = 1; i < A.size(); i++){
        if( A[i-1] == ' ' &&  A[i] >= 'a' && A[i] <= 'z') {
            char capital = A[i] - ( 'a' - 'A');
            B += capital;
            continue;
    } else {
        B = B + A[i];
    }
}

И версия "современный С++":

std::string title(const std::string& src)
{
    std::string result(src);
    bool change = true;
    std::for_each(result.begin(), result.end(), [&change](char& c) {
        if (change) {
            c = std::toupper(c);
        }
        change = std::isspace(c);
    });
    return result;
}

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

Так по нормальному в C++ и не получится ибо вариантов тьма:
#include <string>
#include <locale>
#include <iostream>
using namespace std;

wstring capitalize(const wstring &str) {
    wstring res; bool start=true;
    for(auto ch : str) {
        bool is_letter=towupper(ch)!=tolower(ch);
        if (start && is_letter) { ch=towupper(ch); start=false; }
        else if (isspace(ch)) start=true;
        res+=ch;
    }
    return res; 
}

int main() {
    setlocale(LC_CTYPE, "en_US.UTF-8");
    wcout << capitalize(L"óó hello волк") << endl;
    return 0;
}

"С с классами" - это не про не использование (код-1) vs использование (код-2) библиотечных функций.

А про механизмы управления памятью.


А сам код код-1 - явная пародия (ну или 99-й процентиль)

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

Механизмы управления памятью, это безусловно тоже один из таких моментов (но только один!), когда мы вместо того чтобы говорить "как" и когда управлять паматью, просто указываем тип владения памятью, т.е. по сути указываем опять-же "что" мы хотим сделать и забываем об этом.

Код честно взятый со stackoverflow: https://stackoverflow.com/a/66505401/11680056 и там такого я думаю еще много. Конечно это не лучший образец кода, ну так мы и говорим о том как не надо писать.

Мой посыл все-таки сводится больше к тому, что в C и/или "С с классами" мы писали по большому счету "как" что-то сделать, те же циклы обхода контейнеров и т.д. и т.п. А в современном C++ во главу угла ставится подход когда мы пишем "что" должно быть сделано, а компилятор и библиотеки (стандартные и нет) это реализуют наилучшим возможным способом.

А в современном C++ во главу угла ставится подход когда мы пишем "что" должно быть сделано,

Ну это просто не так.
fold \ scan - не является декларативным программированием (даже map \ filter не являются)
А foreach(x.begin(), x.end(), &) - ещё хуже по многим причинам, от уродсва конструкции, до невозможности проконтролировать что там внутри foreach делается.

Так что code-2 выше - обычный императивный от плоти императивного код. Обойди контейнер с начала до конца и сделай: toupper с каждой буквой.
Просто code-1 изуродовали специально (или спецом нашли 99%-ugliness percentile и выставили как чучело)

std::string title(const std::string A) {
	std::string B(A);
	bool change_ahead = true;

	for (int i = 0; i < B.size(); i++) {
		if (change_ahead)
			B[i] = std::toupper(B[i]);
		change_ahead = std::isspace(c);
	}
	return B
} 

А вот такое (если код-1 специально не уродовать) - уже в общем-то мало чем хуже.

В C++ любят закладывать грабли. string.size() имеет тип size_t который может не помещаться в int. Следует писать или auto или size_t (или ptrdiff_t если надо со знаком) или через лямбды (как выше написали) что бы это спрятать под ковёр.
Потому как «Си с классами» более чем достаточен (Если обходить все грабли которые заложили именно в C++)

"Сложная система контроля типов" - это в основном хаскель надо, в плюсах она вообще слабая; а безопасность это в том числе и проверка переполнений и прочей памяти (раст)

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

/me ставит на стол unsafe блок...

Было бы желание, а зафакапить память и на расте можно :)

Никакая навороченная (да и не такая уж она навороченная, на самом деле) система типов не спасет, когда на каждом углу раскиданы undefined behavior и сырые указатели с их арифметикой.

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

Boomburum Модерация первых комментариев явно не работает.

С подключением. Уже минимум несколько лет так. Комменты подтверждают не читая.

Даже если про Путина плохое расскажут?

Слова "Путин" и "плохое" в одном предложении. За вами выехали.

За Вами тоже...

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

Эта некромантия была ошибкой или умышленно сделали?

Так то ошибка, но подобные «ошибки» с подтверждением(публикатором и/или модераторами) сомнительных комментов, частое явление.
С учётом того что автор публикации работает на Хабр, вопросов становится больше.

В комментах опять парад второкурсников? Откуда такая любовь к С/C++? Если вы любите эти языки, то вы либо гений, либо админ 1С. Скорее второе. Так как эти языки достали всех еще в 2000х. Да и не был С++ никогда самым популярным. После С все перешли сразу на С# и Java.

За микроконтроллеры бедные замолвите слово.

Там на С, как правило, шпарят.

На stm32 и аналогах пишут на плюсах. Даже на xmega уже мало кто на чистом С пишет уже лет десять. Другой вопрос, что можно не использовать динамическое выделение памяти и прочие плюшки.

Ну если брать в расчёт Arduino и DIY, прибавить к ним M7 то наверно утверждение будет верно. Проекты для "промышленных применений" на CORTEX 0,3 и даже 4 пока таки больше на С по моим ощущениям. Хотя лично я RTOS на четвёрках уже использую и к плюсам приглядываюсь всё больше. Ходят упорные слухи что компиляторы плюсов всё меньше по размеру скомпилированного кода проигрывают, а использование классов что не говори сильно упрощает читабильность кода и его повторное использование.

Мы периодически делаем изменения в проекте под техасовский DSP примерно 2005 года, и он-таки уже тогда был написан на плюсах. И слава б-гу, что на плюсах, а не на голом С.

Что касается размера кода, то у нас пока не было случая, когда кончалась память программ. Оперативка кончалась, на xmega, например, это вообще легко получить. Но память программ ещё ни разу не заполнялась даже на 50%. А что нужно делать на stm чтоб кончилась память, я вообще не знаю. Видимо специально выбирать модель на 1 рубль дешевле с памятью впритык.

Слава тому же богу что количество программистов не видящих отличий "DSP" от Cortex M0, особенно в случае использование последних скажем в датчиках уровня содержания того или иного газа, выпускаемых если не миллионами, то сотнями тысяч, когда идёт оптимизация с борьбой ,буквально за каждую копейку только растёт.

По крайней мере работы у меня меньше не станет.

Я и под "DSP" писал, и под тинки авровские и под много что. Разумеется, начинал с Z80, так что экономить каждый такт и байт умею. Но надо же понимать, что у всех задачи разные. У одних - сделать максимально дешево миллионы изделий, тогда выбираем одно. У других - сделать мелкосерийно, но быстро, например, и плевать на цену. Или ещё разные другие обстоятельства бывают. Так что я тоже без работы не останусь, могу так, могу эдак, всё могу. Но чот последнее время не очень хочу...

Ну и слава богу. Теперь я и за вас рад.

Главное молодёжь не вводить в заблуждение.

Не холивара ради, Rust вполне успешно заходит в нишу embedded (понятное дело, по количеству библиотек Си ему ещё долго), крупные семейства (stm32, ESP, nRF, MSP430) в разной степени готовности к продакшну, тулинг замечательный (cargo, визуальный дебаггер и т.д.), огромное сообщество во всяких элементах-дискордах-реддитах.

В не очень разной степени готовности. Без слез не взглянешь ни на кого из них.

Опередил! До сих пор на С пишу, особенно на Cortex-M0 каких - нибудь. И не ломают же. Правда там так не развернуться - защита памяти программ у современных версий на высоте.

Либо вы набрасываете на вентилятор.

Да и не был С++ никогда самым популярным. После С все перешли сразу на С# и Java.

Мировая статистика за 2022
Java - 33.27%
C# - 27.98%
C++ - 22.55%
C - 19.24%
Сразу видно, как все после C сразу перешли на C# и Java, равно как и непопулярность С++

https://www.statista.com/statistics/793628/worldwide-developer-survey-most-used-languages/

Вы это так преподносите, как будто это старые и новые версии одного языка, и кодеры "переходят" с одного на другой. Хотя у всех у них свои задачи. Например, на C (и реже на С++) писали, пишут, и будут писать прошивки для железа всех мастей. И вряд ли будут этого делать на шарпах и жавах.

Надеюсь, что всё же прошивки начнут писать на чём-то вроде Rust. Зря вы так пессимистично в будущее смотрите.

Вот когда в nim появится borrow checker как в Rust - тогда можна будет и поговорить.

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

были и есть всякие микродотнеты. Но чтобы там кроме ядра уместился хотя бы хеллоу ворлд, нужно было 200 с лишним кило флеша. Может сейчас меньше, но вряд ли сильно. До недавнего времени атмега 328 была популярна. Сейчас китайцы стм32ф401 продают дешевле авр, но это явно не 411 или более мощные серии. Да и на 401ой памяти тоже не сказать чтобы много.

-1, линукс ядро написано 99% на СИ

-1, Linux написан не на C, а на GNU C, и модель памяти там отличается от сишной.

А, в чём существенная разница при этом?

Аккаунт просто прекрасен)

А что с ним не так в плане безопасности?

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

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

Эт точно. Помню про одну "простую ошибку", когда в питончике можно было написать yaml.load(...)и получить все, что угодно, вплоть по RCE, на untrusted input. Многие писали, а не использующие линтеры и до сих пор пишут. Но "это другое", да.

А в каком-то другом языке было не так? Если проблема в самом YAML, то от языка, в котором вызван тот самый load(), ничего не зависит.

Я к тому, что в любом языке существует возможность легко, но жестоко ошибиться. Те, кто делит языки на "апастные" и "бизапастные", либо преследуют цели продвижения чего-то в неких целях, весьма слабо связанных с "безопасностью для пишущего", либо просто недоумки. Любой язык может быть как "опасным", так и "безопасным", в зависимости от того, кто на нем пишет. И я бы сказал, что чем ниже у языка порог входа, тем бОльший процент его "пользователей" склонен не обращать внимания на детали написанного.

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

Warning: It is not safe to call yaml.load with any data received from an untrusted source! yaml.load is as powerful as pickle.load and so may call any Python function. Check the yaml.safe_load function though.

Жирными такими буквами написано у них на сайте.

С учётом того, что написан на "небезопасном" С )

Но так то на нём довольно сложно случайно сильно накосячить.

А ничего, что все эти "безопасные" языки, (ну возможно кроме Rust, не интересовался, но вероятно он написан сам на себе) написаны таки на C/C++?

Тоже возникла такая мысль. Но потом подумал, что эта основа написана элитными программистами и отшлифована до блеска. А вот обычный код на ПЯВУ, написанный обычными кодерами, хуже проработан и имеет больше ошибок и дыр.

Вклеено то что нужно, а потом отшлифовано до блеска

Go переписан на Go, котлин на котлине, хаскель на хаскеле, далее не везде, но много где. Даже старичек паскаль был переписан с фортрана на паскаль, ведь он появился до С.

Всё, что компилируется, хочет, чтобы на нём написали компилятор )

А как такая трансляция сказывается на быстродействии?

Никак. На выходе все равно х86\х64 исполняемый файл.

Раньше сказывалась плохо.
В 2022 году в качестве бэкэнда работает LLVM. То есть качество генерации машинного кода получается сравнимым.

Можно говорить про наличие \ отсутствие высокоуровневых оптимизаций.
Но в целом есть ощущение, что ничего критичного (типа падения производительности вдвое) там не происходит. А если происходит - то место допиливается руками

Это, можно сказать, индустриальный стандарт. Если язык не может откомпилировать себя, на что он вообще способен? В широко распространённой шутейке "ваш язык не взлетит, потому что" есть два пункта на эту тему: "самый сложный софт на вашем ЯП это его собственный компилятор" и "даже компилятор написан не на нём".

Распространено это намного шире. Даже у Java, например, JVM на С++, а javac таки написан на ней же.

А почему нет-то?
Если компилятор переложил backend на LLMV (терминологически: gcc bakend == LLVM midend + LLVM backend) - то это не значит, что самому компилятору важной и содержательной работы на frontend не осталось.

Например GHC для запуска на ARM просто переписали часть GHC-runtime.
https://www.haskell.org/ghc/blog/20200515-ghc-on-arm.html
https://www.haskell.org/ghc/blog/20210309-apple-m1-story.html

И даже после этого степень уверенности в корректной работе (на слабых моделях памяти) у них не очень большая: "we can now have considerably greater confidence in the correctness
of GHC on today’s increasingly wide".

Думал, достаточно распарсить свой язык в промежуточное представление LLVM, а дальше он сам всё сделает.

Ну в условном web же с появлением библиотек сложность не делась.
В компиляторах тоже - перенеслась во frontend.

Для условного Nim (это не претензия, просто его место - better C) - достаточно.
И то у вас каких-то высокоуровневых оптимизаций не будет (я во front-end не понимаю, поэтому их не перечислю, но это оптимизации на Call-Graph (вызова функций)).

Уже для условного D - возникают проблемы (ЕМНИП вроде little-big endian в его собственном линкуемом runtime). Haskell - ссылки выше.

ПС
Несомненно LLVM отличный инструмент, кратно упрощающий реализацию toolchain ЯП (не поймите меня неправильно). Но содержательная работа всё равно осталась.

Rust тоже написан поверх LLVM, который написан... Да-да. А впрочем, эти "рекомендации анб" напоминают мне фразу "нужно делать так, как нужно, а как не нужно - делать не нужно".

Вспоминается рекомендация NIST по выбору PRNG, где были бекдоры. А NIST гражданская организация, не как сабж.

Ну АНБ в отличии от NIST таки убирала уязвимости в шифроалгоритмах, а не добавляла новые.

LLVM в компиляторе Rust — это бекенд для кодогенерации, для запуска готового исполняемого файла он не нужен. И да, бекенд можно и поменять, например, на cranelift, который написан целиком на Rust.

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


Во-вторых, предполагаю что АНБ в первую очередь беспокоится об уязвимостях, позволяющих получать несанкционированный доступ к данным. Баг в компиляторе скорее всего приведет к падению компилятора (вообще не критично), менее вероятно — к созданию некорректной программы (неприятно). Ошибка в компиляторе, которая будет приводить к появлению уязвимости в скомпилированных программах — астрономически маловероятно, возможно только в результате сознательного сабожата со стороны спецслужб с бесконечным бюджетом.


В-третьих, под фразой "язык написан на языке" можно понимать разные вещи. Языки типа C# и Java состоят, условно, из компилятора (обычно написан на самом языке) и рантайма (скорее всего написан на си или плюсах). Ошибки в рантаймах — штука более серьезная, но и уровень работающих над них специалистов выше.

Не скажу ничего касательно намерений АНБ по эксплуатации уязвимостей рантаймов, но что касаемо аудита кода, на моем месте работы и много где еще в ынтерпрайзе четвертое или пятое поколение безопасников подряд досконально ковыряет JVM HotSpot при каждом переходе на новую версию и бинари распространяются только внутри компании, даже для докер-образов - внешние просто не пустят на деплой.

Да и работают такие приложения в 99% случаев в изолированных контурах на уровне сетевого соединения, куда можно попасть только, если предшествующие слои скомпрометированы (и не только шлюзы API и т.д., но и само сетевое оборудование и его фирмварь). А следовательно задействовать закладку вендора, если таковая имеется, сложнее на порядки.

И несмотря на то, что Java/Kotlin - 75% всего имеющегося кода, С++ - это core-функционал. И там тоже

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

И в целом, рациональное зерно тут есть, и связано оно отнюдь не с желанием контролировать что-угодно by-design (что надо и так управляется и просматривается, но менее топорными методами :] ), а с имитацией общественной значимости учреждения.

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

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

Стоп машина. А как же зелёный переход? Сколько там безопасная Java производит углекислого газа в сравнении с чистым C? [/irony]

Вы так договоритесь ещё, что и облака не нужны

Облака отражают инфракрасное излучение обратно на поверхность планеты. Облака не нужны.

Согласен, облака не нужны, они солнечным панелькам мешают. А ещё ветрогенерация в тренде. Нужно поставить побольше кулеров. С ЛГБТ-подсветкой.

Не зря видимо каждая библиотека в С++ от Китайцев. Знают что выбирать )

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

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

Можно, если хотите раздражать русскоговорящих. С заглавной ассоциируются имена и названия.
В другом месте мне сказали, что такое пошло в последнее время в русские комментарии от тех, кто часто общается на английском. Т.е. не только из-за автодополнения при вводе.

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

Проблема в том, что это предложение можно истолковать как "автором библиотек С++ является некий Китайцев". А заглавная буква не добавляет уважения. Лучше бы проявить уважение к русскому языку.

Это имеет смыл, когда Вы мне объяснили проблема стала очевидной.

Этот проект он анонсировал значительно раньше публикации от АНБ

Астрологи объявили неделю " C#, Go, Java, Ruby, Rust и Swift "

То есть АНБ США как бы намекает что в остальных языках есть закладки.

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

UB на то и UB, что синтаксически код совершенно корректен, и компилятору в общем случае просто не к чему придраться.

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

Немножко грустнее: раньше, когда программист использовать UB, предполагалось, что он знает, что делает (например, кастит массив из 4 uint8_t на uint32_t), сейчас создатели компиляторов, как минимум при оптимизации, считают, что UB в коде просто нет, программист позаботился, что позволяет поднять производительность, но может наделать внезапных дыр.

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

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

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

A как же MISRA C. И еще C это так же про C API (JNI/ctypes/ и т.д.)

А-ха-ха, ну если уж АНБ рекомендует переходить на "безопасные" проприетарные языки американских компаний, тогда да.☝️😂👍

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

тогда это будут уже не плюсы.

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

Это санитайзеры (ака динамические анализаторы), статические анализаторы, системы тестирования и т.д.

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

Но нет, Сообщество упорно продолжает добиваться 20% эффекта за счет 80% усилий и ресурсов.

Это вы так агитируете за что-то типа Aspect C++?

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

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

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

Ну а насчет умельцев - хоть в исходном, хоть в современном C++ и так до черта способов стрелять себе в ноги, и они все множатся.

Бред то какой! Если уж на то пошло, то предложенный ими C# вообще декомпилируется до уровня практически исходников одним кликом... А если очень надо, то вообще никакой разницы на чём оно было написано, расковырять можно что угодно

Одно дело - получить исходники, другое дело - получить где-то UB и выполнение кода из ввода, например.

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

Ну так это от программиста зависит

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

Использование «Блокнота» для написания кода, вместо IDE, не сказывается на безопасности создаваемого кода, если пограммист его создающий не страдает симптомоиами дауна. :)
Надо переписать так:
АНБ США порекомендовало IT-компаниям отказаться от языков C и C++
языки программирования C и C++ дают хакерам больше возможностей
А вы как хотели
С большой силой приходит большая ответственность

Бред, видимо им не хватает специалистов для поиска богов в c++ коде после очередных атак, так как язык действительно не простой. Пишу уже 8 лет на нем, и точно могу сказать что ничего лучше не знаю, разве Си, хотя тут спорно. Когда пишешь на нём чувствуешь себя свободным весь контроль твой. Не понимаю как можно кодить без указателей. Кому то просто не понравился с++ и решили хейтить его, будто бы с#, python написаны на чем то другом. Бреда больше не слышал, си и с++ будут жить вечно.

Много кода на C++ написано до C++11.
Все таки до Java (до 1995-го) большинство писало на C++.
Смею предположить, что существенная доля легаси многих проектов, поддерживающихся и сейчас, была создана в тот период. И именно его хреновость и пытается померить АНБ.

Ваша честь, я протестую!
Например, на тот момент не было shared_ptr, unique_ptr (что решает много проблем с утечками памяти).
Язык сильно изменился и рядовому программисту (который не зашел дальше лаб в ВУЗе), легче поверить в россказни маркетологов, которым нужно по методичке PMHS или AIDA набросать причины, почему стоит учить Python. Или легче поверить в слова программистов, которые сейчас пишут на Java, перейдя (сюрприз сюрприз до 2011 года) с C++.

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

P. S.
Я изучаю C++ 2,5 года. Не могу сказать, что познал достаточно, чтобы претендовать на истину в таких спорах. Но пройти мимо и не вставить свои 5 копеек я не мог :)

Only those users with full accounts are able to leave comments. Log in, please.