X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=bsd-user%2Fbsdload.c;h=5b3c061a452a6025eb0fe54f34d24a02ec4c8938;hb=9d14db15b121c81a008098c46053d98cd6a0da6b;hp=379015c74441f6aa9906fadf775d7947388c540b;hpb=223005f0584ece2868b0b5ac11b06f3984aad569;p=mirror_qemu.git diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c index 379015c744..5b3c061a45 100644 --- a/bsd-user/bsdload.c +++ b/bsd-user/bsdload.c @@ -19,8 +19,6 @@ #include "qemu.h" -#define TARGET_NGROUPS 32 - /* ??? This should really be somewhere else. */ abi_long memcpy_to_target(abi_ulong dest, const void *src, unsigned long len) @@ -98,7 +96,7 @@ static int prepare_binprm(struct bsd_binprm *bprm) /* Construct the envp and argv tables on the target stack. */ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, - abi_ulong stringp, int push_ptr) + abi_ulong stringp) { int n = sizeof(abi_ulong); abi_ulong envp; @@ -108,13 +106,6 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, envp = sp; sp -= (argc + 1) * n; argv = sp; - if (push_ptr) { - /* FIXME - handle put_user() failures */ - sp -= n; - put_user_ual(envp, sp); - sp -= n; - put_user_ual(argv, sp); - } sp -= n; /* FIXME - handle put_user() failures */ put_user_ual(argc, sp); @@ -139,21 +130,55 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, return sp; } +static bool 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 true; + } + + return false; +} + int loader_exec(const char *filename, char **argv, char **envp, struct target_pt_regs *regs, struct image_info *infop, struct bsd_binprm *bprm) { + char *path, fullpath[PATH_MAX]; int retval, i; bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES; for (i = 0; i < MAX_ARG_PAGES; i++) { /* clear page-table */ bprm->page[i] = NULL; } - retval = open(filename, O_RDONLY); + + if (strchr(filename, '/') != NULL) { + path = realpath(filename, fullpath); + if (path == NULL) { + /* Failed to resolve. */ + return -1; + } + if (!is_there(path)) { + return -1; + } + } else { + path = g_find_program_in_path(filename); + if (path == NULL) { + return -1; + } + } + + retval = open(path, O_RDONLY); if (retval < 0) { + g_free(path); return retval; } + bprm->fullpath = path; bprm->fd = retval; bprm->filename = (char *)filename; bprm->argc = count(argv);