Bug#632192: [PATCH] introduce environment variables for all qemu-user options

2011-08-20 Thread Yann Dirson
This patch will be useful, but there is a security problem in its
current form.  The qemu-user-static package installs binfmt-misc
entries with "flags: OC", which makes the binary honor setuid bits.

Regardless of whether it is a good idea or not, the envvars ought to
be ignored in such a case.  Some clever checks using getresuid(), or
just geteuid() and getuid() when getresuid() is not available, surely
have to done.  There is probably some existing code for this in other
programs...

Best regards,
-- 
Yann



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Bug#632192: [PATCH] introduce environment variables for all qemu-user options

2011-08-05 Thread Johannes Schauer
Rework option parsing code for linux-user in a table-driven manner to allow
environment variables for all commandline options.

Also generate usage() output from option table.

Fix complains from checkpatch.pl, also have envlist global


Signed-off-by: Johannes Schauer 
---
 linux-user/main.c |  530 ++---
 1 files changed, 342 insertions(+), 188 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index dbba8be..74c5198 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -40,6 +40,11 @@
 char *exec_path;
 
 int singlestep;
+const char *filename;
+const char *argv0;
+int gdbstub_port;
+envlist_t *envlist;
+const char *cpu_model;
 unsigned long mmap_min_addr;
 #if defined(CONFIG_USE_GUEST_BASE)
 unsigned long guest_base;
@@ -47,6 +52,8 @@ int have_guest_base;
 unsigned long reserved_va;
 #endif
 
+static void usage(void);
+
 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 
@@ -2624,50 +2631,6 @@ void cpu_loop (CPUState *env)
 }
 #endif /* TARGET_ALPHA */
 
-static void usage(void)
-{
-printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION ", 
Copyright (c) 2003-2008 Fabrice Bellard\n"
-   "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
-   "Linux CPU emulator (compiled for %s emulation)\n"
-   "\n"
-   "Standard options:\n"
-   "-hprint 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 modelselect CPU (-cpu ? for list)\n"
-   "-drop-ld-preload  drop LD_PRELOAD for target process\n"
-   "-E var=value  sets/modifies targets environment variable(s)\n"
-   "-U varunsets targets environment variable(s)\n"
-   "-0 argv0  forces target process argv[0] to be argv0\n"
-#if defined(CONFIG_USE_GUEST_BASE)
-   "-B addressset guest_base address to address\n"
-   "-R size   reserve size bytes for guest virtual address 
space\n"
-#endif
-   "\n"
-   "Debug options:\n"
-   "-d options   activate log (logfile=%s)\n"
-   "-p pagesize  set the host page size to 'pagesize'\n"
-   "-singlestep  always run in singlestep mode\n"
-   "-strace  log system calls\n"
-   "\n"
-   "Environment variables:\n"
-   "QEMU_STRACE   Print system calls and arguments similar to 
the\n"
-   "  'strace' program.  Enable by setting to any 
value.\n"
-   "You can use -E and -U options to set/unset environment variables\n"
-   "for target process.  It is possible to provide several variables\n"
-   "by repeating the option.  For example:\n"
-   "-E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
-   "Note that if you provide several changes to single variable\n"
-   "last change will stay in effect.\n"
-   ,
-   TARGET_ARCH,
-   interp_prefix,
-   guest_stack_size,
-   DEBUG_LOGFILE);
-exit(1);
-}
-
 THREAD CPUState *thread_env;
 
 void task_settid(TaskState *ts)
@@ -2703,24 +2666,351 @@ void init_task_state(TaskState *ts)
 }
 ts->sigqueue_table[i].next = NULL;
 }
