bug-hurd
[Top][All Lists]
Advanced

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

[PATCH 1/4] Add a new exec_exec_file_name RPC


From: Jeremie Koenig
Subject: [PATCH 1/4] Add a new exec_exec_file_name RPC
Date: Wed, 17 Aug 2011 21:25:20 +0200

From: Emilio Pozuelo Monfort <pochu27@gmail.com>

* hurd/exec.defs (exec_exec_file_name): New RPC.
(exec_exec): Label as deprecated.
* doc/hurd.texi: Updated.
* exec/exec.c (S_exec_exec_file_name): New function.
(S_exec_exec): Label as deprecated.
(do_exec): Add argument.
* exec/hashexec.c (check_hashbang): Add argument.
Don't guess the file name if file_name_exec is set.
* exec/priv.h (check_hashbang): Add argument.

Signed-off-by: Jeremie Koenig <jk@jk.fr.eu.org>
---
 doc/hurd.texi   |    8 ++++----
 exec/exec.c     |   50 +++++++++++++++++++++++++++++++++++++++++++++-----
 exec/hashexec.c |   18 ++++++++++++------
 exec/priv.h     |    4 +++-
 hurd/exec.defs  |   19 +++++++++++++++++--
 5 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/doc/hurd.texi b/doc/hurd.texi
index 098bebf..c0238f9 100644
--- a/doc/hurd.texi
+++ b/doc/hurd.texi
@@ -93,25 +93,25 @@
 @syncodeindex pg cp
 
 @dircategory Kernel
 @direntry
 * Hurd: (hurd).  Using and programming the Hurd kernel servers.
 @end direntry
 
 @copying
 This file documents the GNU Hurd kernel component.  This edition of the
 documentation was last updated for version @value{VERSION} of the Hurd.
 
 Copyright @copyright{} 1994, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
-2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 @quotation
 Permission is granted to make and distribute verbatim copies of
 this manual provided the copyright notice and this permission notice
 are preserved on all copies.
 
 @ignore
 Permission is granted to process this file through TeX and print the
 results, provided the printed document carries a copying permission
 notice identical to this one except for the removal of this paragraph
 (this paragraph not being relevant to the printed manual).
 
@@ -2761,32 +2761,32 @@ the @code{file_exec} RPC with @code{ENOEXEC}.
 If either the setuid or setgid bits are set, the server needs to
 construct a new authentication handle with the additional new ID's.
 Then all the ports passed to @code{file_exec} need to be reauthenticated
 with the new handle.  If the fileserver is unable to make the new
 authentication handle (for example, because it is not running as root)
 it is not acceptable to return an error; in such a case the server
 should simply silently fail to implement the setuid/setgid semantics.
 
 If the setuid/setgid transformation adds a new uid or gid to the user's
 authentication handle that was not previously present (as opposed to
 merely reordering them), then the @code{EXEC_SECURE} and
 @code{EXEC_NEWTASK} flags should both be added in the call to
-@code{exec_exec}.
+@code{exec_exec_file_name}.
 
 The server then needs to open a new port onto the executed file which
 will not share any file pointers with the port the user passed in,
 opened with @code{O_READ}.  Finally, all the information (mutated
 appropriately for setuid/setgid) should be sent to the execserver with
-@code{exec_exec}.  Whatever error code @code{exec_exec} returns should
-returned to the caller of @code{file_exec}.
+@code{exec_exec_file_name}.  Whatever error code @code{exec_exec_file_name}
+returns should be returned to the caller of @code{file_exec}.
 
 @node File Locking
 @subsection File Locking
 
 The @code{flock} call is in flux, as the current Hurd interface (as of
 version @value{VERSION}) is not suitable for implementing the POSIX
 record-locking semantics.
 
 @findex file_lock
 @findex file_lock_stat
 You should ignore the @code{file_lock} and @code{file_lock_stat} calls
 until the new record-locking interface is implemented.
