From: "Kirill A. Shutemov" <kirill@shutemov.name>
To: qemu-devel@nongnu.org
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Subject: [Qemu-devel] [PATCH] Introduce option -binfmt-misc-friendly
Date: Mon, 8 Sep 2008 17:03:36 +0300 [thread overview]
Message-ID: <1220882616-18735-8-git-send-email-kirill@shutemov.name> (raw)
In-Reply-To: <1220882616-18735-7-git-send-email-kirill@shutemov.name>
-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 <kirill@shutemov.name>
---
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
next prev parent reply other threads:[~2008-09-08 14:03 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-08 14:03 [Qemu-devel] [PATCH] Fix vfork() syscall emulation Kirill A. Shutemov
2008-09-08 14:03 ` [Qemu-devel] [PATCH] Fix getgroups() " Kirill A. Shutemov
2008-09-08 14:03 ` [Qemu-devel] [PATCH] Swap only altered elements of the grouplist Kirill A. Shutemov
2008-09-08 14:03 ` [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI Kirill A. Shutemov
2008-09-08 14:03 ` [Qemu-devel] [PATCH] Implement syscall fstatat64() Kirill A. Shutemov
2008-09-08 14:03 ` [Qemu-devel] [PATCH] Implement futimesat() syscall Kirill A. Shutemov
2008-09-08 14:03 ` [Qemu-devel] [PATCH] Imaplement ioctls MTIOCTOP, MTIOCGET and MTIOCPOS Kirill A. Shutemov
2008-09-08 14:03 ` Kirill A. Shutemov [this message]
2008-09-13 19:41 ` [Qemu-devel] Linux user emulator maintainer Kirill A. Shutemov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1220882616-18735-8-git-send-email-kirill@shutemov.name \
--to=kirill@shutemov.name \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).