• От каких атак защищен процессор Эльбрус?

    OCTAGRAM
    @OCTAGRAM
    Там есть так называемый защищённый режим, унаследованный от советского Эльбруса. В СССР эта защита в железе дополняла защиту в софте. Несмотря на то, что Паскаль и Си ровесники (1970), пока стоял СССР, в страну Си не пускали, зато очень заинтересовались Адой, приняли ГОСТ, перевели книги, написали с десяток трансляторов, в том числе под Эльбрус. И там была гармония между семантикой языка программирования и железом.

    По прошествии лихих годин (выражение Ельцина, 1992 год) потенциал был растрачен, и былая гармония раскололась. Эльбрус выжил, но трансляторы для него теперь совсем другие, главным образом это Си (C++ там был куплен у Edison group, которые делают Comeau C++-> C транслятор). Си не создавался в расчёте на безопасность, это, по выражению создателей, переносимый ассемблер, но вот на этот ассемблер попытались навинтить унаследованную от советского Эльбруса аппаратную защиту. Если в случае с Адой железо органично продолжает воплощение языковых запретов, то для Си навинчивание защиты является хаком, и для многих программ на Си, особенно, где местечковое ООП реализовано, или хоть немного шаг влево, шаг вправо, всё, такая программа уже не транслируется без допиливаний. Так что если взять купить Эльбрус, там практически ничего не работает в защищённом режиме, он там где-то сбоку есть. В презентации МЦСТ про защищённый режим был описан программный комплекс из Эльбрус полностью в защищённом режиме и обычного ПК с Windows 10. В защищённом режиме не было графического режима, потому что даже примитивные библиотеки для фреймбуфера не портированы. Отображение было на Windows 10 по сети. Часть кода зачем-то пришлось портировать с C++ на C.

    Механизм защиты строится на том, что в дополнение к значащим битам информации есть биты тегов. В оперативной памяти они хранятся в битах ECC, вместо битов контроля ошибок аппаратных сбоев. Из памяти теги перетекают в регистры. Обращаться к памяти из защищённого режима можно только по дескриптору. Дескриптор должен иметь подходящий тег. Если тега нет, то это просто число, которым никак иначе нельзя воспользоваться. Любые неправильные операции над дескрипторами либо возбуждают исключение, либо ломают тег, превращая дескриптор в число.

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

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

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

    Также в Эльбрус есть способ пометить память как неинициализирванную для отлова ошибок обращения к ней.

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

    Подводя итоги, дескриптор содержит:
    1. обычный указатель
    2. тип дескриптора (массивный/объектный)
    3. дескриптор модуля
    4. индекс кадра стека
    5. либо указатели на границы массива, либо указатели на информацию для ООП

    1 и 5 дают как минимум 3 обычных указателя в одном дескрипторе, а 2-4 добивают дескриптор информацией под завязку. Известно, что размер дескриптора 128 бит. По всему видно, что как ни крути, а 3 64битных указателя, хоть их до 48 бит обрезай, ну не влезают никак. Может, 36 бит ещё можно впихнуть, но, похоже, что нет. Так что защищённый режим Эльбруса 32битный или не сильно отличается от такового.

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

    По большому счёту, многие ошибки, от которых даёт защиту Эльбрус, специфичны для C и C++. Программисты на С и С++ создают проблемы, и тут появляется Эльбрус и типа их героически решает. Ну это бред, если так подумать. По-хорошему, надо писать на Аде и от других требовать того же. Сколько лет существуют ошибки переполнения буфера, столько же лет существует и решение для них (Паскаль и Си ровесники). Учитывая, что в защищённом режиме Эльбрус почти ничего сишное просто так не работает, выходит, что под Эльбрус писать новый софт на Си, что на Аде, ощутимые вложения труда делать хоть как придётся. Но на Аде оно будет защищено везде, не только лишь на Эльбрусе, и на Аде есть 64 бита. А для повышенной защиты есть верифицируемое подмножество SPARK, которое в последнее время переживает бум. Раньше SPARK был довольно дубовый. Если что-то нельзя верифицировать, то в SPARK этого не было. Например, там не было обычных контейнеров, как в языке Ада, а были свои, занимащие сразу максимальный размер памяти. Но сейчас готовится заимствование из ParaSail и Rust безопасных указателей, так что с динамической памятью в SPARK станет посвободнее.

    Аппаратная защита в Эльбрусе не уникальна. Был когда-то Intel i960MX. На базе MIPS в Кембридже разработали CHERI, и он и сейчас продаётся. В отличие от Эльбруса, там не секретничают. Можно прямо с сайта скачать эмулятор, документацию и инструменты разработки. Бери, смотри, изучай кто хочешь. И это не Россия под санкциями, это влиятельный британский университет. Ничего из этого не помогло ему занять какие-то особо значимые ниши. Верификация не имеет 1:1 соответствия с аппаратным контролем, им бы лучше дополнять друг друга, чем заставлять выбирать, но видно, что реальные покупатели, авиация (Боинг), а с некоторых пор беспилотные автомобили (nVidia) полагаются на верификацию больше, чем на аппаратную защиту.
    Ответ написан
    Комментировать
  • Почему выскакивает ошибка при объявлении массива?

    GavriKos
    @GavriKos
    ХЗ что там за компилятор cpp.sh, но нельзя создавать массив в стеке неопределенного на этапе компиляции размера.
    Используйте new и выделяйте на куче столько, сколько вам нужно.
    Ответ написан
    1 комментарий
  • Как собрать на linux программу на писанную на с++ без Gcc/g++?

    @res2001
    Developer, ex-admin
    Если это нужно для дистрибуции программы, то делаете свой репозиторий куда кладете предварительно собранные пакеты для поддерживаемых платформ. Репозиторий добавляете в настройки пакетного менеджера ОС и устанавливаете штатными средствами уже из репозитория.
    Ответ написан
    4 комментария
  • Как собрать на linux программу на писанную на с++ без Gcc/g++?

    @stratosmi
    Есть ли какие то стандартные сборщики для в Centos или вообще в linux.

    Ну, например, во FreeBSD в комплекте идет clang.
    Однако в Linux такого не припомню. Посмотри, если нет ни gcc ни clang, то всё же придется поставить.
    Ответ написан
    1 комментарий
  • Как собрать на linux программу на писанную на с++ без Gcc/g++?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    gcc :)

    yum install gcc мешают сделать какие-то высшие соображения?
    Ответ написан
    3 комментария
  • Как добавить путь LD_LIBRARY_PATH в коде с++?

    @none7
    Ваша программа, это не sh скрипт. И пара строк:
    std::system("export myvar=1");
    std::system("echo $myvar");

    неожиданно выведут пустую строку. Нужно либо устанавливать переменную в том же вызове system(env LD_LIBRARY_PATH=${LD_LIBRARY_PATH} path/to/app) или ручками менять переменные своей программы(getenv/setenv).
    Ответ написан
    Комментировать
  • Как настроить make install для проекта?

    @MechanicZelenyy
    Если проект на c++, то лучше все-таки использовать cmake, и настраивать параметры установки в нем. А он уже нужный makefile сгенерирует.
    Ответ написан
    5 комментариев
  • Как в netbeans подключить динамическую библиотеку вместе со статическими ubuntu?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    пишу ключ -static

    из info gcc:
    '-static'
    On systems that support dynamic linking, this prevents linking with
    the shared libraries. On other systems, this option has no effect.


    линковать с ключем -dynamic.

    нет же такого ключа когда собираешь под linux

    Что делать? Убирать ключ -static -- всё равно статически слинкованного исполняемого файла не получится, раз нужна динамическая библиотека.
    Ответ написан
    1 комментарий
  • Почему у std::string нет человеческого replace?

    @xxx3Vxxx
    Программист C++
    #include <regex>
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        string t = "asd asd asd";
        t = regex_replace(t, regex("asd"), "sdf");
        cout << t;
    
        return 0;
    }


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

    Zifix
    @Zifix Куратор тега Qt
    Barbatum
    Поднимите сервис на своем сервере, туда будет приходить запрос от программы, а уже с сервера отправлять письмо.
    Ответ написан
    Комментировать
  • Как обрезать заголовок в https ответе?

    fzfx
    @fzfx
    18,5 дм
    удалить всё от нулевого байта до первого переноса строки включительно или использовать функции библиотеки, которая заточена на работу с http.
    Ответ написан
    Комментировать
  • Как обрезать заголовок в https ответе?

    myjcom
    @myjcom Куратор тега C++
    в boost практически аналогично
    #include <iostream>
    #include <algorithm>
    #include <iterator>
    using namespace std;
    
    int main()
    {
        char buf[1500]{"HTTPS/1.1 200 OK\nContent-Type: \
                        application/json; charset=utf-8\n\
                        Content-Length: 48\
                        Connection: Close{\"DATA\": {\"ERROR\":\
                         \"ANY USER IS LOGIN\"}}"};
        auto bs{ find(begin(buf) , end(buf)  , '{' ) };
        auto es{ find(rbegin(buf), rend(buf) , '}' ) };
        copy(bs, es.base(), ostream_iterator<char>(cout));
    }

    {"DATA": {"ERROR": "ANY USER IS LOGIN"}}
    Ответ написан
    4 комментария
  • Вопрос по QTableView, как разделить строки по ячейкам из одного QlineEdit?

    myjcom
    @myjcom Куратор тега C++
    использовать split
    doc.qt.io/qt-5/qstring.html#split

    spoiler
    QStandardItemModel *model = new QStandardItemModel();
    for (auto& x : tx->AddrsTo) 
    {
      Qstring s(x.c_str()); 
      QStringList items = s.split(';');
      int sz = items.size();
      for(int i = 0; i < sz; ++i)
      {
        model->setItem(0, i, new QStandardItem(items[i]));
      }
    }
    this->findChild<QTableView*>("Adresses_tableView")->setModel(model);
    Ответ написан
    Комментировать
  • Как в Ubuntu 16 подключить библиотеку Qt5 вместо Qt4?

    Xuxicheta
    @Xuxicheta
    инженер
    ваша установленная версия лежит в /opt
    Прописывайте руками пути до qmake в вашем NetBeans

    Можно еще попробовать просто установить qt5 из реп, может он сам подхватит.
    apt install qt5-default
    Ответ написан
    2 комментария
  • Как вывести массив?

    @Codebaker
    Всё умею, всё могу!
    Добавьте счетчик numberOfUserEnteredStrings, увеличивайте его каждый раз, когда пользователь что-то вводит.
    При выводе результатов цикл сделайте не до 200, а уже до numberOfUserEnteredStrings.
    Ответ написан
    1 комментарий
  • Как сделать выход из цикла ввода в массив string?

    @Codebaker
    Всё умею, всё могу!
    Оператором getline(cin, name[i]);
    вы считываете строку от пользователя в i-тый элемент массива name.
    А для выхода используете if (i == en), очевидно, что надо сравнивать так: if (0 == name[i].compare(en))
    Ответ написан
    Комментировать
  • Книги по Нейронным сетям, ИИ и машинному зрению?

    @Junior007 Автор вопроса
    Нашел то, что искал: Репозиторий на GitHub

    В описании есть 8 книг, которые искать не нужно уже в репозитории + 3 онлайн курса (ссылки) и еще статьи. Вдруг кто тоже искать будет.
    Ответ написан
    Комментировать
  • Что такое Circular list на C++?

    Кольцевой или циклический список. По достижению конца списка, итератор сбрасывается на первый элемент и наоборот.
    Ответ написан
    Комментировать