O sinalizador GCC -fstack-protector permite o uso de canários de pilha para proteção contra estouro de pilha. O uso desse sinalizador por padrão tem sido mais proeminente nos últimos anos.
Se um pacote for compilado com -fstack-protector e sobrecarregarmos um buffer no programa, é provável que ocorram erros como:
*** buffer overflow detected ***: /xxx/xxx terminated
No entanto, "quem" é responsável por essas mensagens de erro? Onde essas mensagens são registradas? O daemon syslog seleciona essas mensagens?
libssp
emitirá sua mensagem pela saída stderr usada pelo nginx. Em seguida,libssp
tente sair do processo (ou processo filho do nginx). Se "não precisar" travar o aplicativo, os registradores de saída anormais não serão atendidos. Essa é uma interpretação correta?__builtin_trap()
em primeiro lugar, em seguida, se isso falhar, tentando provocar uma violação de segmento, e somente se isso falhar, sair com status de 127.abort()
).Distribuições modernas do Linux como o CentOS / Fedora configuram um daemon de tratamento de falhas (por exemplo,
systemd-coredump
ouabortd
), por padrão.Portanto, quando seu programa termina de forma anormal (segfault, exceção não capturada, abortamento, instrução ilegal etc.), esse evento é registrado e registrado por esse daemon. Assim, você encontra algumas mensagens no diário do sistema e, possivelmente, uma referência a um diretório com alguns detalhes adicionais (por exemplo, arquivo principal, logs, etc.).
Exemplo
Compilar:
Executar:
O status de saída é 134, que é 128 + 6, ou seja, 128 mais o número do sinal de cancelamento.
O diário do sistema:
Isso significa que você obtém o log do
auditd
daemon de auditoria e dosystemd-coredump
manipulador de falhas.Para verificar se um daemon de manipulação de falhas está configurado, você pode verificar
/proc
, por exemplo:(tudo testado no Fedora 26, x86-64)
fonte
abort()
que produz um sinal de abortamento, ou seja, não há nenhuma falha de segmentação em andamento. É só que os manipuladores de sinal padrão para falha de aborto / segmentação etc. produzem a mesma ação: escreva o núcleo e saia do processo com um status de saída igual a zero que também codifica o número do sinal. A escrita principal é feita pelo kernel e seu comportamento é configurável via/proc/.../core_pattern
. No exemplo acima, um auxiliar de espaço do usuário é configurado e, portanto, chamado. O kernel também aciona a auditoria.abort()
, o código SSP usa__builtin_trap()
(mas o efeito é o mesmo).abort()
é chamado.__builtin_trap()
para evitar ter uma dependência explícitaabort()
). Outras distribuições têm diferentes rastreamentos de pilha.