Doque Embedded – Telegram
Doque Embedded
3.13K subscribers
600 photos
38 videos
1 file
87 links
С/С++, memes and random things
Download Telegram
Проклятые технологии
🔥33
🔥39
Модульная клавиатура в формате еврорек-синтезатора.
Иногда я охуеваю от того что и как совмещают люди.
🔥41
Ура, наконец-то круглое число. Спасибо всем что вы со мной.
🔥44
Считаю что stack-protec лучшее название ветки которое я придумывал.
He protec
But also he stack
🔥16
Как обмануть и унизить компилятор.

На заре прошивки Flipper Zero нам понадобилось перенести функцию strdup (выделение места и копирование в него строки) в наш код, чтобы эффективнее использовать heap операционной системы.

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

char* strdup(const char* s) {
const char* s_null = s;
if(s_null == NULL) {
return NULL;
}

size_t siz = strlen(s) + 1;
char* y = pvPortMalloc(siz);
memcpy(y, s, siz);

return y;
}

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

error: null argument where non-null required

Окей, давайте обманывать компилятор.

void* absolutely_not_null(){ return NULL; }
strdup(absolutely_not_null());

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

if(s == NULL) return NULL;
error: 'nonnull' argument 's' compared to NULL

Ага, вот почему оно было так странно написано, и вот ответ на наши странности. Аргумент функции в недрах stdlib помечен как nonnull (не может быть NULL), так что компилятор выкидывает ненужную по его мнению проверку. Но мы же его уже обманывали, давайте обманем еще раз:

void* absolutely_not_null(){ return NULL; }
if(s == absolutely_not_null()) return NULL;

К сожалению компилятор и это детектит как ненужную проверку. Что мы еще можем сделать?

if(1 / ((uint32_t)s + 1) == 1) {
return NULL;
}

И это тоже детектируется как проверка на NULL.

if(((uint32_t)s << 1) == 0) {
return NULL;
}

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

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

А вот вам ссылка на поиграться: https://godbolt.org/z/PqeEcqKax
🔥40
This media is not supported in your browser
VIEW IN TELEGRAM
Modern machine learning python application:
Гонять кур с газона.
🔥43💩1
🔥12
🔥16
🔥30💩1
This media is not supported in your browser
VIEW IN TELEGRAM
Неочевидных игровых механик пост

Взрыв эмоций каждый раз, когда натыкаюсь на гениальные и простые игровые механики, переосмысляющие привычные нам вещи.
Пример — вот вроде бы клавиатура, используется для управления в играх, wasd и все дела. А что если изменить привычный UX и сделать клавиатуру частью геймплея? — БУМ, магия 🧚‍♀️

Поиграться можно тут
Увидел тут
За наводку спасибо Витале Веберу 😘
🔥45
Forwarded from Иван
Чилийский художник PEPEGR∆PHIX - большой любитель ретро игр. Он придумал своего персонажа и таким образом пародирует рекламу со старых японских журналов 80-х. Выглядит очень атмосферно. 🔥🧡
🔥38