diff options
author | Yoav Zach <yoav.zach@intel.com> | 2004-06-17 17:53:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-06-17 17:53:34 -0700 |
commit | 79baf43b978b7842a28d332d9015e5cae16ebf14 (patch) | |
tree | a7f06f7838aedcbe81f9ca6881fcd342a37a89ce /Documentation | |
parent | 69ac831eeaeec87d7d1e4d0a5ecaa0aadb15cc9a (diff) | |
download | history-79baf43b978b7842a28d332d9015e5cae16ebf14.tar.gz |
[PATCH] Handle non-readable binfmt_misc executables
<background>
I work in a group that works on enabling the IA-32 Execution Layer
(http://www.intel.com/pressroom/archive/releases/20040113comp.htm) on Linux.
In a few words - this is a dynamic translator for IA-32 binaries on IPF
platform. Following David Mosberger's advice - we use the binfmt_misc
mechanism for the invocation of the translator whenever the user tries to
exec an IA-32 binary.
The EL is meant to help in the migration path from IA-32 to IPF. From our
beta customers we learnt that at first stage - they tend to keep their
environment mostly intact, using the legacy IA-32 binaries.
Such an environment has, naturally, setuid and non-readable binaries. It
will be useless to ask the administrator to change the settings of such an
environment - some of them are very complex, and the administrators are
reluctant to make any changes in a system that already proved itself to be
robust and secure. So, our target with these patches is not to enhance the
support for scripts but rather to allow a translator to be integrated into a
working environment that is not (and should not be) aware to the fact it's
being emulated.
As I said before - it is practically hopeless to expect an administrator of
such a system to change it so that it will suit the current behavior of
binfmt_misc. But, even if we could do that,
I'm not sure it would be a good idea - these changes are likely to be less
secure than the suggested patches -
- In order to execute non-readable binaries the binary will have to be made
readable, which is obviously less secure than allowing only a trusted
translator to read it
- There will be no way for the translator to calculate the accurate
AT_SECURE value for the translated process. This might end up with the
translated process running in a non-secured mode when it actually needs to
be secured.
</background>
I prepared a patch that solves a couple of problems that interpreters have
when invoked via binfmt_misc. currently -
1) such interpreters cannot open non-readable binaries
2) the processes will have their credentials and security attributes
calculated according to interpreter permissions and not those of the
original binary
the proposed patch solves these problems by -
1) opening the binary on behalf of the interpreter and passing its fd
instead of the path as argv[1] to the interpreter
2) calling prepare_binprm with the file struct of the binary and not the
one of the interpreter
The new functionality is enabled by adding a special flag to the registration
string. If this flag is not added then old behavior is not changed.
A preliminary version of this patch was sent to the list on 9/1/2003 with the
title "[PATCH]: non-readable binaries - binfmt_misc 2.6.0-test4". This new
version fixes the concerns that were raised by the patch, except of calling
unshare_files() before allocating a new fd. this is because this feature did
not enter 2.6 yet.
Arun Sharma <arun.sharma@intel.com> says:
We were going through an internal review of this patch:
http://marc.theaimsgroup.com/?l=linux-kernel&m=107424598901720&w=2
which is in your tree already. I'm not sure if this line of code got
sufficient review.
+ /* call prepare_binprm before switching to interpreter's file
+ * so that all security calculation will be done according to
+ * binary and not interpreter */
+ retval = prepare_binprm(bprm);
The case that concerns me is: unprivileged interpreter and a privileged
binary. One can use binfmt_misc to execute untrusted code (interpreter) with
elevated privileges. One could argue that all binfmt_misc interpreters are
trusted, because only root can register them. But that's a change from the
traditional behavior of binfmt_misc (and binfmt_script).
(Update):
Arun pointed out that calculating the process credentials according to the
binary that needs to be translated is a bit risky, since it requires the
administrator to pay extra attention not to register an interpreter which is
not intended to run with root credentials.
After discussing this issue with him, I would like to propose a modified
patch: The old patch did 2 things - 1) open the binary for reading and 2)
calculate the credentials according to the binary.
I removed the riskier part of changing the credentials calculation, so the
revised patch only opens the binary for reading. It also includes few words
of warning in the description of the 'open-binary' feature in
binfmt_misc.txt, and makes the function entry_status print the flags in use.
As for the 'credentials' part of the patch, I will prepare a separate patch
for it and send it again to the LKML, describe the problem and ask for people
comments.
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/binfmt_misc.txt | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/Documentation/binfmt_misc.txt b/Documentation/binfmt_misc.txt index 3de8edbe66d3dc..8f8fb4a7730ac4 100644 --- a/Documentation/binfmt_misc.txt +++ b/Documentation/binfmt_misc.txt @@ -15,7 +15,7 @@ First you must mount binfmt_misc: mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc To actually register a new binary type, you have to set up a string looking like -:name:type:offset:magic:mask:interpreter: (where you can choose the ':' upon +:name:type:offset:magic:mask:interpreter:flags (where you can choose the ':' upon your needs) and echo it to /proc/sys/fs/binfmt_misc/register. Here is what the fields mean: - 'name' is an identifier string. A new /proc file will be created with this @@ -34,6 +34,21 @@ Here is what the fields mean: The mask is anded with the byte sequence of the file. - 'interpreter' is the program that should be invoked with the binary as first argument (specify the full path) + - 'flags' is an optional field that controls several aspects of the invocation + of the interpreter. It is a string of capital letters, each controls a certain + aspect. The following flags are supported - + 'P' - preserve-argv[0]. Legacy behavior of binfmt_misc is to overwrite the + original argv[0] with the full path to the binary. When this flag is + included, binfmt_misc will add an argument to the argument vector for + this purpose, thus preserving the original argv[0]. + 'O' - open-binary. Legacy behavior of binfmt_misc is to pass the full path + of the binary to the interpreter as an argument. When this flag is + included, binfmt_misc will open the file for reading and pass its + descriptor as an argument, instead of the full path, thus allowing + the interpreter to execute non-readable binaries. This feature should + be used with care - the interpreter has to be trusted not to emit + the contents of the non-readable binary. + There are some restrictions: - the whole register string may not exceed 255 characters @@ -83,9 +98,9 @@ If you want to pass special arguments to your interpreter, you can write a wrapper script for it. See Documentation/java.txt for an example. -Your interpreter should NOT look in the PATH for the filename; the -kernel passes it the full filename to use. Using the PATH can cause -unexpected behaviour and be a security hazard. +Your interpreter should NOT look in the PATH for the filename; the kernel +passes it the full filename (or the file descriptor) to use. Using $PATH can +cause unexpected behaviour and can be a security hazard. There is a web page about binfmt_misc at |