É possível conectar a execução de um script em cada criação de processo?
Essencialmente o equivalente a inotifywait para monitorar a atividade do disco, mas aplicado à tabela de processos.
Seria para permitir realizar uma ação na geração dos processos, por exemplo, registrá-lo, cgset, outro. Posso ver o desafio que isso se aplicaria recursivamente aos novos processos. Mas, em vez de pesquisar a tabela de processos o mais rápido possível para detectar alterações que seriam vulneráveis às condições de corrida, existe uma maneira melhor.
Obrigado
Responder1
Primeiro, a criação de processos raramente é um evento útil para registrar e é irrelevante para a segurança (exceto para limitação de recursos). Acho que você quer enganchar a execução de programas, o que é feito porexecve
, nãofork
.
Em segundo lugar, os casos de uso que você cita geralmente são mais bem atendidos usando mecanismos existentes feitos para essa finalidade, em vez de criar o seu próprio.
- Para registro,Contabilidade de processos BSDfornece uma pequena quantidade de informações e está disponível na maioria das variantes do Unix; no Linux, instale oUtilitários de contabilidade GNU(instale o pacote da sua distribuição). Para registro mais sofisticado no Linux, você pode usar osubsistema de auditoria(o
auditctl
a página man tem exemplos; como expliquei acima, a chamada do sistema que você deseja registrar éexecve
). - Se você quiser aplicar restrições de segurança a determinados programas, use uma estrutura de segurança comoSELinuxouAppArmor.
- Se você deseja executar um programa específico em um contêiner ou com determinadas configurações, mova o executável e coloque um script wrapper em seu lugar que defina as configurações desejadas e chame o executável original.
Se você quiser modificar a forma como um programa específico chama outros programas, sem afetar o comportamento dos outros programas, há dois casos: ou o programa é potencialmente hostil ou não.
- Se o programa for potencialmente hostil, execute-o em uma máquina virtual dedicada.
- Se o programa for cooperativo, o ângulo de ataque mais óbvio é executá-lo com um arquivo
PATH
. Se o programa usa caminhos absolutos que não são fáceis de configurar, em um sistema Linux não antigo, você pode executá-lo em um sistema separado.montar namespace(Veja tambémkernel: suporte a namespaces). Se você realmente precisar de um controle preciso, poderá carregar uma biblioteca que substitua algumas chamadas de biblioteca invocando o programa comLD_PRELOAD=my_override_library.so theprogram
. VerRedirecionar um descritor de arquivo antes da execuçãoPor exemplo. Observe que, além deexecve
, você precisará substituir todas as funções da biblioteca C que chamamexecve
internamente, porqueLD_PRELOAD
isso não afeta as chamadas internas da biblioteca C. Você pode obter um controle mais preciso executando o programa emptrace
; isso permite substituir uma chamada do sistema, mesmo que seja feita por uma função da biblioteca C, mas é mais difícil de configurar (não conheço nenhuma maneira fácil de fazer isso).
Responder2
//fakeExec.c
#include <unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
int execve(const char *path, char *const argv[], char *const envp[]) {
printf("Execing \"%s\"\n", path);
return syscall(SYS_execve, path, argv, envp);
}
No terminal:
$ gcc -fPIC -shared fakeExec.c -o fakeExec.so
$ export LD_PRELOAD=$PWD/fakeExec.so
E agora você deve registrar todos os novos arquivos executados em stdout
.
Aparentemente, um invólucro de garfo exigiria um pouco mais de trabalho para ser feito corretamente.
(O wrapper trivial fork
(como o acima, mas for fork
em vez de execve
) funciona, mas leva a alguns setgpid
erros nos processos gerados com ele.
Aparentemente, a libc fork
funciona com algumas coisas adicionais, que não entendo muito bem. )