* 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