Source-Changes-HG archive

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

[src/trunk]: src/sys/kern On non absolute exec pathnames, prepend the working...



details:   https://anonhg.NetBSD.org/src/rev/baa18df76c2d
branches:  trunk
changeset: 340529:baa18df76c2d
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Sep 11 01:23:37 2015 +0000

description:
On non absolute exec pathnames, prepend the working directory if
possible so that we can provide in most situations the absolute
pathname in the AUX vector so that $ORIGIN works. The following
are implementation issues:
    1. deep path execs still don't work (can't provide path to the AUX vector)
    2. the returned path is not normalized (cosmetic)

diffstat:

 sys/kern/kern_exec.c |  83 +++++++++++++++++++++++++++++++++------------------
 1 files changed, 53 insertions(+), 30 deletions(-)

diffs (135 lines):

diff -r defacb560695 -r baa18df76c2d sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c      Thu Sep 10 19:57:48 2015 +0000
+++ b/sys/kern/kern_exec.c      Fri Sep 11 01:23:37 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exec.c,v 1.413 2015/07/31 07:37:17 maxv Exp $     */
+/*     $NetBSD: kern_exec.c,v 1.414 2015/09/11 01:23:37 christos Exp $ */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.413 2015/07/31 07:37:17 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.414 2015/09/11 01:23:37 christos Exp $");
 
 #include "opt_exec.h"
 #include "opt_execfmt.h"
@@ -79,6 +79,7 @@
 #include <sys/namei.h>
 #include <sys/vnode.h>
 #include <sys/file.h>
+#include <sys/filedesc.h>
 #include <sys/acct.h>
 #include <sys/atomic.h>
 #include <sys/exec.h>
@@ -592,6 +593,51 @@
 #endif
 }
 
+static struct pathbuf *
+makepathbuf(struct lwp *l, const char *upath)
+{
+       char *path, *bp;
+       size_t len;
+       int error;
+       struct cwdinfo *cwdi;
+
+       path = PNBUF_GET();
+       error = copyinstr(upath, path, MAXPATHLEN, &len);
+       if (error) {
+               PNBUF_PUT(path);
+               DPRINTF(("%s: copyin path @%p %d\n", __func__, upath, error));
+               return NULL;
+       }
+
+       if (path[0] == '/')
+               goto out;
+
+       len++;
+       if (len + 1 >= MAXPATHLEN)
+               goto out;
+       bp = path + MAXPATHLEN - len;
+       memmove(bp, path, len);
+       *(--bp) = '/';
+
+       cwdi = l->l_proc->p_cwdi; 
+       rw_enter(&cwdi->cwdi_lock, RW_READER);
+       error = getcwd_common(cwdi->cwdi_cdir, NULL, &bp, path, MAXPATHLEN / 2,
+           GETCWD_CHECK_ACCESS, l);
+       rw_exit(&cwdi->cwdi_lock);
+
+       if (error) {
+               DPRINTF(("%s: getcwd_common path %s %d\n", __func__, path,
+                   error));
+               goto out;
+       }
+       len = path + MAXPATHLEN - bp;
+
+       memmove(path, bp, len);
+       path[len] = '\0';
+out:
+       return pathbuf_assimilate(path);
+}
+
 static int
 execve_loadvm(struct lwp *l, const char *path, char * const *args,
        char * const *envs, execve_fetch_element_t fetch_element,
@@ -651,12 +697,9 @@
         * functions call check_exec() recursively - for example,
         * see exec_script_makecmds().
         */
-       error = pathbuf_copyin(path, &data->ed_pathbuf);
-       if (error) {
-               DPRINTF(("%s: pathbuf_copyin path @%p %d\n", __func__,
-                   path, error));
+       data->ed_pathbuf = makepathbuf(l, path);
+       if (data->ed_pathbuf == NULL)
                goto clrflg;
-       }
        data->ed_pathstring = pathbuf_stringcopy_get(data->ed_pathbuf);
        data->ed_resolvedpathbuf = PNBUF_GET();
 
@@ -880,7 +923,6 @@
        (void)memcpy(p->p_comm, commandname, commandlen);
        p->p_comm[commandlen] = '\0';
 
-       path = PNBUF_GET();
 
        /*
         * If the path starts with /, we don't need to do any work.
@@ -888,30 +930,11 @@
         * In the future perhaps we could canonicalize it?
         */
        if (pathstring[0] == '/') {
-               (void)strlcpy(path, pathstring,
-                   MAXPATHLEN);
+               path = PNBUF_GET();
+               (void)strlcpy(path, pathstring, MAXPATHLEN);
                epp->ep_path = path;
-       }
-#ifdef notyet
-       /*
-        * Although this works most of the time [since the entry was just
-        * entered in the cache] we don't use it because it will fail for
-        * entries that are not placed in the cache because their name is
-        * longer than NCHNAMLEN and it is not the cleanest interface,
-        * because there could be races. When the namei cache is re-written,
-        * this can be changed to use the appropriate function.
-        */
-       else if (!(error = vnode_to_path(path, MAXPATHLEN, p->p_textvp, l, p)))
-               epp->ep_path = path;
-#endif
-       else {
-#ifdef notyet
-               printf("Cannot get path for pid %d [%s] (error %d)\n",
-                   (int)p->p_pid, p->p_comm, error);
-#endif
+       } else
                epp->ep_path = NULL;
-               PNBUF_PUT(path);
-       }
 }
 
 /* XXX elsewhere */



Home | Main Index | Thread Index | Old Index