
خبرفوری

آهنگیفای

TrueCaller

Notcoin Community

Whale Chanel

Proxy MTProto | پروکسی

iRo Proxy | پروکسی

Findo Lucky

My Proxy | مای پروکسی

خبرفوری

آهنگیفای

TrueCaller

Notcoin Community

Whale Chanel

Proxy MTProto | پروکسی

iRo Proxy | پروکسی

Findo Lucky

My Proxy | مای پروکسی

خبرفوری

آهنگیفای

TrueCaller

Курсы хуюрсы
TL;DR
Рейтинг TGlist
0
0
ТипПублічний
Верифікація
Не верифікованийДовіреність
Не надійнийРозташування
МоваІнша
Дата створення каналуЛют 06, 2025
Додано до TGlist
Трав 26, 2024Прикріплена група
КХ
Курсы хуюрсы Chat
13
29.01.202520:43
#dev
Все мы знаем, что разыменовывать нулевой указатель плохо, потому что программа крашнется и вообще это UB, отстаньте. На самом деле, за этим утверждением скрывается много всякого интересного и неожиданного.
Начнем с того, что есть нуль, а есть ноль.
Как вытекает из предыдущего, ничего особенного в адресе
Впрочем, одно дело — UB по стандарту, другое — поведение на практике. В прошлом стандарт C воспринимался скорее как гайдлайн, чем правила. Старые компиляторы не делали умных оптимизаций, и вообще Ритчи не подразумевал, что за счет UB будут оптимизировать, поэтому на многих платформах разыменование нулевого указателя только и делало, что читало значение в памяти по адресу
В современном мире писать по адресу, совпадающему с адресом
Хочется верить, что по крайней мере на современных платформах разыменовывание
Потом эту лавочку прикрыли, и даже не потому, что это скрывает баги в программах на C. Ну, точнее, ровно поэтому, только программой на C здесь выступает само ядро. Достаточно большое количество ядерных эксплоитов того времени заключалось в том, чтобы дата рейсом или иным методом заставить ядро разыменовать нулевой указатель. Поскольку внутри ядра (была) видна память текущего процесса, это приводило к тому, что пользовательская память начинала интерпретироваться как ядерные структуры. Чтобы этого избежать, сейчас Linux не позволяет аллоцировать страницы ниже адреса
На этом история с разыменованием нуля могла бы закончиться: в Windows ограничение на память на малых адресах было уже давно, в Linux ввели, других операционных систем не существует. Но хипстеры придумали WebAssembly, и поскольку с ним вопрос об изоляции внутри контейнера не встает, по адресу
Такие дела.
@alisa_rummages
Все мы знаем, что разыменовывать нулевой указатель плохо, потому что программа крашнется и вообще это UB, отстаньте. На самом деле, за этим утверждением скрывается много всякого интересного и неожиданного.
Начнем с того, что есть нуль, а есть ноль.
NULL
не обязан иметь адрес 0
и, например, на некоторых архитектурах и интерпретаторах C это не так. Прагматичным людям из POSIX это не нравится, поэтому там NULL
всегда имеет адрес 0
. Впрочем. не обязательно даже уходить далеко в прошлое: amdgcn определяет NULL
как -1
, так что встретиться с таким сегодня вполне реально. Типичное определение NULL
как (void*)0
на таких машинах все еще работает, потому что (void*)0
стандарт определяет равным NULL
, но вот int x = 0; (void*)x
портабельно NULL
не даст.Как вытекает из предыдущего, ничего особенного в адресе
NULL`а нет, и в железе никто не запрещает существовать странице по адресу `0
. Железу плевать на то, какие правила накладывает стандарт C, и поэтому, например, на процессорах x86 в real mode по адресам 0
— 256
хранятся таблицы прерываний. Разыменовывать адрес 0
в C все еще UB, но вот 1
разыменовать никто не запрещает.Впрочем, одно дело — UB по стандарту, другое — поведение на практике. В прошлом стандарт C воспринимался скорее как гайдлайн, чем правила. Старые компиляторы не делали умных оптимизаций, и вообще Ритчи не подразумевал, что за счет UB будут оптимизировать, поэтому на многих платформах разыменование нулевого указателя только и делало, что читало значение в памяти по адресу
0
. Компилятор C на HP-UX (это были еще те времена, когда свободных компиляторов C не было, и под каждую платформу были свои компиляторы, зачастую платные), например, давал опцию: мапать страницу по адресу 0
, чтобы *(int*)NULL
возвращало 0
(гарантированно! без современного понимания UB!), или не мапать, чтобы падало.В современном мире писать по адресу, совпадающему с адресом
NULL
, опасно прям совсем. В embedded, где такое периодически приходится делать, у этой проблемы есть два решения: молоток и микроскоп. Во-первых, можно написать код для записи по адресу 0
на ассемблере, железо сожрет. Во-вторых, иногда железо игнорирует старшие биты адреса, поэтому можно записывать не по адресу 0
, а, например, по адресу 0x80000000
, который железо воспримет так же, а компилятор проинтерпретирует корректно.Хочется верить, что по крайней мере на современных платформах разыменовывание
NULL
(если его не выкинет компилятор, конечно) приведет к сегфолту или чему-то подобному. Это не так. Во-первых, Linux поддерживает флаг personality MMAP_PAGE_ZERO
, аллоцирующий страницу по адресу 0
на старте программы для совместимости с System V. Во-вторых, даже без этого вы можете с помощью mmap
аллоцировать страницу по адресу 0
руками — этим даже пользовались эмуляторы.Потом эту лавочку прикрыли, и даже не потому, что это скрывает баги в программах на C. Ну, точнее, ровно поэтому, только программой на C здесь выступает само ядро. Достаточно большое количество ядерных эксплоитов того времени заключалось в том, чтобы дата рейсом или иным методом заставить ядро разыменовать нулевой указатель. Поскольку внутри ядра (была) видна память текущего процесса, это приводило к тому, что пользовательская память начинала интерпретироваться как ядерные структуры. Чтобы этого избежать, сейчас Linux не позволяет аллоцировать страницы ниже адреса
sysctl vm.mmap_min_addr
— 64 кибибайта на большинстве устройств. (Нет бы писать без багов...)На этом история с разыменованием нуля могла бы закончиться: в Windows ограничение на память на малых адресах было уже давно, в Linux ввели, других операционных систем не существует. Но хипстеры придумали WebAssembly, и поскольку с ним вопрос об изоляции внутри контейнера не встает, по адресу
0
здесь вполне есть доступная память. Некоторых это бесит, некоторых удивляет, меня — радует, ибо нефиг проталкивать ограничения уровней абстракции вниз (впрочем, с этим в WebAssembly проиграли в других местах).Такие дела.
@alisa_rummages
Увійдіть, щоб розблокувати більше функціональності.