[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] Introduce option -binfmt-misc-friendly
From: |
Kirill A. Shutemov |
Subject: |
[Qemu-devel] [PATCH] Introduce option -binfmt-misc-friendly |
Date: |
Mon, 8 Sep 2008 17:03:36 +0300 |
-binfmt-misc-friendly makes qemu compatible with binfmt_misc's flags 'P'
and 'O'.
'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.
Signed-off-by: Kirill A. Shutemov <address@hidden>
---
linux-user/linuxload.c | 7 +----
linux-user/main.c | 54 ++++++++++++++++++++++++++++++++++++++++-------
linux-user/qemu.h | 2 +-
3 files changed, 49 insertions(+), 14 deletions(-)
diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index ada7c69..cbd90f7 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -154,7 +154,7 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong
sp,
return sp;
}
-int loader_exec(const char * filename, char ** argv, char ** envp,
+int loader_exec(int fd, const char * filename, char ** argv, char ** envp,
struct target_pt_regs * regs, struct image_info *infop)
{
struct linux_binprm bprm;
@@ -164,10 +164,7 @@ int loader_exec(const char * filename, char ** argv, char
** envp,
bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
bprm.page[i] = 0;
- retval = open(filename, O_RDONLY);
- if (retval < 0)
- return retval;
- bprm.fd = retval;
+ bprm.fd = fd;
bprm.filename = (char *)filename;
bprm.argc = count(argv);
bprm.argv = argv;
diff --git a/linux-user/main.c b/linux-user/main.c
index 4bf739e..d3223f2 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -26,6 +26,7 @@
#include "qemu.h"
#include "qemu-common.h"
+#include "elf.h"
/* For tb_lock */
#include "exec-all.h"
@@ -2180,12 +2181,13 @@ static void usage(void)
"Linux CPU emulator (compiled for %s emulation)\n"
"\n"
"Standard options:\n"
- "-h print this help\n"
- "-g port wait gdb connection to port\n"
- "-L path set the elf interpreter prefix (default=%s)\n"
- "-s size set the stack size in bytes (default=%ld)\n"
- "-cpu model select CPU (-cpu ? for list)\n"
- "-drop-ld-preload drop LD_PRELOAD for target process\n"
+ "-h print this help\n"
+ "-g port wait gdb connection to port\n"
+ "-L path set the elf interpreter prefix
(default=%s)\n"
+ "-s size set the stack size in bytes (default=%ld)\n"
+ "-cpu model select CPU (-cpu ? for list)\n"
+ "-drop-ld-preload drop LD_PRELOAD for target process\n"
+ "-binfmt-misc-friendly make qemu compatible with binfmt_misc's
flags 'O' and 'P' \n"
"\n"
"Debug options:\n"
"-d options activate log (logfile=%s)\n"
@@ -2218,9 +2220,10 @@ void init_task_state(TaskState *ts)
ts->sigqueue_table[i].next = NULL;
}
-int main(int argc, char **argv)
+int main(int argc, char **argv, char **envp)
{
const char *filename;
+ int fd = -1;
const char *cpu_model;
struct target_pt_regs regs1, *regs = ®s1;
struct image_info info1, *info = &info1;
@@ -2230,6 +2233,7 @@ int main(int argc, char **argv)
const char *r;
int gdbstub_port = 0;
int drop_ld_preload = 0, environ_count = 0;
+ int binfmt_misc_friendly = 0;
char **target_environ, **wrk, **dst;
if (argc <= 1)
@@ -2302,6 +2306,8 @@ int main(int argc, char **argv)
drop_ld_preload = 1;
} else if (!strcmp(r, "strace")) {
do_strace = 1;
+ } else if (!strcmp(r, "binfmt-misc-friendly")) {
+ binfmt_misc_friendly = 1;
} else
{
usage();
@@ -2381,7 +2387,39 @@ int main(int argc, char **argv)
}
*dst = NULL; /* NULL terminate target_environ */
- if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
+ if (binfmt_misc_friendly) {
+#if HOST_LONG_BITS == 32
+#define Elf_Dyn Elf32_Dyn
+#else
+#define Elf_Dyn Elf64_Dyn
+#endif
+ Elf_Dyn *auxv;
+
+ optind++; /* Handle binfmt_misc's option 'P' */
+
+ /* Handle binfmt_misc's option 'O' */
+ while(*envp++ != NULL); /* skip envp. we are on auxv now */
+ for(auxv = (Elf_Dyn *)envp; auxv->d_tag != AT_NULL; auxv++) {
+ if( auxv->d_tag == AT_EXECFD) {
+ fd = auxv->d_un.d_val;
+ break;
+ }
+ }
+
+ if (fd < 0) {
+ printf("Cannot find binary file descriptor\n");
+ _exit(1);
+ }
+
+ } else {
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ printf("Cannot open file %s: %s\n", filename, strerror(errno));
+ _exit(1);
+ }
+ }
+
+ if (loader_exec(fd, filename, argv+optind, target_environ, regs, info) !=
0) {
printf("Error loading %s\n", filename);
_exit(1);
}
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index a12cc9b..216e2f8 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -168,7 +168,7 @@ struct linux_binprm {
void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
abi_ulong stringp, int push_ptr);
-int loader_exec(const char * filename, char ** argv, char ** envp,
+int loader_exec(int fd, const char * filename, char ** argv, char ** envp,
struct target_pt_regs * regs, struct image_info *infop);
int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
--
1.5.6.5.GIT
- [Qemu-devel] [PATCH] Fix vfork() syscall emulation, Kirill A. Shutemov, 2008/09/08
- [Qemu-devel] [PATCH] Fix getgroups() syscall emulation, Kirill A. Shutemov, 2008/09/08
- [Qemu-devel] [PATCH] Swap only altered elements of the grouplist, Kirill A. Shutemov, 2008/09/08
- [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI, Kirill A. Shutemov, 2008/09/08
- [Qemu-devel] [PATCH] Implement syscall fstatat64(), Kirill A. Shutemov, 2008/09/08
- [Qemu-devel] [PATCH] Implement futimesat() syscall, Kirill A. Shutemov, 2008/09/08
- [Qemu-devel] [PATCH] Imaplement ioctls MTIOCTOP, MTIOCGET and MTIOCPOS, Kirill A. Shutemov, 2008/09/08
- [Qemu-devel] [PATCH] Introduce option -binfmt-misc-friendly,
Kirill A. Shutemov <=
[Qemu-devel] Linux user emulator maintainer, Kirill A. Shutemov, 2008/09/13
- [Qemu-devel] [PATCH] Fix vfork() syscall emulation, Kirill A. Shutemov, 2008/09/18
- [Qemu-devel] [PATCH] Fix getgroups() syscall emulation, Kirill A. Shutemov, 2008/09/18
- [Qemu-devel] [PATCH] Swap only altered elements of the grouplist, Kirill A. Shutemov, 2008/09/18
- [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI, Kirill A. Shutemov, 2008/09/18
- [Qemu-devel] [PATCH] Implement fstatat64() syscall, Kirill A. Shutemov, 2008/09/18
- [Qemu-devel] [PATCH] Implement futimesat() syscall, Kirill A. Shutemov, 2008/09/18
- [Qemu-devel] [PATCH] Imaplement ioctls MTIOCTOP, MTIOCGET and MTIOCPOS, Kirill A. Shutemov, 2008/09/18
- [Qemu-devel] [PATCH] Fix building with 2.6.27 kernel headers, Kirill A. Shutemov, 2008/09/18
- Re: [Qemu-devel] [PATCH] Fix building with 2.6.27 kernel headers, Riku Voipio, 2008/09/19