How to disable the 'kill' command on Linux
I want to disable all kill commands (including root user). I have tried to change permissions, but it still can be executed. Is there a way to do that?
Solution 1:
"Disabling" kill
for root
, even if it was possible, would most likely have unwanted side-effects, like system scripts malfunctioning, and in the worst (but likely) scenario it would prevent your computer from starting up properly (or even shutting down properly).
For a user, too, it would cause issues. I have, for example, scripts that I run as an unprivileged user, that checks to see if certain processes are running using kill -0 $pid
. Those scripts would stop working.
For yourself, you could alias
the kill
command to something else, like echo "kill"
:
$ alias kill='echo "kill"'
That would prevent kill
from doing anything useful on the command line at least:
$ kill -s HUP $$
kill -s HUP 11985
Solution 2:
Use this kernel module to disable the kill
system call on amd64
.
Use at your own risk. Devastating side effects are expected.
#include <linux/module.h>
MODULE_LICENSE("GPL");
int __init init(void) __attribute__((noreturn))
{
unsigned long long cr0 = read_cr0();
write_cr0(cr0 & ~(1 << 16)); /* Clear Write Protection (WP) bit */
*(unsigned char *)sys_kill = 0xc3; /* opcode for "ret" */
write_cr0(cr0);
/* This makes sure that delete_module below won't complain */
__this_module.refcnt = 1;
__this_module.state = MODULE_STATE_LIVE;
asm volatile
(
"mov %0, %%rsp\n\t" /* It seems GCC refuses to mess with the stack pointer */
"jmp sys_delete_module\n\t" /* call delete_module(name, flags) */
:: "r"(current->stack + THREAD_SIZE - sizeof(struct pt_regs) - 8), "D"(__this_module.name), "S"(0) :
);
}
void __exit exit(void)
{
return;
}
Compile it like you would any other module. Then use insmod
on it.
Solution 3:
You should not disable it system-wide, because it's used in system scripts (e.g., in /etc/init.d/functions
in the initscripts
package).
You can disable it for the login shell (and its subshells) by alias
'ing it to, say, true
/false
(or something like kill_disabled
if you wish to get an error rather than a no-op).
Note that this way is not fool-proof: it will only affect commands executed directly (not those inside scripts). And the user will be able to remove the alias with unalias
.
To do this, run the following command
alias kill=kill_disabled
or add it to an appropriate bash
startup file to run it at every login.
Now, running kill
interactively will produce:
$ kill 9999
-bash: kill_disabled: command not found
As I said, the above way is easily subverted. If you need a fool-proof way, the only solution is to run the entire login shell session in a chroot
environment. It will still only disable the stock command, not a direct syscall, however done. The latter cannot be disabled, because it's essential for normal operation (e.g., every Ctrl + C sends SIGINT
, pipes require SIGPIPE
, and background processes are controlled with more than five different signals). Setting up a chroot environment is an advanced task and it's generally inconvenient if the user needs to access the entire filesystem.