LINUX.ORG.RU

Си. Почему бы не запретить запись в стек?

 


1

4

Решил немного разобраться как работают уязвимости. Как я понял, весомая их часть модифицирует стек.

#include <stdio.h>

register long unsigned rsp asm("rsp");

void print_arg(int arg) {
    ((int*)rsp)[3] = 0xBADC0DE;
    printf("arg = %x\n", arg);
}

int main(int argc, char **argv) {
    print_arg(0xF00D);
    return 0;
}

Этот код отрабатывает и не выводит ошибкок с

-fhardened -fcf-protection=full

На мой взгляд выглядит небезопасно.

Почему бы не вставлять проверки на ассемблере при записи в память, на включаемость в регион стека? Если нужно записать что то в аргумент на стеке (int), то проверку можно не вставлять. При записи по указателю, уже обязательно вставлять. Если адрес стека то ошибка. В memset проверять пересечение двух диапазонов.

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

void read_file(const char *name)
{
        char buff[999];
        FILE *f = fopen(name, "rb");
        read_block(f, buff);
}

void read_block(FILE *f, char *buff)
{
        // тут компилятор должен вывести что len(buff) == 999
        fread(buff, 1, 9999, f);
}

Что бы все идеально работало, нужно будет:

  • Пометить libc функции
  • Если функция работает со стеком как у меня в верхнем примере, но это правильное поведение, пометить и ее
  • Перекомпилировать основные библиотеки, что бы не ломать ABI можно ввести экспорт двух прототипов, с доп.значениями для проверки диапазонов и без, дублирование прототипов понадобится для малого числа функций
★★★★★

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

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

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

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

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

(а) как мы собираемся различать указатели на стек, и указатели куда-то ещё

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

(б) что делать с custom allocators

Они будут корректно работать без изменений.

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

Это все фон Нейман.

Не вращай старика в гробу. Ты можешь аппаратно разместить stack, heap, shared и static в разных микросхемах, но адресное пространство у них общее.

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

Просто вбей свой код в интерпретатор и пойми что он работает не так, как ты (скорее всего) ожидаешь, нечего тут раскрывать.

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

как мы собираемся различать указатели на стек, и указатели куда-то ещё

Это я объяснял выше.

Процитируйте - буду признателен.

что делать с custom allocators

Они будут корретно работать без изменения

Оуеть, да ладно!

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

Падение программы или заражение системы, что лучше?

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

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

Я ниже после кода привел вывод от запуска программы. От компилятора к компилятору поведение может отличаться.

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

Давно пора.
Архитектура процессора, позволяющая защитить данные НИКОМУ НЕ НУЖНА!

Потому-то в эти игры никогда не играю.
ИМХО пустая трата времени.

Чинить решето - не моё!

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 6)
Ответ на: комментарий от bugfixer

Процитируйте - буду признателен.

Си. Почему бы не запретить запись в стек? (комментарий)

Оуеть, да ладно!

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

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

В процессорах много чего скрытого есть ..., но лучше ИМХО разработкой заниматься.
Профита больше.

Как бы воевать с ветряными мельницами ныне «не современно».

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

Надо было отдельную аппаратную память под стеки делать

Не выдумывай, этот функционал ещё в 80286 16-битном проце был в 1982 году. Но умники, проектировавшие 32-битные ОС, его проигнорировали, т.к. им оказалось слишком сложно, а затем другие умники, проектировавшие amd64, дропнули его поддержку в 64-битном режиме.

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

я еще должен твои чудесатые «программы» проверять и толковать? не буду.

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

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

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

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

Почему я не могу сравнивать два указателя?

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

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

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

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

вам морковкин 4 стека надо уже? а еще свой стек у каждого треда. и надо переклчать стек при переключении контекста. то есть надо 4 стека на тред?

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

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

Меня стек amd64 вполне устраивает, мой компилятор например использует rsp для стека переходов, а rbp для данных. Есть еще отдельные стеки для других вещей, например для плавающей точки.

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

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

Тут скорее не знание процессора а знанием как юзается память что ли. Кто это ВАМ сказал что они ведут на один объект ?

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

Тут скорее не знание процессора а знанием как юзается память что ли. Кто это ВАМ сказал что они ведут на один объект ?

Компилятор - https://godbolt.org/z/as43a9oYE

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

Вот правильная ссылка https://godbolt.org/z/8fvqrxovs

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

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

Не поэтому.
Тред весьма интересен, но его акцент меня не особо интересует.

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

То бишь у меня этих проблем - нет!

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