- 
+
+static void handle_arg_help(const char *arg)
+{
+usage();
+}
+
+static void handle_arg_log(const char *arg)
+{
+int mask;
+const CPULogItem *item;
+
+mask = cpu_str_to_log_mask(arg);
+if (!mask) {
+printf("Log items (comma separated):\n");
+for (item = cpu_log_items; item->mask != 0; item++) {
+printf("%-10s %s\n", item->name, item->help);
+}
+exit(1);
+}
+cpu_set_log(mask);
+}
+
+static void handle_arg_set_env(const char *arg)
+{
+char *r, *p, *token;
+r = p = strdup(arg);
+while ((token = strsep(&p, ",")) != NULL) {
+if (envlist_setenv(envlist, token) != 0) {
+usage();
+}
+}
+free(r);
+}
+
+static void handle_arg_unset_env(const char *arg)
+{
+char *r, *p, *token;
+r = p = strdup(arg);
+while ((token = strsep(&p, ",")) != NULL) {
+if (envlist_unsetenv(envlist, token) != 0) {
+usage();
+}
+}
+free(r);
+}
+
+static void handle_arg_argv0(const char *arg)
+{
+argv0 = strdup(arg);
+}
+
+static void handle_arg_stack_size(const char *arg)
+{
+char *p;
+guest_stack_size = strtoul(arg, &p, 0);
+if (guest_stack_size == 0) {
+usage();
+}
+
+if (*p == 'M') {
+guest_stack_size *= 1024 * 1024;
+} else if (*p == 'k' || *p == 'K') {
+guest_stack_size *= 1024;
+}
+}
+
+static void handle_arg_ld_prefix(const char *arg)
+{
+interp_prefix = strdup(arg);
+}
+
+s

Bug#632192: [PATCH] introduce environment variables for all qemu-user options

2011-08-05 Thread Peter Maydell
On 31 July 2011 22:40, Johannes Schauer  wrote:
> Rework option parsing code for linux-user in a table-driven manner to allow
> environment variables for all commandline options.
>
> Also generate usage() output from option table.

Thanks for this, it looks good. A couple of minor points:
(1) what's the rationale for having most of the things the
arg-parsing-functions change be global variables but passing
envlist as an argument to each function? It's only used by
two of the functions so maybe that should just be a global too.
(2) scripts/checkpatch.pl complains about a number of formatting
nits; mostly these are in existing code you've just moved around,
but I think it's worth fixing them in passing anyway.

-- PMM



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org



Bug#632192: [PATCH] introduce environment variables for all qemu-user options

2011-07-31 Thread Johannes Schauer
Rework option parsing code for linux-user in a table-driven manner to allow
environment variables for all commandline options.

Also generate usage() output from option table.



Signed-off-by: Johannes Schauer 
---
 linux-user/main.c |  518 ++---
 1 files changed, 331 insertions(+), 187 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index dbba8be..95e8651 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -40,6 +40,10 @@
 char *exec_path;
 
 int singlestep;
+const char *filename;
+const char *argv0 = NULL;
+int gdbstub_port = 0;
+const char *cpu_model;
 unsigned long mmap_min_addr;
 #if defined(CONFIG_USE_GUEST_BASE)
 unsigned long guest_base;
@@ -47,6 +51,8 @@ int have_guest_base;
 unsigned long reserved_va;
 #endif
 
+static void usage(void);
+
 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 
@@ -2624,50 +2630,6 @@ void cpu_loop (CPUState *env)
 }
 #endif /* TARGET_ALPHA */
 
