LSM: Use derived creds for accessing an executable's interpreter and binary loader

Currently, the caller must be able to open the script interpreter and/or the
binary loader that an executable wants to make use of, even if the executable
will be transitioned to a different context that can make use of that
interpreter or loader when the caller's context does not permit it.

Override credentials in open_exec() and kernel_read() with the currently
constructed new credentials so that if the executable file or its interpreter
specifies a transition to a different security context (DAC or MAC), then the
caller only has to provide access to the file to be executed, and not to the
interpreter (e.g. perl) or binary loader (e.g. ld.so) for the executable or
interpreter.

This means that if the caller does not have access to a script interpreter or
binary loader, it can still use scripts and executables that transition to a
security context that do.


For the initial opening of the executable file specified to execve(), this
won't make much difference as the new creds at that point are a clone of the
old ones (except that the new creds do not have thread or process keyrings).

For the opening of script interpreters (e.g. /bin/sh), the file will be opened
with the credentials-to-be rather than the credentials of the caller of
execve() by the script binfmt passing the bprm to open_exec(), and the file
will be reopened on the subsequent pass through prepare_binprm() if a security
context transition takes place.

For the opening of binary loaders (e.g. ld-linux.so), the file will be opened
with the credentials-to-be rather than the credentials of the caller of
execve() by the binary binfmt passing the bprm to open_exec().

If we publish the new credentials by making use of them, however, we may not
change them thereafter.  This relies on the previous patches to make the cred
pointer in struct linux_binfmt semi-committed once it's assigned there.

Note that reopen_exec() uses dentry_open() rather than do_file_open().  To use
the latter, prepare_binprm() has to be furnished with a pointer to the filename
for whatever was opened for bprm->file and the core SELinux policy requires an
additional rule:

	allow setfiles_t bin_t:lnk_file read;

so that /sbin/setfiles can be exec'd as /sbin/restorecon (which is a symlink).


To make the SELinux testsuite work after this patch, the following two rules
need to be added to the policy:

	[policy/test_ptrace.te]
	allow test_ptrace_traced_t bin_t:file { execute read open };

	[policy/test_file.te]
	allow fileop_t fileop_exec_t:file { execute read open };

The first allows the ptrace test to use the perl interpreter (labelled bin_t)
to run a perl script and the second allows the SIGIO file test's wait program
to use its binary (labelled fileop_exec_t).

Reported-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Signed-off-by: David Howells <dhowells@redhat.com>
1 file changed