Флаг GCC -fstack-protector flag разрешает использование канареек стека для защиты переполнения стека. Использование этого флага по умолчанию стало более заметным в последние годы.
Если пакет скомпилирован с -fstack-protector, и мы переполняем буфер в программе, мы, вероятно, получим ошибку, такую как:
*** buffer overflow detected ***: /xxx/xxx terminated
Тем не менее, «кто» отвечает за эти сообщения об ошибках? Где эти сообщения регистрируются? Демон системного журнала выбирает эти сообщения?
libssp
выведет свое сообщение с помощью вывода stderr, используемого nginx. Затемlibssp
может попытаться выйти из процесса (или дочернего процесса для nginx). Если приложение «не нуждается» в аварийном завершении приложения, то аварийные регистраторы выхода не поймут это. Это правильная интерпретация?__builtin_trap()
сначала, а затем, если это не удается, пытается спровоцировать нарушение сегмента, и только если это не удается, выход со статусом 127.abort()
).Современные дистрибутивы Linux, такие как CentOS / Fedora , по умолчанию устанавливают демон обработки сбоев (например,
systemd-coredump
илиabortd
).Таким образом, когда ваша программа завершается ненормальным образом (segfault, uncaught exception, abort, недопустимая инструкция и т. Д.), Это событие регистрируется и регистрируется этим демоном. Таким образом, вы найдете некоторые сообщения в системном журнале и, возможно, ссылку на каталог с некоторыми дополнительными сведениями (например, файл ядра, журналы и т. Д.).
пример
Обобщение:
Выполнение:
Состояние выхода - 134, что составляет 128 + 6, то есть 128 плюс номер сигнала прерывания.
Системный журнал:
Это означает , что вы получите вход от
auditd
аудита демона и вsystemd-coredump
аварии обработчика.Чтобы проверить, настроен ли демон обработки сбоев, вы можете проверить
/proc
, например:(все проверено на Fedora 26, x86-64)
источник
abort()
которые выдают сигнал прерывания, то есть не происходит ошибки сегментации. Просто обработчики сигналов по умолчанию для сбоя / сбоя сегментации и т. Д. Дают одно и то же действие: записать ядро и выйти из процесса с неравным нулем состояния выхода, которое также кодирует номер сигнала. Запись ядра выполняется ядром, а его поведение настраивается с помощью/proc/.../core_pattern
. В приведенном выше примере вспомогательный пользовательский пространства настроен и, таким образом, вызывается. Ядро также запускает одитинг.abort()
, код SSP использует__builtin_trap()
(но эффект тот же).abort()
называется.__builtin_trap()
чтобы избежать явной зависимости отabort()
). Другие дистрибутивы имеют разные трассировки стека.