Re: security-/misfeature-fix for binfmt_misc [2nd PATCH]

Richard Guenther (richard.guenther@student.uni-tuebingen.de)
Fri, 4 Jul 1997 10:03:26 +0200 (MESZ)


On Tue, 1 Jul 1997, Richard Guenther wrote:

> Hi!
>
> The patch below fixes binfmt_misc to use bprm->filename rather than
> argv[0] (thanx to hpa). It does minor cleanup as well.
>
> Richard.

Sorry, this was a "Schnellschuss" (what the h*** is this in english??)
Below the 'right' patch is apended (though the documentation needs some
more checking, especially the example section).

Richard.

diff -u --recursive --new-file linux-2.1.43/Documentation/binfmt_misc.txt linux-2.1.43x/Documentation/binfmt_misc.txt
--- linux-2.1.43/Documentation/binfmt_misc.txt Sun Jun 22 12:54:59 1997
+++ linux-2.1.43x/Documentation/binfmt_misc.txt Wed Jul 2 23:46:28 1997
@@ -1,8 +1,8 @@
Kernel Support for miscellaneous (your favourite) Binary Formats v1.1
- ====================================================================
+ =====================================================================

This Kernel feature allows to invoke almost (for restrictions see below) every
-program by simply typing it's name in the shell.
+program by simply typing its name in the shell.
This includes for example compiled Java(TM), Python or Emacs programs.

To achieve this you must tell binfmt_misc which interpreter has to be invoked with
@@ -16,11 +16,11 @@
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
- this name below /proc/sys/fs/binfmt_misc
+ name below /proc/sys/fs/binfmt_misc
- 'type' is the type of recognition. Give 'M' for magic and 'E' for extension.
- Give the corresponding lowercase letter to let binfmt_misc strip of the
+ Give the corresponding lowercase letter to let binfmt_misc strip off the
filename extension.
- - 'offset' is the offset of the magic/mask in the file counted in bytes. This
+ - 'offset' is the offset of the magic/mask in the file, counted in bytes. This
defaults to 0 if you omit it (i.e. you write ':name:type::magic...')
- 'magic' is the byte sequence binfmt_misc is matching for. The magic string
may contain hex-encoded characters like \x0a or \xA4. In a shell environment
@@ -45,17 +45,22 @@
A few examples (assumed you are in /proc/sys/fs/binfmt_misc):

- enable Java(TM)-support (like binfmt_java):
- echo ":Java:M::\xca\xfe\xba\xbe::/usr/local/bin/java:" > register
- echo :Applet:M::\<\!--applet::/usr/local/bin/appletviewer: > register
+ echo :Java1:e::class::/use/local/bin/java: > register
+ echo ":Java2:m::\xca\xfe\xba\xbe::/usr/local/bin/java:" > register
+ echo :Applet1:M::\<\!--applet::/usr/local/bin/appletviewer: > register
+ echo :Applet2:E::html::/usr/local/bin/appletviewer: > register
+
- enable support for em86 (like binfmt_em86, for Alpha AXP only):
echo ":i386:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:" > register
echo ":i486:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:" > register
+
- enable support for packed DOS applications (pre-configured dosemu hdimages):
echo ":DEXE:M::\x0eDEX::/usr/bin/dosexec:" > register
+
- enable support for DOS/Windows executables (using mzloader and dosemu/wine):
echo ":DOSWin:M::MZ::/usr/sbin/mzloader:" > register
echo ":DOS:E::com::/usr/sbin/mzloader:" > register
-
+ echo ":DOS2:E::exe::/usr/sbin/mzloader:" > register

You can enable/disable binfmt_misc or one binary type by echoing 0 (to disable)
or 1 (to enable) to /proc/sys/fs/binfmt_misc/status or /proc/.../the_name.
@@ -68,13 +73,12 @@
HINTS:
======

-If your interpreter does not look at the PATH to determine the full name of the
-program, you need to invoke a wrapper-script (like the following for java) first:
+If you want to pass special arguments to your interpreter, you can
+write a wrapper script for it.

-#!/bin/sh
-FOO=`which $1` || exit 1
-shift
-/usr/local/bin/java $FOO ${1+$@}
+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.


There is a web page about binfmt_misc at
diff -u --recursive --new-file linux-2.1.43/fs/binfmt_misc.c linux-2.1.43x/fs/binfmt_misc.c
--- linux-2.1.43/fs/binfmt_misc.c Sun Jun 22 12:55:07 1997
+++ linux-2.1.43x/fs/binfmt_misc.c Thu Jul 3 14:28:05 1997
@@ -7,9 +7,11 @@
* a specified wrapper. This should obsolete binfmt_java, binfmt_em86 and
* binfmt_mz.
*
- * 25.4.97 first version
- * [...]
- * 19.5.97 cleanup
+ * 1997-04-25 first version
+ * [...]
+ * 1997-05-19 cleanup
+ * 1997-06-26 hpa: pass the real filename rather than argv[0]
+ * 1997-06-30 minor cleanup
*/

#include <linux/module.h>
@@ -85,7 +87,6 @@
*ep = e->next;
entry_proc_cleanup(e);
kfree(e);
- MOD_DEC_USE_COUNT;
}
write_unlock(&entries_lock);
}
@@ -102,7 +103,6 @@
entries = entries->next;
entry_proc_cleanup(e);
kfree(e);
- MOD_DEC_USE_COUNT;
}
write_unlock(&entries_lock);
}
@@ -185,12 +185,11 @@

/* Build args for interpreter */
if ((fmt_flags & ENTRY_STRIP_EXT) &&
- (p = strrchr(bprm->filename, '.'))) {
+ (p = strrchr(bprm->filename, '.')))
*p = '\0';
- remove_arg_zero(bprm);
- bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
- bprm->argc++;
- }
+ remove_arg_zero(bprm);
+ bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
+ bprm->argc++;
bprm->p = copy_strings(1, &iname_addr, bprm->page, bprm->p, 2);
bprm->argc++;
if (!bprm->p) {
@@ -322,7 +321,7 @@
entries = e;
write_unlock(&entries_lock);

- return count;
+ err = count;
_err:
MOD_DEC_USE_COUNT;
return err;
@@ -499,6 +498,7 @@
unregister_binfmt(&misc_format);
remove_proc_entry("register", bm_dir);
remove_proc_entry("status", bm_dir);
+ clear_entries();
remove_proc_entry("sys/fs/binfmt_misc", NULL);
}
#endif