-static void usage(void)
-{
-printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION ", 
Copyright (c) 2003-2008 Fabrice Bellard\n"
-   "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
-   "Linux CPU emulator (compiled for %s emulation)\n"
-   "\n"
-   "Standard options:\n"
-   "-hprint 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 modelselect CPU (-cpu ? for list)\n"
-   "-drop-ld-preload  drop LD_PRELOAD for target process\n"
-   "-E var=value  sets/modifies targets environment variable(s)\n"
-   "-U varunsets targets environment variable(s)\n"
-   "-0 argv0  forces target process argv[0] to be argv0\n"
-#if defined(CONFIG_USE_GUEST_BASE)
-   "-B addressset guest_base address to address\n"
-   "-R size   reserve size bytes for guest virtual address 
space\n"
-#endif
-   "\n"
-   "Debug options:\n"
-   "-d options   activate log (logfile=%s)\n"
-   "-p pagesize  set the host page size to 'pagesize'\n"
-   "-singlestep  always run in singlestep mode\n"
-   "-strace  log system calls\n"
-   "\n"
-   "Environment variables:\n"
-   "QEMU_STRACE   Print system calls and arguments similar to 
the\n"
-   "  'strace' program.  Enable by setting to any 
value.\n"
-   "You can use -E and -U options to set/unset environment variables\n"
-   "for target process.  It is possible to provide several variables\n"
-   "by repeating the option.  For example:\n"
-   "-E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
-   "Note that if you provide several changes to single variable\n"
-   "last change will stay in effect.\n"
-   ,
-   TARGET_ARCH,
-   interp_prefix,
-   guest_stack_size,
-   DEBUG_LOGFILE);
-exit(1);
-}
-
 THREAD CPUState *thread_env;
 
 void task_settid(TaskState *ts)
@@ -2703,24 +2665,342 @@ void init_task_state(TaskState *ts)
 }
 ts->sigqueue_table[i].next = NULL;
 }
