Flaga Flaga GCC -fstack-protector umożliwia użycie kanarek stosu do ochrony przed przepełnieniem stosu. Domyślnie użycie tej flagi było bardziej widoczne w ostatnich latach.
Jeśli pakiet zostanie skompilowany z opcją -fstack-protector i przepełnimy bufor w programie, prawdopodobnie wystąpi błąd, taki jak:
*** buffer overflow detected ***: /xxx/xxx terminated
Jednak „kto” odpowiada za te komunikaty o błędach? Gdzie są rejestrowane te wiadomości? Czy demon syslog wybiera te wiadomości?
libssp
wyśle swój komunikat przez wyjście stderr używane przez nginx. Następnielibssp
może spróbować zakończyć proces (lub proces potomny dla nginx). Jeśli aplikacja „nie musi” zawieszać aplikacji, nieprawidłowe rejestratory wyjścia nie będą tego odbierać. Czy to poprawna interpretacja?__builtin_trap()
najpierw, a następnie, jeśli to zawiedzie, próbuje sprowokować naruszenie segment i tylko wtedy, gdy nie powiedzie się, wychodzenia ze stanu 127.abort()
.).Nowoczesne dystrybucje Linuksa, takie jak CentOS / Fedora , domyślnie konfigurują demona do obsługi awarii (np.
systemd-coredump
Lubabortd
).Tak więc, gdy twój program kończy się w nienormalny sposób (segfault, nieprzechwycony wyjątek, przerwanie, nielegalne instrukcje itp.) To zdarzenie jest rejestrowane i rejestrowane przez tego demona. W związku z tym w dzienniku systemowym znajdują się pewne komunikaty i ewentualnie odniesienie do katalogu z dodatkowymi szczegółami (np. Plik podstawowy, dzienniki itp.).
Przykład
Skompilować:
Wykonać:
Status wyjścia ma wartość 134, czyli 128 + 6, tj. 128 plus numer sygnału przerwania.
Dziennik systemu:
Oznacza to, że logujesz się od
auditd
demona kontroli i programusystemd-coredump
obsługi awarii.Aby sprawdzić, czy skonfigurowano demona do obsługi awarii, możesz sprawdzić
/proc
, np .:(wszystko testowane na Fedorze 26, x86-64)
źródło
abort()
co daje sygnał przerwania, tzn. nie występuje błąd segmentacji. Po prostu domyślne procedury obsługi sygnałów dla błędu przerwania / segmentacji itp. Dają tę samą akcję: zapisz rdzeń i wyjdź z procesu z nierównym zerowym statusem wyjścia, który również koduje numer sygnału. Pisanie rdzenia odbywa się przez jądro, a jego zachowanie można skonfigurować za pomocą/proc/.../core_pattern
. W powyższym przykładzie pomocnik w przestrzeni użytkownika jest skonfigurowany i wywołany. Jądro uruchamia także inspekcję.abort()
, używa kodu SSP__builtin_trap()
(ale efekt jest taki sam).abort()
się nazywa.__builtin_trap()
aby uniknąć wyraźnej zależnościabort()
). Inne dystrybucje mają różne ślady stosu.