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?
4 Answers
"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
-
4Disabling
kill
only for interactive use is the only sane answer, so +1. If you do want to use it from an interactive shell with this alias, just run/bin/kill ...
, orbuiltin kill ...
orcommand kill
to suppress function/alias lookup. Bash has keywords to override the default command lookup. The normal use-case is in wrapper functions, e.g.cd(){ command cd "$@"; pwd > /tmp/here.$$; }
Jun 22, 2016 at 10:20 -
8
-
@AndrewHenle: Oh right, I used to use
\rm
fairly often when I had it aliased torm -i
(instead of my current choice ofrm -I
). Jun 22, 2016 at 16:18 -
@PeterCordes If you somehow disabled kill for interactive use, the trivial work-around would be to invoke kill via a wrapper script. Jun 22, 2016 at 18:37
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.
-
74It's amazing how you can count on people to hand you multiple guns to shoot yourself in the foot if you ask for it. Including kernel module. :D Jun 22, 2016 at 10:57
-
13
-
42Hopefully at least anyone who knows how to "compile it like you would any other module" knows how much of a bad idea this is. Jun 22, 2016 at 16:45
-
5Interesting, I guess you modify
%rsp
before tail-callingsys_delete_module
so the return address is outside the deleted function. Anyway, always use constraints to ask for your data in the right register, instead of usingmov
instructions. e.g. use"D"(__this_module.name)
to ask for it in%rdi
in the first place. Amov
at the start or end of an inline asm block of code is almost always sub-optimal, and better left to the compiler. I don't think there's a constraint for%rsp
, though, and I know there aren't constraints for any of%r8
through%r15
. Jun 22, 2016 at 19:52 -
15Can someone please insert this module in a VM and post a recording of what happens on YouTube? Jun 23, 2016 at 4:12
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.
-
1
-
-
2Uh if you run it in a chroot nothing stops you making the kill syscall directly from e.g. another application, which could even be one you compiled and uploaded into the chroot. (Byte by byte if you cared enough). Chroot is nowhere near foolproof. Short of hobbling the system call inside the kernel nothing can stop it completely.– FlexoJun 22, 2016 at 20:32
-
1@xxlali What are you trying to do? The fact that you are not an advanced user makes it even more likely that disabling
kill
is not what you should actually be doing to solve the problem you're having...– DavidJun 23, 2016 at 23:36 -
1@DavidYoung I have a program. There is another way to stop this program, but some users prefer the stop this program using 'kill -9 %pid%' which causes unwanted results. So, I want to force users to use normal way stop. This is why I want to disable kill command usage.– xxlaliJun 24, 2016 at 11:59
If you want the users to be able to use kill
normally except for when they try to kill your specific program, you can define a kill
function in the .bashrc
of the user profile and within this function, check if the user is trying to kill your program. If not, you can call the kill
utility from within your function itself.
As an example, I wrote a small kill function which will not kill the sleep
utility but will function as a normal kill utility for any other parameter provided to it.
function kill() {
process=$(ps -p "${@: -1}" | awk 'END{print $(NF)}');
if [[ $process == "sleep"]]
then
echo "Killing $process is not allowed"
else
/bin/kill $@
fi
}
-
1
kill
executable by calling the c functionkill
.kill
on your system? Do you have processes being terminated by people with root privileges which you don't want being terminated?