bug-hurd
[Top][All Lists]
Advanced

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

[PATCH 4/4] Make the exec filename available at exec_startup time


From: Jeremie Koenig
Subject: [PATCH 4/4] Make the exec filename available at exec_startup time
Date: Wed, 17 Aug 2011 21:25:23 +0200

* hurd/exec_startup.defs (exec_startup_get_info_2): Define a new version of
exec_startup_get_info to get the executable filename.
(exec_startup_get_info): Mark as deprecated.
* exec/priv.h (struct bootinfo): Add a filename field.
* exec/exec.c (do_exec): Fill it in.
(S_exec_startup_get_info): Mark as deprecated, forward to...
(S_exec_startup_get_info_2): New version, fill in the filename.
* libdiskfs/boot-start.c (diskfs_S_exec_startup_get_info_2): New function.
(diskfs_S_exec_startup_get_info): Deprecate.
---
 exec/exec.c            |   38 ++++++++++++++++++++++++
 exec/priv.h            |    1 +
 hurd/exec_startup.defs |   22 ++++++++++++++
 libdiskfs/boot-start.c |   74 +++++++++++++++++++++++++++++++++++------------
 4 files changed, 116 insertions(+), 19 deletions(-)

diff --git a/exec/exec.c b/exec/exec.c
index 1f91d5b..947e3f0 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -1440,24 +1440,29 @@ do_exec (file_t file,
      have no effect, and the lack of installed standard ports should
      not cause an error.  -mib */
   if ((!std_ports || !std_ints) && (flags & (EXEC_SECURE|EXEC_DEFAULTS)))
     return EIEIO;
 
   /* 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);
 
+  /* The user-provided FILENAME is never to be trusted in EXEC_SECURE
+     circumstances.  */
+  if (flags & EXEC_SECURE)
+    filename = "";
+
   if (e.error == ENOEXEC)
     {
       /* Check for a #! executable file.  */
       check_hashbang (&e,
                      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);
@@ -1558,24 +1563,27 @@ do_exec (file_t file,
 
     /* These flags say the information we pass through to the new program
        may need to be modified.  */
     secure = (flags & EXEC_SECURE);
     defaults = (flags & EXEC_DEFAULTS);
 
     /* Now record the big blocks of data we shuffle around unchanged.
        Whatever arrived inline, we must allocate space for so it can
        survive after this RPC returns.  */
 
     boot->flags = flags;
 
+    assert (filename);
+    strncpy (boot->filename, filename, sizeof (string_t));
+
     argv = servercopy (argv, argvlen, argv_copy, &e.error);
     if (e.error)
       goto stdout;
     boot->argv = argv;
     boot->argvlen = argvlen;
     envp = servercopy (envp, envplen, envp_copy, &e.error);
     if (e.error)
       goto stdout;
     boot->envp = envp;
     boot->envplen = envplen;
     dtable = servercopy (dtable, dtablesize * sizeof (mach_port_t),
                         dtable_copy, &e.error);
@@ -2252,54 +2260,84 @@ S_exec_setexecdata (struct trivfs_protid *protid,
   std_nints = nints;
 
   rwlock_writer_unlock (&std_lock);
 
   return 0;
 }
 
 
 #include "exec_startup_S.h"
 
 /* RPC sent on the bootstrap port.  */
 
+/* Deprecated.  */
 kern_return_t
 S_exec_startup_get_info (mach_port_t port,
                         vm_address_t *user_entry,
                         vm_address_t *phdr_data, vm_size_t *phdr_size,
                         vm_address_t *stack_base, vm_size_t *stack_size,
                         int *flags,
                         char **argvp, mach_msg_type_number_t *argvlen,
                         char **envpp, mach_msg_type_number_t *envplen,
                         mach_port_t **dtable,
                         mach_msg_type_name_t *dtablepoly,
                         mach_msg_type_number_t *dtablesize,
                         mach_port_t **portarray,
                         mach_msg_type_name_t *portpoly,
                         mach_msg_type_number_t *nports,
                         int **intarray, mach_msg_type_number_t *nints)
 {
+  return S_exec_startup_get_info_2 (port, user_entry,
+                                   phdr_data, phdr_size,
+                                   stack_base, stack_size,
+                                   flags, NULL,
+                                   argvp, argvlen, envpp, envplen,
+                                   dtable, dtablepoly, dtablesize,
+                                   portarray, portpoly, nports,
+                                   intarray, nints);
+}
+
+kern_return_t
+S_exec_startup_get_info_2 (mach_port_t port,
+                          vm_address_t *user_entry,
+                          vm_address_t *phdr_data, vm_size_t *phdr_size,
+                          vm_address_t *stack_base, vm_size_t *stack_size,
+                          int *flags, string_t filename,
+                          char **argvp, mach_msg_type_number_t *argvlen,
+                          char **envpp, mach_msg_type_number_t *envplen,
+                          mach_port_t **dtable,
+                          mach_msg_type_name_t *dtablepoly,
+                          mach_msg_type_number_t *dtablesize,
+                          mach_port_t **portarray,
+                          mach_msg_type_name_t *portpoly,
+                          mach_msg_type_number_t *nports,
+                          int **intarray, mach_msg_type_number_t *nints)
+{
   struct bootinfo *boot = ports_lookup_port (port_bucket, port,
                                             execboot_portclass);
   if (! boot)
     return EOPNOTSUPP;
   ports_port_deref (boot);
 
   /* Pass back all the information we are storing.  */
 
   *user_entry = boot->user_entry;
   *phdr_data = boot->phdr_addr;
   *phdr_size = boot->phdr_size;
   *stack_base = boot->stack_base;
   *stack_size = boot->stack_size;
 
+  if (filename)
+    strncpy (filename, boot->filename, sizeof (string_t));
+
   *argvp = boot->argv;
   *argvlen = boot->argvlen;
   boot->argvlen = 0;
 
   *envpp = boot->envp;
   *envplen = boot->envplen;
   boot->envplen = 0;
 
   *dtable = boot->dtable;
   *dtablesize = boot->dtablesize;
   *dtablepoly = MACH_MSG_TYPE_MOVE_SEND;
   boot->dtablesize = 0;
diff --git a/exec/priv.h b/exec/priv.h
index 980d99f..ac48670 100644
--- a/exec/priv.h
+++ b/exec/priv.h
@@ -47,24 +47,25 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 extern bfd_arch_info_type host_bfd_arch_info;
 extern bfd host_bfd;
 #endif
 
 /* Information kept around to be given to a new task
    in response to a message on the task's bootstrap port.  */
 struct bootinfo
   {
     struct port_info pi;
     vm_address_t stack_base;
     vm_size_t stack_size;
     int flags;
+    string_t filename;
     char *argv, *envp;
     size_t argvlen, envplen, dtablesize, nports, nints;
     mach_port_t *dtable, *portarray;
     int *intarray;
     vm_address_t phdr_addr, user_entry;
     vm_size_t phdr_size;
   };
 
 
 /* Where to put the service ports. */
 struct port_bucket *port_bucket;
 struct port_class *execboot_portclass;
diff --git a/hurd/exec_startup.defs b/hurd/exec_startup.defs
index 9dfb79a..67a823a 100644
--- a/hurd/exec_startup.defs
+++ b/hurd/exec_startup.defs
@@ -17,30 +17,52 @@ You should have received a copy of the GNU General Public 
License
 along with the GNU Hurd; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* Written by Roland McGrath.  */
 
 subsystem exec_startup 30500;
 
 #include <hurd/hurd_types.defs>
 
 /* This call is made by a new task to its bootstrap port to get its
    startup ports and information.  */
 
+/* Deprecated.  */
 routine exec_startup_get_info (
        bootstrap: mach_port_t;
        /* These describe the entry point and program header data
           of the user program loaded into the task.  */
        out user_entry: vm_address_t;
        out phdr_data: vm_address_t;
        out phdr_size: vm_size_t;
        /* These are the base address and size of the initial stack
           allocated by the exec server.   */
        out stack_base: vm_address_t;
        out stack_size: vm_size_t;
        /* The rest of the information is that passed by exec_exec.  */
        out flags: int;
        out argv: data_t, dealloc;
        out envp: data_t, dealloc;
        out dtable: portarray_t, dealloc;
        out portarray: portarray_t, dealloc;
        out intarray: intarray_t, dealloc);
+
+/* 2011-07: Add filename.  */
+routine exec_startup_get_info_2 (
+       bootstrap: mach_port_t;
+       /* These describe the entry point and program header data
+          of the user program loaded into the task.  */
+       out user_entry: vm_address_t;
+       out phdr_data: vm_address_t;
+       out phdr_size: vm_size_t;
+       /* These are the base address and size of the initial stack
+          allocated by the exec server.   */
+       out stack_base: vm_address_t;
+       out stack_size: vm_size_t;
+       /* The rest of the information is that passed by exec_exec.  */
+       out flags: int;
+       out filename: string_t;
+       out argv: data_t, dealloc;
+       out envp: data_t, dealloc;
+       out dtable: portarray_t, dealloc;
+       out portarray: portarray_t, dealloc;
+       out intarray: intarray_t, dealloc);
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index e816b0b..bac002a 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -276,63 +276,66 @@ diskfs_start_bootstrap ()
   free (exec_argv);
   free (exec_env);
   mach_port_deallocate (mach_task_self (), root_pt);
   mach_port_deallocate (mach_task_self (), startup_pt);
   mach_port_deallocate (mach_task_self (), bootpt);
   assert_perror (err);
 }
 
 /* We look like an execserver to the execserver itself; it makes this
    call (as does any task) to get its state.  We can't give it all of
    its ports (we'll provide those with a later call to exec_init).  */
 kern_return_t
-diskfs_S_exec_startup_get_info (mach_port_t port,
-                               vm_address_t *user_entry,
-                               vm_address_t *phdr_data,
-                               vm_size_t *phdr_size,
-                               vm_address_t *base_addr,
-                               vm_size_t *stack_size,
-                               int *flags,
-                               char **argvP,
-                               mach_msg_type_number_t *argvlen,
-                               char **envpP __attribute__ ((unused)),
-                               mach_msg_type_number_t *envplen,
-                               mach_port_t **dtableP,
-                               mach_msg_type_name_t *dtablepoly,
-                               mach_msg_type_number_t *dtablelen,
-                               mach_port_t **portarrayP,
-                               mach_msg_type_name_t *portarraypoly,
-                               mach_msg_type_number_t *portarraylen,
-                               int **intarrayP,
-                               mach_msg_type_number_t *intarraylen)
+diskfs_S_exec_startup_get_info_2 (mach_port_t port,
+                                 vm_address_t *user_entry,
+                                 vm_address_t *phdr_data,
+                                 vm_size_t *phdr_size,
+                                 vm_address_t *base_addr,
+                                 vm_size_t *stack_size,
+                                 int *flags,
+                                 string_t filename,
+                                 char **argvP,
+                                 mach_msg_type_number_t *argvlen,
+                                 char **envpP __attribute__ ((unused)),
+                                 mach_msg_type_number_t *envplen,
+                                 mach_port_t **dtableP,
+                                 mach_msg_type_name_t *dtablepoly,
+                                 mach_msg_type_number_t *dtablelen,
+                                 mach_port_t **portarrayP,
+                                 mach_msg_type_name_t *portarraypoly,
+                                 mach_msg_type_number_t *portarraylen,
+                                 int **intarrayP,
+                                 mach_msg_type_number_t *intarraylen)
 {
   error_t err;
   mach_port_t *portarray, *dtable;
   mach_port_t rootport;
   struct ufsport *upt;
   struct protid *rootpi;
   struct peropen *rootpo;
 
   if (!(upt = ports_lookup_port (diskfs_port_bucket, port,
                                 diskfs_execboot_class)))
     return EOPNOTSUPP;
 
   *user_entry = 0;
   *phdr_data = *base_addr = 0;
   *phdr_size = *stack_size = 0;
 
   /* We have no args for it.  Tell it to look on its stack
      for the args placed there by the boot loader.  */
   *argvlen = *envplen = 0;
   *flags = EXEC_STACK_ARGS;
+  if (filename)
+    memset (filename, 0, sizeof (string_t));
 
   if (*portarraylen < INIT_PORT_MAX)
     *portarrayP = mmap (0, INIT_PORT_MAX * sizeof (mach_port_t),
                        PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
   portarray = *portarrayP;
   *portarraylen = INIT_PORT_MAX;
 
   if (*dtablelen < 3)
     *dtableP = mmap (0, 3 * sizeof (mach_port_t), PROT_READ|PROT_WRITE,
                     MAP_ANON, 0, 0);
   dtable = *dtableP;
   *dtablelen = 3;
@@ -355,24 +358,57 @@ diskfs_S_exec_startup_get_info (mach_port_t port,
   portarray[INIT_PORT_PROC] = MACH_PORT_NULL;
   portarray[INIT_PORT_CTTYID] = MACH_PORT_NULL;
   portarray[INIT_PORT_BOOTSTRAP] = port; /* use the same port */
 
   *portarraypoly = MACH_MSG_TYPE_MAKE_SEND;
 
   *dtablepoly = MACH_MSG_TYPE_COPY_SEND;
 
   ports_port_deref (upt);
   return 0;
 }
 
+/* Deprecated version.  */
+kern_return_t
+diskfs_S_exec_startup_get_info (mach_port_t port,
+                               vm_address_t *user_entry,
+                               vm_address_t *phdr_data,
+                               vm_size_t *phdr_size,
+                               vm_address_t *base_addr,
+                               vm_size_t *stack_size,
+                               int *flags,
+                               char **argvP,
+                               mach_msg_type_number_t *argvlen,
+                               char **envpP __attribute__ ((unused)),
+                               mach_msg_type_number_t *envplen,
+                               mach_port_t **dtableP,
+                               mach_msg_type_name_t *dtablepoly,
+                               mach_msg_type_number_t *dtablelen,
+                               mach_port_t **portarrayP,
+                               mach_msg_type_name_t *papoly,
+                               mach_msg_type_number_t *palen,
+                               int **intarrayP,
+                               mach_msg_type_number_t *intarraylen)
+{
+  return diskfs_S_exec_startup_get_info_2 (port, user_entry,
+                                          phdr_data, phdr_size,
+                                          base_addr, stack_size,
+                                          flags, NULL,
+                                          argvP, argvlen,
+                                          envpP, envplen,
+                                          dtableP, dtablepoly, dtablelen,
+                                          portarrayP, papoly, palen,
+                                          intarrayP, intarraylen);
+}
+
 /* Called by S_fsys_startup for execserver bootstrap.  The execserver
    is able to function without a real node, hence this fraud.  */
 error_t
 diskfs_execboot_fsys_startup (mach_port_t port, int flags,
                              mach_port_t ctl,
                              mach_port_t *real,
                              mach_msg_type_name_t *realpoly)
 {
   error_t err;
   string_t pathbuf;
   enum retry_type retry;
   struct port_info *pt;
-- 
1.7.5.4




reply via email to

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