The idea is as follows: by default, the standard behavior applies. To
request the alternate behavior, the character "P" (for "preserve") is
added to the end of the binfmt_misc registration string.
For example, consider the case:
execve("ls", {"arg0", "arg1", NULL}, envp);
If this execve() were to be redirected to the "ski" interpreter,
binfmt_misc would normally invoke it like this:
argv[0] = /usr/bin/ski
argv[1] = /bin/ls
argv[2] = "arg1"
With the alternate behavior, "ski" would be invoked as:
argv[0] = /usr/bin/ski
argv[1] = /bin/ls
argv[2] = arg0
argv[3] = arg1
In other words, this way, an interpreter has access both to the full
path (as determined by the kernel) and the original value of arg0.
(Obviously the interpreter needs to know whether the binfmt_misc
registration occurred with or without 'P', but that's the
interpreter's problem and we can deal with that.)
Comments?
--david
--- a/fs/binfmt_misc.c Mon Aug 19 11:44:32 2002
+++ b/fs/binfmt_misc.c Sun Aug 25 10:07:41 2002
@@ -35,6 +35,7 @@
static int enabled = 1;
enum {Enabled, Magic};
+#define MISC_FMT_PRESERVE_ARGV0 (1<<31)
typedef struct {
struct list_head list;
@@ -121,7 +122,9 @@
bprm->file = NULL;
/* Build args for interpreter */
- remove_arg_zero(bprm);
+ if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
+ remove_arg_zero(bprm);
+ }
retval = copy_strings_kernel(1, &bprm->filename, bprm);
if (retval < 0) goto _ret;
bprm->argc++;
@@ -287,6 +290,11 @@
if (!e->interpreter[0])
goto Einval;
+ if (*p == 'P') {
+ p++;
+ e->flags |= MISC_FMT_PRESERVE_ARGV0;
+ }
+
if (*p == '\n')
p++;
if (p != buf + count)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/