In a word, "no".
Linux doesn't really differentiate between executables and scripts; the #!
at the beginning is a way to tell the kernel what program to run to evaluate the input but it's not the only way a script can be executed.
So, for example, if I have a script
$ cat x
#!/bin/sh
echo hello
Then I can run this with the command
$ ./x
That will cause the kernel to try and execute it, spot the #!
and then effectively run /bin/sh x
instead.
However I could also run any of these variants as well:
$ sh ./x
$ bash ./x
$ cat x | sh
$ cat x | bash
$ sh < x
or even
. ./x
So even if the kernel tried to enforce signing at the exec
layer we can bypass this by only running the interpreter with the script as a parameter.
This means that signing code would have to be in the interpreter itself. And what would stop a user from compiling their own copy of a shell without the signing enforcement code?
The standard solution to this isn't to use signing, but to use Mandatory Access Controls (MAC), such as SELinux
. With MAC systems you can specify exactly what each user is allowed to run and transition layers. So, for example, you can say "normal users can run anything but the web server and CGI processes can only access stuff from the /var/httpd
directory; everything else is rejected".
noexec
on a read-only partition on a dm-verity signed block device. – Charles Duffy yesterday