#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
// Прагмы нужны для того, чтобы оптимизатор не выкинул половину нашего кода.
#pragma GCC push_options
#pragma GCC optimize "-O0"
static int is_admin = 0;
#pragma GCC pop_options
static void vulnerable(size_t index, size_t length)
{
// Пишем безопасный код: запрещаем атакующему обращаться к данным за
// пределами массива.
if (index >= length) {
printf("oops, the index is out of bounds\n"); return;
}
// Выделяем память, обращаемся к ней. В общем-то ничего плохого не
// делаем.
uint8_t *ptr
= malloc(length
); printf("got some memory from malloc(): %p\n", (void *) ptr
); ptr[index] = 1;
}
static void destroy_the_world(void)
{
if (!is_admin) {
return;
}
printf("nuclear apocalypse in 3... 2... 1...\n"); }
int main(void)
{
// Представим, что размер и индекс контролируются атакующим.
size_t index_from_user = (size_t) &is_admin;
size_t length_from_user = SIZE_MAX;
printf("BEFORE: is_admin = %u\n", is_admin
); vulnerable(index_from_user, length_from_user);
printf("AFTER: is_admin = %u\n", is_admin
);
destroy_the_world();
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW50Lmg+CgovLyDQn9GA0LDQs9C80Ysg0L3Rg9C20L3RiyDQtNC70Y8g0YLQvtCz0L4sINGH0YLQvtCx0Ysg0L7Qv9GC0LjQvNC40LfQsNGC0L7RgCDQvdC1INCy0YvQutC40L3Rg9C7INC/0L7Qu9C+0LLQuNC90YMg0L3QsNGI0LXQs9C+INC60L7QtNCwLgojcHJhZ21hIEdDQyBwdXNoX29wdGlvbnMKI3ByYWdtYSBHQ0Mgb3B0aW1pemUgIi1PMCIKc3RhdGljIGludCBpc19hZG1pbiA9IDA7CiNwcmFnbWEgR0NDIHBvcF9vcHRpb25zCgpzdGF0aWMgdm9pZCB2dWxuZXJhYmxlKHNpemVfdCBpbmRleCwgc2l6ZV90IGxlbmd0aCkKewogICAgLy8g0J/QuNGI0LXQvCDQsdC10LfQvtC/0LDRgdC90YvQuSDQutC+0LQ6INC30LDQv9GA0LXRidCw0LXQvCDQsNGC0LDQutGD0Y7RidC10LzRgyDQvtCx0YDQsNGJ0LDRgtGM0YHRjyDQuiDQtNCw0L3QvdGL0Lwg0LfQsAogICAgLy8g0L/RgNC10LTQtdC70LDQvNC4INC80LDRgdGB0LjQstCwLgogICAgaWYgKGluZGV4ID49IGxlbmd0aCkgewogICAgICAgIHByaW50Zigib29wcywgdGhlIGluZGV4IGlzIG91dCBvZiBib3VuZHNcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIAogICAgLy8g0JLRi9C00LXQu9GP0LXQvCDQv9Cw0LzRj9GC0YwsINC+0LHRgNCw0YnQsNC10LzRgdGPINC6INC90LXQuS4g0JIg0L7QsdGJ0LXQvC3RgtC+INC90LjRh9C10LPQviDQv9C70L7RhdC+0LPQviDQvdC1CiAgICAvLyDQtNC10LvQsNC10LwuCiAgICB1aW50OF90ICpwdHIgPSBtYWxsb2MobGVuZ3RoKTsKICAgIHByaW50ZigiZ290IHNvbWUgbWVtb3J5IGZyb20gbWFsbG9jKCk6ICVwXG4iLCAodm9pZCAqKSBwdHIpOwogICAgcHRyW2luZGV4XSA9IDE7CiAgICBmcmVlKHB0cik7Cn0KCnN0YXRpYyB2b2lkIGRlc3Ryb3lfdGhlX3dvcmxkKHZvaWQpCnsKICAgaWYgKCFpc19hZG1pbikgewogICAgICAgIHByaW50ZigiYWNjZXNzIGRlbmllZFxuIik7CiAgICAgICAgcmV0dXJuOwogICB9CgogICBwcmludGYoIm51Y2xlYXIgYXBvY2FseXBzZSBpbiAzLi4uIDIuLi4gMS4uLlxuIik7Cn0KCmludCBtYWluKHZvaWQpCnsKICAgIC8vINCf0YDQtdC00YHRgtCw0LLQuNC8LCDRh9GC0L4g0YDQsNC30LzQtdGAINC4INC40L3QtNC10LrRgSDQutC+0L3RgtGA0L7Qu9C40YDRg9GO0YLRgdGPINCw0YLQsNC60YPRjtGJ0LjQvC4KICAgIHNpemVfdCBpbmRleF9mcm9tX3VzZXIgPSAoc2l6ZV90KSAmaXNfYWRtaW47CiAgICBzaXplX3QgbGVuZ3RoX2Zyb21fdXNlciA9IFNJWkVfTUFYOwoKICAgIHByaW50ZigiQkVGT1JFOiBpc19hZG1pbiA9ICV1XG4iLCBpc19hZG1pbik7CiAgICB2dWxuZXJhYmxlKGluZGV4X2Zyb21fdXNlciwgbGVuZ3RoX2Zyb21fdXNlcik7CiAgICBwcmludGYoIkFGVEVSOiAgaXNfYWRtaW4gPSAldVxuIiwgaXNfYWRtaW4pOwogICAgCiAgICBkZXN0cm95X3RoZV93b3JsZCgpOwp9