diff --git a/exec/exec.c b/exec/exec.c
index 01d22e7..1f91d5b 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -1,15 +1,15 @@
 /* GNU Hurd standard exec server.
-   Copyright (C) 1992,93,94,95,96,98,99,2000,01,02,04
-       Free Software Foundation, Inc.
+   Copyright (C) 1992 ,1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+   2002, 2004, 2010 Free Software Foundation, Inc.
    Written by Roland McGrath.
 
    Can exec ELF format directly.
    #ifdef GZIP
    Can gunzip executables into core on the fly.
    #endif
    #ifdef BFD
    Can exec any executable format the BFD library understands
    to be for this flavor of machine.
    #endif
    #ifdef BZIP2
    Can bunzip2 executables into core on the fly.
@@ -1348,24 +1348,25 @@ servercopy (void *arg, mach_msg_type_number_t argsize, 
boolean_t argcopy,
       *errorp = errno;
       return NULL;
     }
   memcpy (copy, arg, argsize);
   return copy;
 }
 
 
 static error_t
 do_exec (file_t file,
         task_t oldtask,
         int flags,
+        char *filename,
         char *argv, mach_msg_type_number_t argvlen, boolean_t argv_copy,
         char *envp, mach_msg_type_number_t envplen, boolean_t envp_copy,
         mach_port_t *dtable, mach_msg_type_number_t dtablesize,
         boolean_t dtable_copy,
         mach_port_t *portarray, mach_msg_type_number_t nports,
         boolean_t portarray_copy,
         int *intarray, mach_msg_type_number_t nints, boolean_t intarray_copy,
         mach_port_t *deallocnames, mach_msg_type_number_t ndeallocnames,
         mach_port_t *destroynames, mach_msg_type_number_t ndestroynames)
 {
   struct execdata e, interp;
   task_t newtask = MACH_PORT_NULL;
@@ -1443,25 +1444,25 @@ do_exec (file_t file,
 
   /* Suspend the existing task before frobnicating it.  */
   if (oldtask != MACH_PORT_NULL && (e.error = task_suspend (oldtask)))
     return e.error;
 
   /* Prime E for executing FILE and check its validity.  */
   prepare_and_check (file, &e);
 
   if (e.error == ENOEXEC)
     {
       /* Check for a #! executable file.  */
       check_hashbang (&e,
-                     file, oldtask, flags,
+                     file, oldtask, flags, filename,
                      argv, argvlen, argv_copy,
                      envp, envplen, envp_copy,
                      dtable, dtablesize, dtable_copy,
                      portarray, nports, portarray_copy,
                      intarray, nints, intarray_copy,
                      deallocnames, ndeallocnames,
                      destroynames, ndestroynames);
       if (! e.error)
        /* The #! exec succeeded; nothing more to do.  */
        return 0;
     }
 
@@ -2046,40 +2047,79 @@ do_exec (file_t file,
       /* If there is vm_allocate'd space for the original intarray and/or
         portarray, and we are not saving those pointers in BOOT for later
         transfer, deallocate the original space now.  */
       if (intarray_dealloc)
        munmap (intarray, nints * sizeof intarray[0]);
       if (!portarray_copy)
        munmap (portarray, nports * sizeof portarray[0]);
     }
 
   return e.error;
 }
 
