qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 07/23] bsd-user: find target executable in path when


From: Stacey Son
Subject: [Qemu-devel] [PATCH 07/23] bsd-user: find target executable in path when absolute path not given
Date: Sun, 23 Jun 2013 21:03:39 -0500

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 <address@hidden>
---
 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 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
             bprm->page[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 *);
 };
 
-- 
1.7.8




reply via email to

[Prev in Thread] Current Thread [Next in Thread]