From patchwork Tue Jun 14 19:26:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Holdsworth X-Patchwork-Id: 635513 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rTfrw2dz2z9t0q for ; Wed, 15 Jun 2016 05:31:12 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=vcatechnology-com.20150623.gappssmtp.com header.i=@vcatechnology-com.20150623.gappssmtp.com header.b=ylz1FARz; dkim-atps=neutral Received: from localhost ([::1]:37687 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCu3K-0006bR-A5 for incoming@patchwork.ozlabs.org; Tue, 14 Jun 2016 15:31:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50854) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCtyx-0002RE-Mm for qemu-devel@nongnu.org; Tue, 14 Jun 2016 15:26:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bCtyr-00026B-9F for qemu-devel@nongnu.org; Tue, 14 Jun 2016 15:26:38 -0400 Received: from mail-it0-x22d.google.com ([2607:f8b0:4001:c0b::22d]:35669) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCtyr-000267-3b for qemu-devel@nongnu.org; Tue, 14 Jun 2016 15:26:33 -0400 Received: by mail-it0-x22d.google.com with SMTP id z189so86501438itg.0 for ; Tue, 14 Jun 2016 12:26:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vcatechnology-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0KIoIYKzh8fnX/7bPBQZqeAlekWASugvru0tgUxv1ow=; b=ylz1FARzfjpLjdZjzLxuraXBSdYoWTuVmtqGIau3wq49RIWS4n3y4n6HBTaVREvITm 4yKE0BClRQ6gWMke2O1wpc9VwNztgIXzZtd4hB9aQUqWm/0YD+ZALalD3FYg2gQ9sXf0 W7KWdAnO8wjzibFEydIi5nht87Gq7TlDzKl9Oc3txYmz19LHhy1VouPeVOO26/WlSmxE 2Uhvw2AqehfOjX/VCrueccnWFfrdRKMov61xGQ8j7oPerTZcQ5Zf1m9rQjIxB6LvQwtD 3pDc0XDwE0Jc0MfNzU5S7fKoAcLf1wdlyfPo2LQLlFwZj1GHjmvtuJYymgj4Ct3+tFsE f1iQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=0KIoIYKzh8fnX/7bPBQZqeAlekWASugvru0tgUxv1ow=; b=T5KmBuo6BacZ76SX6RgjHJK8muFN7JyC0M9cccAk/9tJXAL1cuBga/nmVu95vTYr4S 9K9XguIpCbHsilYC6GMdJPOKPoGmZ0sf35OIX4VbA9NABSka4VBqU+E5RJx/N/rommd2 Mtp+nkXhpslXHmrKrao4c5jSHKGsfLPxToY8BAkwee2UL8tlenX758iMCOdkKVUuQ5jq WDtINJUnfUe/hQn810LfNvUdWRfnzEb57vngTjfGOhZatolkXZNuvhgPPCjeCzYQY0Co BCdD5egfnG7gDxXm20mVsZaZLXQPlXwUzDxxY685epRbhUwrantTRa6JHHEXL//OxmLR 7DHA== X-Gm-Message-State: ALyK8tJgMB9wWcto3lHho39icTJbMzL56ToZZ7/cEz5agmkODYl8Hq411n1lH4T0aT4tcFiB X-Received: by 10.36.10.65 with SMTP id 62mr10902173itw.89.1465932392542; Tue, 14 Jun 2016 12:26:32 -0700 (PDT) Received: from localhost.localdomain (50-205-134-174-static.hfc.comcastbusiness.net. [50.205.134.174]) by smtp.googlemail.com with ESMTPSA id w10sm2509039itc.1.2016.06.14.12.26.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 14 Jun 2016 12:26:32 -0700 (PDT) From: Joel Holdsworth To: qemu-devel@nongnu.org Date: Tue, 14 Jun 2016 20:26:20 +0100 Message-Id: <1465932382-28645-3-git-send-email-joel.holdsworth@vcatechnology.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1465932382-28645-1-git-send-email-joel.holdsworth@vcatechnology.com> References: <1465932382-28645-1-git-send-email-joel.holdsworth@vcatechnology.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:4001:c0b::22d Subject: [Qemu-devel] [PATCH v2 2/4] linux-user: pass environment arguments in execve X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: riku.voipio@iki.fi, Vasileios.Kalintiris@imgtec.com, Joel Holdsworth Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Previously, when emulating execve(2), qemu would execute a child instance of the emulator with the environment variables provided by the parent process. This caused problems with qemu if any of the variables affected the child emulator's behaviour e.g. LD_LIBRARY_PATH. This patch solves this issue by passing the environment variables with '-E' arguments to the child qemu instance. The call to execve(2) is replaced by a call to execv(2) so that the parent emulator's environment variable state is propagated into the child. Any variables from the host environment that are not in the in the execve() call are removed with a '-U' argument. --- linux-user/syscall.c | 96 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 26 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a478f56..440986e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6665,9 +6665,13 @@ static abi_long qemu_execve(char *filename, char *argv[], char *envp[]) { char *i_arg = NULL, *i_name = NULL; - char **new_argp; - int argc, fd, ret, i, offset = 3; + char **qemu_argp, **argp; + int i, j; + size_t qemu_argc = 3, argc, host_envc, envpc; + int fd, ret; char *cp; + size_t def_envc = 0, undef_envc = 0; + char **def_env, **undef_env; char buf[BINPRM_BUF_SIZE]; /* normal execve case */ @@ -6675,10 +6679,12 @@ static abi_long qemu_execve(char *filename, char *argv[], return get_errno(execve(filename, argv, envp)); } - for (argc = 0; argv[argc] != NULL; argc++) { - /* nothing */ ; - } + /* count the number of arguments and environment variables */ + for (argc = 0; argv[argc]; argc++); + for (host_envc = 0; environ[host_envc]; host_envc++); + for (envpc = 0; envp[envpc]; envpc++); + /* read the file header so we can check the shebang */ fd = open(filename, O_RDONLY); if (fd == -1) { return get_errno(fd); @@ -6739,36 +6745,74 @@ static abi_long qemu_execve(char *filename, char *argv[], i_arg = cp; } - if (i_arg) { - offset = 5; - } else { - offset = 4; - } + if (i_arg) + qemu_argc += 2; + else + qemu_argc += 1; + } + + /* list environment variables to define */ + def_env = alloca((envpc + 1) * sizeof(envp[0])); + for (i = 0; i != envpc; i++) { + for (j = 0; j != host_envc; j++) + if (!strcmp(envp[i], environ[j])) + break; + if (j == host_envc) + def_env[def_envc++] = envp[i]; } - new_argp = alloca((argc + offset + 1) * sizeof(void *)); + qemu_argc += def_envc * 2; - /* Copy the original arguments with offset */ - for (i = 0; i < argc; i++) { - new_argp[i + offset] = argv[i]; + /* list environment variables to undefine */ + undef_env = alloca((host_envc + 1) * sizeof(undef_env[0])); + for (i = 0; i != host_envc; i++) { + const char *const host_env = environ[i]; + const size_t key_len = strchr(host_env, '=') - host_env; + for (j = 0; j != envpc; j++) + if (!strncmp(host_env, envp[j], key_len)) + break; + if (j == envpc) + undef_env[undef_envc++] = strndup(environ[i], key_len); } - new_argp[0] = strdup(qemu_execve_path); - new_argp[1] = strdup("-0"); - new_argp[offset] = filename; - new_argp[argc + offset] = NULL; + qemu_argc += undef_envc * 2; - if (i_name) { - new_argp[2] = i_name; - new_argp[3] = i_name; + /* allocate the argument list */ + argp = qemu_argp = alloca((qemu_argc + 1) * sizeof(void *)); - if (i_arg) { - new_argp[4] = i_arg; - } + /* set up the qemu arguments */ + *argp++ = strdup(qemu_execve_path); + + /* add arguments for the enironment variables */ + for (i = 0; i < def_envc; i++) { + *argp++ = strdup("-E"); + *argp++ = def_env[i]; + } + + for (i = 0; i < undef_envc; i++) { + *argp++ = strdup("-U"); + *argp++ = undef_env[i]; + } + + /* add the path to the executable */ + *argp++ = strdup("-0"); + if (i_name) { + *argp++ = i_name; + *argp++ = i_name; + if (i_arg) + *argp++ = i_arg; } else { - new_argp[2] = argv[0]; + *argp++ = argv[0]; } + *argp++ = filename; + + /* copy the original arguments with offset */ + for (i = 1; i < argc; i++) + *argp++ = argv[i]; + + *argp++ = NULL; + /* Although execve() is not an interruptible syscall it is * a special case where we must use the safe_syscall wrapper: * if we allow a signal to happen before we make the host @@ -6779,7 +6823,7 @@ static abi_long qemu_execve(char *filename, char *argv[], * before the execve completes and makes it the other * program's problem. */ - return get_errno(safe_execve(qemu_execve_path, new_argp, envp)); + return get_errno(safe_execve(qemu_execve_path, qemu_argp, environ)); } /* do_syscall() should always have a single exit point at the end so