В Си есть функция с мемным названием
memmem()
. Работает она похоже на strstr()
, т.е. ищет подстроку в строке. Только вместо null-terminated строки на вход подается указатель на начало строки и ее размер.Разработчики ядра применили изменение, в результате которого у меня сломалась работа с Secure Boot:
https://bugzilla.kernel.org/show_bug.cgi?id=216642
Ответ на баг-репорт убил:
In that sense, your use case is exactly what we intended to fix with that patch.
https://bugzilla.kernel.org/show_bug.cgi?id=216642
Ответ на баг-репорт убил:
In that sense, your use case is exactly what we intended to fix with that patch.
Маппинг памяти на нулевой адрес в Linux
Вопрос обсуждался на Stack Overflow здесь
Если коротко, то мапить странцы по нулевому адресу можно (если делать это с флагом
Пример (со Stack Overflow):
Вопрос обсуждался на Stack Overflow здесь
Если коротко, то мапить странцы по нулевому адресу можно (если делать это с флагом
MAP_FIXED
). Правда, это может сделать только root
(или процесс с нужными capabilities). Почему это не может сделать процесс обычного пользователя? Чтобы пользователь не мог эксплуатировать уязвимости ядра, связанные с чтением по нулевому указателю. А он это мог бы сделать, поскольку ядро «видит» маппинги памяти пользовательского процесса. И если пользователь замапил нулевую страницу, то она будет доступна и в ядре, тоже по нулевому адресу.Пример (со Stack Overflow):
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
int main() {
void *p = mmap(0, sysconf(_SC_PAGE_SIZE),
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
printf("mmap result %p (errno %s)\n", p, strerror(errno));
return 0;
}
Самый необычный тип в C++ (с расширениями GCC)
Пусть вам дана функция
Если мы воспользуемся variable-length array (в Cтандарте C++ его нет, зато есть в расширениях GCC) и попробуем передать в
Пусть вам дана функция
template <class T>Как вы думаете, какие типы возможно передать в foo()? Любые? Любые, кроме void? А вот и нет!
void foo(const T &) {}
Если мы воспользуемся variable-length array (в Cтандарте C++ его нет, зато есть в расширениях GCC) и попробуем передать в
foo()
:int n = 42;
int a[n];
foo(a);
то получим эпичную ошибку:main.cpp:34:28: note: variable-sized array type ‘int [n]’ is not a valid template argument
А еще variable-length array интересен тем, что sizeof()
от него вычисляется в рантайме. Во время компиляции это невозможно, поскольку мы не знаем размер массива.Всем, кто утверждает, что компилятор Go быстро компилирует, покажите вот этот код:
https://pastebin.com/vzp5ha1y
и попросите дождаться, пока он скомпилируется.
Конечно, это очень вырожденный случай. Компилятору здесь как минимум нужно выписать тип в виде строки (чтобы использовать
https://pastebin.com/vzp5ha1y
и попросите дождаться, пока он скомпилируется.
Конечно, это очень вырожденный случай. Компилятору здесь как минимум нужно выписать тип в виде строки (чтобы использовать
reflect
). При этом для любого типа T
верно, что func(a, b T)
перепишется в func(a T, b T)
. Таким образом, количество раз, которое мы выписали T
, удвоилось. Вкладывая так func(a, b T)
друг в друга много раз, мы получаем, что строка с записью типа растет экспоненциально быстро, и компилятор не осиливает.