Tornar um processo inábil no Linux

14

Estou trabalhando em um aplicativo gerenciador de senhas e, por razões de segurança, desejo iniciar um processo inabalável.

Além disso, não quero que este programa seja um daemon, pois preciso ler da entrada padrão e escrever nele.

Existe uma maneira de fazer isso?

Mohammad Razeghi
fonte
11
"por razões de segurança, quero iniciar um processo inabalável." Apenas uma observação - se isso fosse permitido, as pessoas poderiam facilmente explorá-lo por razões nefastas - por exemplo, lançar uma bomba de garfo imparável.
VLAZ
32
Isso soa como um problema XY . Suspeito que o que você realmente está tentando alcançar, um processo inábil não é o caminho para fazê-lo. "Por razões de segurança" é muito vago. O que exatamente você deseja impedir que o usuário faça? Que acesso eles têm?
Nate Eldredge 04/09
4
Qualquer processo que não seja passível de qualificação para todos os efeitos é um vírus.
Naftuli Kay 04/09/15
3
@NateEldredge: Antes, faça com que o programa ignore os sinais. Essa é a maneira típica de fazer isso; caso contrário, alguém poderia enviar um SIGINT ou SIGTSTP diretamente ao processo, ignorando o terminal.
Noah Spurrier
2
@NoahSpurrier: Estou imaginando uma situação em que você tem um usuário que pode digitar coisas no console, mas que não pode executar código no computador (como um quiosque). Você o configura para que nenhuma tecla que eles possam digitar tenha um efeito inesperado. Se eles podem executar outro código, ignorar SIGINT e SIGTSTP e SIGQUIT não ajuda; qualquer pessoa que possa enviar esses sinais diretamente para o processo também poderá enviar SIGKILL ou SIGSTOP, que você não pode ignorar.
Nate Eldredge

Respostas:

41

Faça o gerenciador de senhas prazo sob um usuário e pega separada / ignore / sinais gerados pelo bloco de terminais ( SIGINT, SIGQUIT, SIGHUP, SIGTSTP, SIGTTIN, e SIGTTOU).

Você não pode enviar sinais para processos (= kill) executados sob um usuário diferente (usuário cujo uid real e uid definido como salvo são diferentes do uid efetivo), a menos que seu ID efetivo seja 0 (root).

Todos os processos ainda serão executáveis ​​pela raiz.

Para mais detalhes, consulte kill (2) .

PSkocik
fonte
15

A única maneira de tornar um processo inábil é implementá-lo como um thread do kernel , o que não é algo trivial.

Você ainda pode matá-lo, mas isso seria um dano colateral ao desligamento do SO.

Você também pode desenvolver um módulo de kernel personalizado que definiria o SIGNAL_UNKILLABLEsinalizador para o seu processo. Esse sinalizador foi projetado para ser definido apenas para init(ou systemdqualquer processo inicial que o kernel inicie), que são os únicos processos da terra do usuário protegidos contra uma interrupção incondicional, mas nada parece proibir que esse sinalizador esteja presente em um processo regular.

jlliagre
fonte
1
que poderia ser o processo de inicialização
muhmuhten
@muhmuhten Você está certo, o init é um processo da terra do usuário protegido contra uma morte incondicional. No entanto, ele não foi projetado para ser personalizado enquanto houver definitivamente uma API para módulos e threads do kernel.
Jlliagre
Para elaborar minha própria resposta, suponho que você não tenha acesso a uma conta raiz (o que, aliás, sugere que este é um exemplo de brinquedo, um projeto de curso ou malware). Isso impede a ideia de que você poderia conectar um módulo do kernel para esse fim. Observe também que o sinalizador SIGNAL_UNKILLABLE não está disponível para processos normais e impede algumas operações normais importantes (como vforking) e, portanto, eu o consideraria um caso de margem normalmente impraticável.
GregD 5/09/15
@ jlliagre de fato, não é.
muhmuhten 5/09/2015
@dudek Um processo inábil já é um caso de margem normalmente impraticável.
Jlliagre
11

Tecnicamente, não há como tornar um processo inviável.

Obviamente, para usuários não raiz, eles podem matar apenas processos com o mesmo ID de usuário, portanto, se você puder criar contas diferentes, poderá usar um ID de usuário "exclusivo" para o processo e somente o root poderá matá-lo.

Uma solução simples, mas menos robusta, é fazer com que seu processo capte o máximo de sinais possível (talvez ignorando-os). Isso é adequado apenas para exemplos de brinquedos ou ambientes não adversários, pois não há como capturar o sinal KILL (sinal 9), mas, caso contrário, você pode evitar ser morto por eles.

Finalmente, você pode fazer com que seu processo reapareça se for morto. Isso também é frágil (muito frágil), mas tornará um pouco mais difícil a eliminação. Isso pode ser feito usando um processo de monitor próprio ou usando o inittab. Para um adversário que sabe o que está fazendo, isso pode ser facilmente contornado, matando vários processos ao mesmo tempo.

GregD
fonte
1
Mas (além de inittab) é possível que o processo do monitor também possa ser eliminado, não?
roaima 4/09/15
Não, os drivers de dispositivo (módulos do kernel) podem criar processos que não podem ser eliminados pela raiz.
Noah Spurrier