- 
+
+static void handle_arg_help(const char *arg, envlist_t *envlist)
+{
+usage();
+}
+
+static void handle_arg_log(const char *arg, envlist_t *envlist)
+{
+int mask;
+const CPULogItem *item;
+
+mask = cpu_str_to_log_mask(arg);
+if (!mask) {
+printf("Log items (comma separated):\n");
+for(item = cpu_log_items; item->mask != 0; item++) {
+printf("%-10s %s\n", item->name, item->help);
+}
+exit(1);
+}
+cpu_set_log(mask);
+}
+
+static void handle_arg_set_env(const char *arg, envlist_t *envlist)
+{
+char *r, *p, *token;
+r = p = strdup(arg);
+while ((token = strsep(&p, ",")) != NULL) {
+if (envlist_setenv(envlist, token) != 0)
+usage();
+}
+free(r);
+}
+
+static void handle_arg_unset_env(const char *arg, envlist_t *envlist)
+{
+char *r, *p, *token;
+r = p = strdup(arg);
+while ((token = strsep(&p, ",")) != NULL) {
+if (envlist_unsetenv(envlist, token) != 0)
+usage();
+}
+free(r);
+}
+
+static void handle_arg_argv0(const char *arg, envlist_t *envlist)
+{
+argv0 = strdup(arg);
+}
+
+static void handle_arg_stack_size(const char *arg, envlist_t *envlist)
+{
+char *p;
+guest_stack_size = strtoul(arg, &p, 0);
+if (guest_stack_size == 0)
+usage();
+if (*p == 'M')
+guest_stack_size *= 1024 * 1024;
+else if (*p == 'k' || *p == 'K')
+guest_stack_size *= 1024;
+}
+
+static void handle_arg_ld_prefix(const char *arg, envlist_t *envlist)
+{
+interp_prefix = 

Bug#632192: [PATCH] introduce environment variables for all qemu-user options

2011-07-31 Thread j . schauer
From: Johannes Schauer 

A first try to introduce a generic setup for mapping environment variables to
command line options.

I'm afraid to code something for platforms I can't do runtime tests on, so this 
is only for linux-user for now.

Signed-off-by: Johannes Schauer 
---
 linux-user/main.c |  147 +++-
 1 files changed, 144 insertions(+), 3 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index dbba8be..fb986e3 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2640,26 +2640,51 @@ static void usage(void)
"-E var=value  sets/modifies targets environment variable(s)\n"
"-U varunsets targets environment variable(s)\n"
"-0 argv0  forces target process argv[0] to be argv0\n"
+   "-r uname  set qemu uname release string\n"
 #if defined(CONFIG_USE_GUEST_BASE)
"-B addressset guest_base address to address\n"
"-R size   reserve size bytes for guest virtual address 
space\n"
 #endif
"\n"
+   "Standard environment variables:\n"
+   "QEMU_GDB  see the -g option\n"
+   "QEMU_LD_PREFIXsee the -L option\n"
+   "QEMU_STACK_SIZE   see the -s option\n"
+   "QEMU_CPU  see the -cpu option\n"
+   "QEMU_SET_ENV  see the -E option, comma separated list of 
arguments\n"
+   "QEMU_UNSET_ENVsee the -U option, comma separated list of 
arguments\n"
+   "QEMU_ARGV0see the -0 option\n"
+   "QEMU_UNAMEsee the -r option\n"
+#if defined(CONFIG_USE_GUEST_BASE)
+   "QEMU_GUEST_BASE   see the -B option\n"
+   "QEMU_RESERVED_VA  see the -R option\n"
+#endif
+   "\n"
"Debug options:\n"
"-d options   activate log (logfile=%s)\n"
"-p pagesize  set the host page size to 'pagesize'\n"
"-singlestep  always run in singlestep mode\n"
"-strace  log system calls\n"
"\n"
-   "Environment variables:\n"
-   "QEMU_STRACE   Print system calls and arguments similar to 
the\n"
-   "  'strace' program.  Enable by setting to any 
value.\n"
+   "Debug environment variables:\n"
+   "QEMU_LOG  see the -d option\n"
+   "QEMU_PAGESIZE see the -p option\n"
+   "QEMU_SINGLESTEP   see the -singlestep option\n"
+   "QEMU_STRACE   see the -strace option\n"
+   "\n"
"You can use -E and -U options to set/unset environment variables\n"
"for target process.  It is possible to provide several variables\n"
"by repeating the option.  For example:\n"
"-E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
"Note that if you provide several changes to single variable\n"
"last change will stay in effect.\n"
+   "Using the environment variables QEMU_SET_ENV and QEMU_UNSET_ENV\n"
+   "to set/unset environment variables for target process is\n"
+   "possible by a comma separated list of values in getsubopt(3)\n"
+   "style. For example:\n"
+   "QEMU_SET_ENV=var1=val2,var2=val2 
QEMU_UNSET_ENV=LD_PRELOAD,LD_DEBUG\n"
+   "Note that if you provide several changes to single variable\n"
+   "last change will stay in effect.\n"
,
TARGET_ARCH,
interp_prefix,
@@ -2758,6 +2783,122 @@ int main(int argc, char **argv, char **envp)
 cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
 #endif
 
+if ((r = getenv("QEMU_LOG")) != NULL) {
+int mask;
+const CPULogItem *item;
+mask = cpu_str_to_log_mask(r);
+if (!mask) {
+printf("Log items (comma separated):\n");
+for(item = cpu_log_items; item->mask != 0; item++) {
+printf("%-10s %s\n", item->name, item->help);
+}
+exit(1);
+}
+cpu_set_log(mask);
+}
+if ((r = getenv("QEMU_SET_ENV")) != NULL) {
+char *p, *token;
+p = strdup(r);
+while ((token = strsep(&p, ",")) != NULL) {
+if (envlist_setenv(envlist, token) != 0)
+usage();
+}
+free(p);
+}
+if ((r = getenv("QEMU_UNSET_ENV")) != NULL) {
+char *p, *token;
+p = strdup(r);
+while ((token = strsep(&p, ",")) != NULL) {
+if (envlist_unsetenv(envlist, token) != 0)
+usage();
+}
+free(p);
+}
+if ((r = getenv("QEMU_ARGV0")) != NULL) {
+argv0 = strdup(r);
+}
+if ((r = getenv("QEMU_STACK_SIZE")) != NULL) {
+guest_stack_size = strtoul(r, (char **)&r, 0);
+if (guest_stack_size == 0)
+usage();
+if (*r == 'M')
+guest_stack_size *= 1024 * 1024;
+else if (*r == 'k' || *r ==