From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KchL0-00087H-B1 for qemu-devel@nongnu.org; Mon, 08 Sep 2008 10:03:30 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KchKx-00085C-QW for qemu-devel@nongnu.org; Mon, 08 Sep 2008 10:03:28 -0400 Received: from [199.232.76.173] (port=39240 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KchKx-000851-Jg for qemu-devel@nongnu.org; Mon, 08 Sep 2008 10:03:27 -0400 Received: from nf-out-0910.google.com ([64.233.182.190]:62378) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KchKw-0007Fs-Rq for qemu-devel@nongnu.org; Mon, 08 Sep 2008 10:03:27 -0400 Received: by nf-out-0910.google.com with SMTP id b2so443313nfb.12 for ; Mon, 08 Sep 2008 07:03:25 -0700 (PDT) From: "Kirill A. Shutemov" Date: Mon, 8 Sep 2008 17:03:36 +0300 Message-Id: <1220882616-18735-8-git-send-email-kirill@shutemov.name> In-Reply-To: <1220882616-18735-7-git-send-email-kirill@shutemov.name> References: <1220882616-18735-1-git-send-email-kirill@shutemov.name> <1220882616-18735-2-git-send-email-kirill@shutemov.name> <1220882616-18735-3-git-send-email-kirill@shutemov.name> <1220882616-18735-4-git-send-email-kirill@shutemov.name> <1220882616-18735-5-git-send-email-kirill@shutemov.name> <1220882616-18735-6-git-send-email-kirill@shutemov.name> <1220882616-18735-7-git-send-email-kirill@shutemov.name> Subject: [Qemu-devel] [PATCH] Introduce option -binfmt-misc-friendly Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: "Kirill A. Shutemov" -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 --- 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 ; isigqueue_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