+/* Deprecated.  */
 kern_return_t
 S_exec_exec (struct trivfs_protid *protid,
             file_t file,
             task_t oldtask,
             int flags,
             char *argv, mach_msg_type_number_t argvlen, boolean_t argv_copy,
             char *envp, mach_msg_type_number_t envplen, boolean_t envp_copy,
             mach_port_t *dtable, mach_msg_type_number_t dtablesize,
             boolean_t dtable_copy,
             mach_port_t *portarray, mach_msg_type_number_t nports,
             boolean_t portarray_copy,
             int *intarray, mach_msg_type_number_t nints,
             boolean_t intarray_copy,
             mach_port_t *deallocnames, mach_msg_type_number_t ndeallocnames,
             mach_port_t *destroynames, mach_msg_type_number_t ndestroynames)
 {
+  return S_exec_exec_file_name (protid,
+                               file,
+                               oldtask,
+                               flags,
+                               "",
+                               argv, argvlen, argv_copy,
+                               envp, envplen, envp_copy,
+                               dtable, dtablesize,
+                               dtable_copy,
+                               portarray, nports,
+                               portarray_copy,
+                               intarray, nints,
+                               intarray_copy,
+                               deallocnames, ndeallocnames,
+                               destroynames, ndestroynames);
+}
+
+kern_return_t
+S_exec_exec_file_name (struct trivfs_protid *protid,
+                      file_t file,
+                      task_t oldtask,
+                      int flags,
+                      char *filename,
+                      char *argv, mach_msg_type_number_t argvlen,
+                      boolean_t argv_copy,
+                      char *envp, mach_msg_type_number_t envplen,
+                      boolean_t envp_copy,
+                      mach_port_t *dtable, mach_msg_type_number_t dtablesize,
+                      boolean_t dtable_copy,
+                      mach_port_t *portarray, mach_msg_type_number_t nports,
+                      boolean_t portarray_copy,
+                      int *intarray, mach_msg_type_number_t nints,
+                      boolean_t intarray_copy,
+                      mach_port_t *deallocnames,
+                      mach_msg_type_number_t ndeallocnames,
+                      mach_port_t *destroynames,
+                      mach_msg_type_number_t ndestroynames)
+{
   if (! protid)
     return EOPNOTSUPP;
 
 #if 0
   if (!(flags & EXEC_SECURE))
     {
       char *list = envz_get (envp, envplen, "EXECSERVERS");
 
       if (list)
        {
          int tried = 0;
          list = strdupa (list);
@@ -2102,25 +2142,25 @@ S_exec_exec (struct trivfs_protid *protid,
                    }
                  return dtable[fd];
                }
              file_t server;
              if (!hurd_file_name_lookup (user_port, user_fd, 0, p, 0,0, 
&server))
                {
                  error_t err;
                  struct trivfs_protid *protid
                    = ports_lookup_port (port_bucket, server,
                                         trivfs_protid_portclasses[0]);
                  if (protid)
                    {
-                     err = do_exec (file, oldtask, 0,
+                     err = do_exec (file, oldtask, 0, filename,
                                     argv, argvlen, argv_copy,
                                     envp, envplen, envp_copy,
                                     dtable, dtablesize, dtable_copy,
                                     portarray, nports, portarray_copy,
                                     intarray, nints, intarray_copy,
                                     deallocnames, ndeallocnames,
                                     destroynames, ndestroynames);
                      ports_port_deref (protid);
                    }
                  else
                    {
                      int n;
@@ -2149,25 +2189,25 @@ S_exec_exec (struct trivfs_protid *protid,
                }
            }
          if (tried)
            /* At least one exec server got a crack at it and gave up.  */
            return ENOEXEC;
        }
     }
 #endif
 
   /* There were no user-specified exec servers,
      or none of them could be found.  */
 
-  return do_exec (file, oldtask, flags,
+  return do_exec (file, oldtask, flags, filename,
                  argv, argvlen, argv_copy,
                  envp, envplen, envp_copy,
                  dtable, dtablesize, dtable_copy,
                  portarray, nports, portarray_copy,
                  intarray, nints, intarray_copy,
                  deallocnames, ndeallocnames,
                  destroynames, ndestroynames);
 }
 
 kern_return_t
 S_exec_setexecdata (struct trivfs_protid *protid,
                    mach_port_t *ports, mach_msg_type_number_t nports, int 
ports_copy,
diff --git a/exec/hashexec.c b/exec/hashexec.c
index 2aa3844..929d37b 100644
--- a/exec/hashexec.c
+++ b/exec/hashexec.c
@@ -1,14 +1,15 @@
 /* GNU Hurd standard exec server, #! script execution support.
-   Copyright (C) 1995,96,97,98,99,2000,02 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2010
+   Free Software Foundation, Inc.
    Written by Roland McGrath.
 
 This file is part of the GNU Hurd.
 
 The GNU Hurd is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 The GNU Hurd is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -26,24 +27,25 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 
 /* This is called to check E for a #! interpreter specification.  E has
    already been prepared (successfully) and checked (unsuccessfully).  If
    we return success, our caller just returns success for the RPC; we must
    handle all the RPC argument details ourselves.  If we return ENOEXEC, we
    should leave everything as it was.  If we return failure other than
    ENOEXEC, our caller will just fail the RPC.  */
 void
 check_hashbang (struct execdata *e,
                file_t file,
                task_t oldtask,
                int flags,
+               char *file_name_exec,
                char *argv, u_int argvlen, boolean_t argv_copy,
                char *envp, u_int envplen, boolean_t envp_copy,
                mach_port_t *dtable, u_int dtablesize, boolean_t dtable_copy,
                mach_port_t *portarray, u_int nports, boolean_t portarray_copy,
                int *intarray, u_int nints, boolean_t intarray_copy,
                mach_port_t *deallocnames, u_int ndeallocnames,
                mach_port_t *destroynames, u_int ndestroynames)
 {
   char *p;
   char *interp, *arg;          /* Interpreter file name, and first argument */
   size_t interp_len, arg_len;
   file_t interp_file;          /* Port open on the interpreter file.  */
@@ -216,28 +218,30 @@ check_hashbang (struct execdata *e,
       jmp_buf args_faulted;
       void fault_handler (int signo)
        { longjmp (args_faulted, 1); }
       error_t setup_args (struct hurd_signal_preemptor *preemptor)
        {
          size_t namelen;
          char * volatile file_name = NULL;
 
          if (setjmp (args_faulted))
            file_name = NULL;
          else if (! (flags & EXEC_SECURE))
            {
-             /* Try to figure out the file's name.  We guess that if ARGV[0]
-                contains a slash, it might be the name of the file; and that
-                if it contains no slash, looking for files named by ARGV[0] in
-                the `PATH' environment variable might find it.  */
+             /* Try to figure out the file's name.  If FILE_NAME_EXEC
+                is not NULL, then it's the file's name.  Otherwise we
+                guess that if ARGV[0] contains a slash, it might be
+                the name of the file; and that if it contains no slash,
+                looking for files named by ARGV[0] in the `PATH'
+                environment variable might find it.  */
 
              error_t error;
              char *name;
              int free_name = 0; /* True if we should free NAME. */
              file_t name_file;
              mach_port_t fileid, filefsid;
              ino_t fileno;
 
              /* Search $PATH for NAME, opening a port NAME_FILE on it.
                 This is encapsulated in a function so we can catch faults
                 reading the user's environment.  */
              error_t search_path (struct hurd_signal_preemptor *preemptor)
@@ -269,25 +273,27 @@ check_hashbang (struct execdata *e,
                goto out;
              mach_port_deallocate (mach_task_self (), filefsid);
 
              if (memchr (argv, '\0', argvlen) == NULL)
                {
                  name = alloca (argvlen + 1);
                  bcopy (argv, name, argvlen);
                  name[argvlen] = '\0';
                }
              else
                name = argv;
 
-             if (strchr (name, '/') != NULL)
+             if (file_name_exec && file_name_exec[0] != '\0')
+               error = lookup (name = file_name_exec, 0, &name_file);
+             else if (strchr (name, '/') != NULL)
                error = lookup (name, 0, &name_file);
              else if ((error = hurd_catch_signal
                        (sigmask (SIGBUS) | sigmask (SIGSEGV),
                         (vm_address_t) envp, (vm_address_t) envp + envplen,
                         &search_path, SIG_ERR)))
                name_file = MACH_PORT_NULL;
 
              if (!error && name_file != MACH_PORT_NULL)
                {
                  mach_port_t id, fsid;
                  ino_t ino;
                  error = io_identity (name_file, &id, &fsid, &ino);
diff --git a/exec/priv.h b/exec/priv.h
index 7cee15e..980d99f 100644
--- a/exec/priv.h
+++ b/exec/priv.h
@@ -1,14 +1,15 @@
 /* GNU Hurd standard exec server, private declarations.
-   Copyright (C) 1992,93,94,95,96,99,2000,02, 04 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2002, 2004,
+   2010 Free Software Foundation, Inc.
    Written by Roland McGrath.
 
 This file is part of the GNU Hurd.
 
 The GNU Hurd is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 The GNU Hurd is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -162,24 +163,25 @@ error_t elf_machine_matches_host (ElfW(Half) e_machine);
 void finish (struct execdata *, int dealloc_file_port);
 
 /* Make sure our mapping window (or read buffer) covers
    LEN bytes of the file starting at POSN, and return
    a pointer into the window corresponding to POSN.  */
 void *map (struct execdata *e, off_t posn, size_t len);
 
 
 void check_hashbang (struct execdata *e,
                     file_t file,
                     task_t oldtask,
                     int flags,
+                    char *filename,
                     char *argv, u_int argvlen, boolean_t argv_copy,
                     char *envp, u_int envplen, boolean_t envp_copy,
                     mach_port_t *dtable, u_int dtablesize,
                     boolean_t dtable_copy,
                     mach_port_t *portarray, u_int nports,
                     boolean_t portarray_copy,
                     int *intarray, u_int nints, boolean_t intarray_copy,
                     mach_port_t *deallocnames, u_int ndeallocnames,
                     mach_port_t *destroynames, u_int ndestroynames);
 
 
 /* Standard exec data for secure execs.  */
diff --git a/hurd/exec.defs b/hurd/exec.defs
index 2888fb1..ae4143b 100644
--- a/hurd/exec.defs
+++ b/hurd/exec.defs
@@ -1,14 +1,15 @@
 /* Interface definitions for the exec servers.
-   Copyright (C) 1991,92,93,94,95,2001 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1992, 1993, 1994, 1995, 2001, 2010
+   Free Software Foundation, Inc.
 
 This file is part of the GNU Hurd.
 
 The GNU Hurd is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 The GNU Hurd is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
@@ -20,38 +21,52 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell and Roland McGrath.  */
 
 subsystem exec 30000;
 
 #include <hurd/hurd_types.defs>
 
 #ifdef EXEC_IMPORTS
 EXEC_IMPORTS
 #endif
 
 INTR_INTERFACE
 
+/* Deprecated: use exec_exec_file_name instead.  */
 routine exec_exec (
        execserver: file_t;
        file: mach_port_send_t;
        oldtask: task_t;
        flags: int;
        argv: data_t SCP;
        envp: data_t SCP;
        dtable: portarray_t SCP;
        portarray: portarray_t SCP;
        intarray: intarray_t SCP;
        deallocnames: mach_port_name_array_t;
        destroynames: mach_port_name_array_t);
 
-skip;                          /* obsolete exec_startup */
+routine exec_exec_file_name (
+       execserver: file_t;
+       file: mach_port_send_t;
+       oldtask: task_t;
+       flags: int;
+       filename: string_t;
+       argv: data_t SCP;
+       envp: data_t SCP;
+       dtable: portarray_t SCP;
+       portarray: portarray_t SCP;
+       intarray: intarray_t SCP;
+       deallocnames: mach_port_name_array_t;
+       destroynames: mach_port_name_array_t);
+
 
 /* This call is made by the bootstrapping filesystem to give the
    execserver its auth handle.  */
 routine exec_init (
        execserver: file_t;
        auth_handle: auth_t;
        proc_server: mach_port_send_t);
 
 simpleroutine exec_setexecdata (
        execserver: file_t;
        ports: portarray_t SCP;
        ints: intarray_t SCP);
-- 
1.7.5.4




reply via email to

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