From patchwork Wed May 25 16:07:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Holdsworth X-Patchwork-Id: 9135719 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E232A6075C for ; Wed, 25 May 2016 16:08:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D3C92282D4 for ; Wed, 25 May 2016 16:08:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C8AF2282DA; Wed, 25 May 2016 16:08:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1BFBC282B3 for ; Wed, 25 May 2016 16:08:20 +0000 (UTC) Received: from localhost ([::1]:33866 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5bM3-0005pO-7U for patchwork-qemu-devel@patchwork.kernel.org; Wed, 25 May 2016 12:08:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50459) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5bKb-0004x9-Rp for qemu-devel@nongnu.org; Wed, 25 May 2016 12:06:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b5bKV-0002oI-G3 for qemu-devel@nongnu.org; Wed, 25 May 2016 12:06:49 -0400 Received: from mail-ig0-x22e.google.com ([2607:f8b0:4001:c05::22e]:38773) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5bKV-0002oE-A5 for qemu-devel@nongnu.org; Wed, 25 May 2016 12:06:43 -0400 Received: by mail-ig0-x22e.google.com with SMTP id fh2so31279739igd.1 for ; Wed, 25 May 2016 09:06:43 -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=XsQt+D2K/54DZ9aouvfP5fVgUtOYuUCdV/ll7x9+gH8=; b=eUfNlcXHMeJGu7ZSJRFUO3Mos5s/Aa4aE98a5YksGTb93V7pJ1SELRMwt4C9dN2Chq fq0IzSTMElOLcf2MsCpJXyOTCNoaZAfT6ULW/qlM91Z+tVBJJ6Yf64k/xFM9iczidwkF 7QqRiWrN+SvKH5GxKLtaeasaWKXmZNwEdcqGBxB0fnYFMAuKnZ2edTnwHRb63qnu7h7b zrljJpo/UOvW05wku3n+uRnEYCysW/KzETIMWzZydTZdH50oS0VSLCX/PdJu6HpxugKh vdvZX6ml2luAIDWgeJ0LxnDVz1CC4F4AVzYVkSLqnqXYsjRU12KiLKoe13+wx6y0DKke JE+Q== 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=XsQt+D2K/54DZ9aouvfP5fVgUtOYuUCdV/ll7x9+gH8=; b=N93EWu4vlYFfQR3XF07NDrN6DY1+SBGVUblp741KFsRCDzpCkXeqSNI27WQC1HPndb 4yo/2cTAw8BQ87tV/8QHGBHwfKTJKxXYTT5i3xiTfsT4hL6EORtVqk7CrccECAjkeT/R 6E6ndL3sFL8lozomSTAGm7ncoHQ5J5Ch6+s5q+5cbnqg/AFTKDTwB1yvrwhkw9yBom8O bUMDsgZxVdOxzEq+p+LCSmxBOaPsrZ567fklpGDNomgw262pbJQZuML5Wdkvb9EpX/LY BKC0V1902WESdmbVJCYaOhQGq5bw88WYshqCnJ/RlMME0jAIQID5AdhbQQ5ryxC5IuXu e0OQ== X-Gm-Message-State: AOPr4FUnGuXMNUMXhZ9gLrJSbTVp2xfMoxxUKTpHtk0jxs3vkkDpTGtIgz2FN4xbKSX7D3tU X-Received: by 10.50.205.8 with SMTP id lc8mr23886965igc.94.1464192402793; Wed, 25 May 2016 09:06:42 -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 d196sm2975958ioe.41.2016.05.25.09.06.41 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 25 May 2016 09:06:42 -0700 (PDT) From: Joel Holdsworth To: qemu-devel@nongnu.org Date: Wed, 25 May 2016 17:07:50 +0100 Message-Id: <1464192472-7885-3-git-send-email-joel.holdsworth@vcatechnology.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1464192472-7885-1-git-send-email-joel.holdsworth@vcatechnology.com> References: <1464192472-7885-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:c05::22e Subject: [Qemu-devel] [PATCH 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+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 750e381..b95f75a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5853,9 +5853,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 */ @@ -5863,10 +5867,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); @@ -5927,37 +5933,75 @@ 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 *)); + 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(envp[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; + 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]; } - return get_errno(execve(qemu_execve_path, new_argp, envp)); + *argp++ = filename; + + /* copy the original arguments with offset */ + for (i = 1; i < argc; i++) + *argp++ = argv[i]; + + *argp++ = NULL; + + return get_errno(execv(qemu_execve_path, qemu_argp)); } /* do_syscall() should always have a single exit point at the end so