RE: [PATCH] Handle non-readable binfmt misc executables

From: Zach, Yoav
Date: Wed Jun 23 2004 - 04:57:46 EST




>-----Original Message-----
>From: Albert Cahalan [mailto:albert@xxxxxxxxxxxxxxxxxxxxx]
>Sent: Monday, June 21, 2004 14:50
>To: Zach, Yoav
>Cc: Albert Cahalan; linux-kernel mailing list
>Subject: RE: [PATCH] Handle non-readable binfmt misc executables
>

>> Right. It might happen once in a (long) while that
>> 'ps -f' doesn't show the correct command line.
>
>So this is a hole in the emulation.
>

You have a point here. The patch below fixes this problem
by passing the open fd via the aux-vector. Argv[1] will
be the full path to the binary regardless of whether the
kernel opened it or not. The patch is against recent mm tree,
thus it needs to be applied on top of two prev patches to
binfmt_misc that are part of this tree.
As my mailer tends to wrap up text, the patch is also attached.


Thanks,
Yoav.



========================= BEGIN PATCH =========================
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.
========================= END PATCH =========================

Attachment: binfmt_misc-nonreadable-execfd.patch
Description: binfmt_misc-nonreadable-execfd.patch