From patchwork Mon Jun 24 02:03:39 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stacey Son X-Patchwork-Id: 253943 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id BB9682C007C for ; Tue, 25 Jun 2013 03:55:12 +1000 (EST) Received: from localhost ([::1]:59845 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ur9xS-00019k-Ck for incoming@patchwork.ozlabs.org; Mon, 24 Jun 2013 12:49:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42053) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ur9wQ-0000eU-23 for qemu-devel@nongnu.org; Mon, 24 Jun 2013 12:48:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ur9wD-0005wE-Kq for qemu-devel@nongnu.org; Mon, 24 Jun 2013 12:48:33 -0400 Received: from cdptpa-omtalb.mail.rr.com ([75.180.132.120]:62598) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ur9wD-0005tZ-6V for qemu-devel@nongnu.org; Mon, 24 Jun 2013 12:48:21 -0400 X-Authority-Analysis: v=2.0 cv=XpZ4yC59 c=1 sm=0 a=Oa4axR4OH/tQIi4PbzyetA==:17 a=BzKiyTcfMA4A:10 a=D0lm8cmiWYwA:10 a=dBRESv0yCI8A:10 a=6I5d2MoRAAAA:8 a=KGjhK52YXX0A:10 a=ahHRRsjABrgA:10 a=ts_S5Zp5VQw1Ly9Dy3AA:9 a=SV7veod9ZcQA:10 a=Oa4axR4OH/tQIi4PbzyetA==:117 X-Cloudmark-Score: 0 X-Authenticated-User: X-Originating-IP: 76.187.137.252 Received: from [76.187.137.252] ([76.187.137.252:52973] helo=salmon.son.org) by cdptpa-oedge02.mail.rr.com (envelope-from ) (ecelerity 2.2.3.46 r()) with ESMTP id C3/1C-15971-25878C15; Mon, 24 Jun 2013 16:48:19 +0000 Received: from son.org (localhost [127.0.0.1]) by salmon.son.org (8.14.7/8.14.7) with ESMTP id r5O249Tr042007; Sun, 23 Jun 2013 21:04:09 -0500 (CDT) (envelope-from sson@son.org) Received: (from sson@localhost) by son.org (8.14.7/8.14.7/Submit) id r5O249bR042006; Sun, 23 Jun 2013 21:04:09 -0500 (CDT) (envelope-from sson) From: Stacey Son To: qemu-devel@nongnu.org Date: Sun, 23 Jun 2013 21:03:39 -0500 Message-Id: <1372039435-41921-8-git-send-email-sson@FreeBSD.org> X-Mailer: git-send-email 1.7.8 In-Reply-To: <1372039435-41921-1-git-send-email-sson@FreeBSD.org> References: <1372039435-41921-1-git-send-email-sson@FreeBSD.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 75.180.132.120 Cc: Stacey Son Subject: [Qemu-devel] [PATCH 07/23] bsd-user: find target executable in path when absolute path not given X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org If the target executable's path is not absolute then this code will search the PATH to find it. Save the fullpath to put on to the stack for the runtime linker. Signed-off-by: Stacey Son --- bsd-user/bsdload.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++-- bsd-user/qemu.h | 3 +- 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c index cc4f534..c768855 100644 --- a/bsd-user/bsdload.c +++ b/bsd-user/bsdload.c @@ -169,19 +169,95 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, return sp; } +static int is_there(const char *candidate) +{ + struct stat fin; + + /* XXX work around access(2) false positives for superuser */ + if (access(candidate, X_OK) == 0 && stat(candidate, &fin) == 0 && + S_ISREG(fin.st_mode) && (getuid() != 0 || + (fin.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)) { + return 1; + } + + return 0; +} + +static int find_in_path(char *path, const char *filename, char *retpath, + size_t rpsize) +{ + const char *d; + int found; + + if (strchr(filename, '/') != NULL) { + if (is_there(filename)) { + if (!realpath(filename, retpath)) { + return -1; + } + return 0; + } else { + return -1; + } + } + + found = 0; + while ((d = strsep(&path, ":")) != NULL) { + if (*d == '\0') { + d = "."; + } + if (snprintf(retpath, rpsize, "%s/%s", d, filename) >= (int)rpsize) { + continue; + } + if (is_there((const char *)retpath)) { + found = 1; + break; + } + } + return found; +} + int loader_exec(const char * filename, char ** argv, char ** envp, struct target_pt_regs *regs, struct image_info *infop, struct bsd_binprm *bprm) { - int retval; - int i; + char *p, *path = NULL, fullpath[PATH_MAX]; + const char *execname = NULL; + int retval, i; - bprm->p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int); + bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES; /* -sizeof(unsigned int); */ for (i=0 ; ipage[i] = NULL; - retval = open(filename, O_RDONLY); + + /* Find target executable in path, if not already an absolute path. */ + p = getenv("PATH"); + if (p != NULL) { + path = g_strdup(p); + if (path == NULL) { + fprintf(stderr, "Out of memory\n"); + return -1; + } + execname = realpath(filename, NULL); + if (execname == NULL) { + execname = filename; + } + if (!find_in_path(path, execname, fullpath, sizeof(fullpath))) { + retval = open(fullpath, O_RDONLY); + bprm->fullpath = g_strdup(fullpath); + } else { + retval = open(execname, O_RDONLY); + bprm->fullpath = NULL; + } + if (execname) { + free((void *)execname); + } + free(path); + } else { + retval = open(filename, O_RDONLY); + bprm->fullpath = NULL; + } if (retval < 0) return retval; + bprm->fd = retval; bprm->filename = (char *)filename; bprm->argc = count(argv); diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index a36e9d2..1e2abd5 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -128,7 +128,8 @@ struct bsd_binprm { int argc, envc; char **argv; char **envp; - char *filename; /* Name of binary */ + char *filename; /* (Given) Name of binary */ + char *fullpath; /* Full path of binary */ int (*core_dump)(int, const CPUArchState *); };