diff -r -U 3 -p linux-2.6/fs/binfmt_elf.c linux/fs/binfmt_elf.c --- linux-2.6/fs/binfmt_elf.c 2004-06-23 08:13:28.000000000 +0300 +++ linux/fs/binfmt_elf.c 2004-06-23 12:33:51.075747675 +0300 @@ -202,6 +202,9 @@ create_elf_tables(struct linux_binprm *b if (k_platform) { NEW_AUX_ENT(AT_PLATFORM, (elf_addr_t)(long)u_platform); } + if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { + NEW_AUX_ENT(AT_EXECFD, (elf_addr_t) BINPRM_GET_EXECFD (bprm->interp_flags)); + } #undef NEW_AUX_ENT /* AT_NULL is zero; clear the rest too */ memset(&elf_info[ei_index], 0, diff -r -U 3 -p linux-2.6/fs/binfmt_misc.c linux/fs/binfmt_misc.c --- linux-2.6/fs/binfmt_misc.c 2004-06-23 08:13:26.000000000 +0300 +++ linux/fs/binfmt_misc.c 2004-06-23 12:33:51.081607003 +0300 @@ -109,7 +109,6 @@ static int load_misc_binary(struct linux char *iname_addr = iname; int retval; int fd_binary = -1; - char fd_str[12]; struct files_struct *files = NULL; retval = -ENOEXEC; @@ -130,7 +129,6 @@ static int load_misc_binary(struct linux } if (fmt->flags & MISC_FMT_OPEN_BINARY) { - char *fdsp = fd_str; files = current->files; retval = unshare_files(); @@ -158,27 +156,27 @@ static int load_misc_binary(struct linux allow_write_access(bprm->file); bprm->file = NULL; - /* make argv[1] be the file descriptor of the binary */ - snprintf(fd_str, sizeof(fd_str), "%d", fd_binary); - retval = copy_strings_kernel(1, &fdsp, bprm); - if (retval < 0) - goto _error; - bprm->argc++; + /* mark the bprm that fd should be passed to interp */ + bprm->interp_flags |= (BINPRM_FLAGS_EXECFD | + BINPRM_SET_EXECFD (fd_binary)); } else { allow_write_access(bprm->file); fput(bprm->file); bprm->file = NULL; - /* make argv[1] be the path to the binary */ - retval = copy_strings_kernel (1, &bprm->interp, bprm); - if (retval < 0) - goto _error; - bprm->argc++; } + /* make argv[1] be the path to the binary */ + retval = copy_strings_kernel (1, &bprm->interp, bprm); + if (retval < 0) + goto _error; + bprm->argc++; + + /* add the interp as argv[0] */ retval = copy_strings_kernel (1, &iname_addr, bprm); if (retval < 0) goto _error; bprm->argc ++; + bprm->interp = iname; /* for binfmt_script */ interp_file = open_exec (iname); diff -r -U 3 -p linux-2.6/include/linux/binfmts.h linux/include/linux/binfmts.h --- linux-2.6/include/linux/binfmts.h 2004-06-23 08:14:39.000000000 +0300 +++ linux/include/linux/binfmts.h 2004-06-23 12:33:51.082583557 +0300 @@ -42,6 +42,14 @@ struct linux_binprm{ #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT) +/* fd of the binary should be passed to the interpreter */ +#define BINPRM_FLAGS_EXECFD_BIT 1 +#define BINPRM_FLAGS_EXECFD (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT) +/* the fd is kept in the high 32 bit of the flags */ +#define BINPRM_GET_EXECFD(flg) (((flg) >> 32) & 0xfffffffful) +#define BINPRM_SET_EXECFD(fd) (((unsigned long)(fd) << 32) & 0xffffffff00000000ul) + + /* * This structure defines the functions that are used to load the binary formats that * linux accepts.