summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Pozuelo Monfort <pochu27@gmail.com>2010-05-26 01:27:40 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-01-08 22:46:06 +0100
commit4152b0ca04f4703a6c6f33e59ba0e7bd95837069 (patch)
treee10f7b717da381cacf8a5d98087d664f271f3bba
parent67fa50fb8f0a6894e5ed6534936afb8044e66613 (diff)
Add a file_exec_file_name RPC
* hurd/fs.defs (file_exec): Deprecate in favor of... (file_exec_paths): ...this new RPC. * TODO: Update. * doc/hurd.texi: Update RPC name. * hurd/hurd_types.h: Update RPC name. * libdiskfs/boot-start.c: Update RPC name. * configure.ac: Check for presence of RPC stubs file_exec_paths exec_exec_paths. * exec/hashexec.c (check_hashbang): When file_exec_paths is available, use it instead of file_exec. * startup/startup.c (run, run_for_real, start_child): Likewise. * utils/login.c (main): Likewise. * libfshelp/start-translator-long.c (fshelp_start_translator_long): Likewise. * libdiskfs/file-exec.c (diskfs_S_file_exec): Move code to new function diskfs_S_file_exec_paths and call it. (diskfs_S_file_exec_paths): New function, use exec_exec_paths when available instead of exec_exec * libnetfs/file-exec.c (netfs_S_file_exec, netfs_S_file_exec_paths): Likewise. * trans/fakeroot.c (netfs_S_file_exec, netfs_S_file_exec_paths): Likewise. * libtrivfs/file-exec.c (trivfs_S_file_exec_paths): New function.
-rw-r--r--TODO2
-rw-r--r--configure.ac2
-rw-r--r--doc/hurd.texi16
-rw-r--r--exec/hashexec.c34
-rw-r--r--hurd/fs.defs29
-rw-r--r--hurd/hurd_types.h9
-rw-r--r--libdiskfs/boot-start.c2
-rw-r--r--libdiskfs/file-exec.c79
-rw-r--r--libfshelp/start-translator-long.c23
-rw-r--r--libnetfs/file-exec.c71
-rw-r--r--libtrivfs/file-exec.c28
-rw-r--r--startup/startup.c87
-rw-r--r--trans/fakeroot.c97
-rw-r--r--utils/login.c25
14 files changed, 395 insertions, 109 deletions
diff --git a/TODO b/TODO
index de2a1997..4361f920 100644
--- a/TODO
+++ b/TODO
@@ -131,7 +131,7 @@ See `tasks', the exported task list.
** libtrivfs
*** Allow for read/write/exec to be passed down.
-*** Implement file_exec when appropriate. !!
+*** Implement file_exec_paths when appropriate. !!
*** Provide for the visible owner, etc., to be held in command-line args
instead of the underlying node, when it's important. !!
diff --git a/configure.ac b/configure.ac
index 5abedf46..73cfa47f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -162,6 +162,8 @@ else
VERSIONING=no
fi
AC_SUBST(VERSIONING)
+# Check if libc contains these functions.
+AC_CHECK_FUNCS(file_exec_paths exec_exec_paths)
# From glibc HEAD, 2007-11-07.
diff --git a/doc/hurd.texi b/doc/hurd.texi
index a9216d1d..e77894a3 100644
--- a/doc/hurd.texi
+++ b/doc/hurd.texi
@@ -2736,10 +2736,10 @@ write the file.
@node Program Execution
@subsection Program Execution
-@findex file_exec
+@findex file_exec_paths
Execution of programs on the Hurd is done through fileservers with the
-@code{file_exec} RPC. The fileserver is expected to verify that the
-user is allowed to execute the file, make whatever modifications to the
+@code{file_exec_paths} RPC. The fileserver is expected to verify that
+the user is allowed to execute the file, make whatever modifications to the
ports are necessary for setuid execution, and then invoke the standard
execserver found on @file{/servers/exec}.
@@ -2751,13 +2751,13 @@ The file must be opened for execution; if it is not, @code{EBADF} should
be returned. In addition, at least one of the execute bits must be on. A
failure of this check should result in @code{EACCES}---not
@code{ENOEXEC}. It is not proper for the fileserver ever to respond to
-the @code{file_exec} RPC with @code{ENOEXEC}.
+the @code{file_exec_paths} 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)
+Then all the ports passed to @code{file_exec_paths} 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.
@@ -2772,7 +2772,7 @@ 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_paths}. Whatever error code @code{exec_exec_paths}
-returns should be returned to the caller of @code{file_exec}.
+returns should be returned to the caller of @code{file_exec_paths}.
@node File Locking
@subsection File Locking
diff --git a/exec/hashexec.c b/exec/hashexec.c
index e8e94844..a7368390 100644
--- a/exec/hashexec.c
+++ b/exec/hashexec.c
@@ -423,16 +423,32 @@ check_hashbang (struct execdata *e,
/* We cannot open the interpreter file to execute it. Lose! */
return;
+#ifdef HAVE_FILE_EXEC_PATHS
/* Execute the interpreter program. */
- e->error = file_exec (interp_file,
- oldtask, flags,
- new_argv, new_argvlen, envp, envplen,
- new_dtable ?: dtable, MACH_MSG_TYPE_COPY_SEND,
- new_dtable ? new_dtablesize : dtablesize,
- portarray, MACH_MSG_TYPE_COPY_SEND, nports,
- intarray, nints,
- deallocnames, ndeallocnames,
- destroynames, ndestroynames);
+ e->error = file_exec_paths (interp_file,
+ oldtask, flags, interp, interp,
+ new_argv, new_argvlen, envp, envplen,
+ new_dtable ?: dtable,
+ MACH_MSG_TYPE_COPY_SEND,
+ new_dtable ? new_dtablesize : dtablesize,
+ portarray, MACH_MSG_TYPE_COPY_SEND, nports,
+ intarray, nints,
+ deallocnames, ndeallocnames,
+ destroynames, ndestroynames);
+ /* For backwards compatibility. Just drop it when we kill file_exec. */
+ if (e->error == MIG_BAD_ID)
+#endif
+ e->error = file_exec (interp_file,
+ oldtask, flags,
+ new_argv, new_argvlen, envp, envplen,
+ new_dtable ?: dtable, MACH_MSG_TYPE_COPY_SEND,
+ new_dtable ? new_dtablesize : dtablesize,
+ portarray, MACH_MSG_TYPE_COPY_SEND, nports,
+ intarray, nints,
+ deallocnames, ndeallocnames,
+ destroynames, ndestroynames);
+
+
mach_port_deallocate (mach_task_self (), interp_file);
munmap (new_argv, new_argvlen);
diff --git a/hurd/fs.defs b/hurd/fs.defs
index 6c0b5731..14800d9a 100644
--- a/hurd/fs.defs
+++ b/hurd/fs.defs
@@ -1,5 +1,6 @@
/* Definitions for the filesystem interface.
- Copyright (C) 1994,95,96,97,98,99,2002 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2002, 2010
+ Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -35,7 +36,8 @@ INTR_INTERFACE
/* Overlay a task with a file. Necessary initialization, including
authentication changes associated with set[ug]id execution must be
handled by the filesystem. Filesystems normally implement this by
- using exec_newtask or exec_loadtask as appropriate. */
+ using exec_newtask or exec_loadtask as appropriate.
+ Deprecated: use file_exec_paths instead. */
routine file_exec (
exec_file: file_t;
RPT
@@ -129,8 +131,8 @@ routine file_lock_stat (
(regardless of the current open modes for this port). ALLOWED is a
bitwise OR of O_READ, O_WRITE, and O_EXEC. This is not necessarily the
same as what an open or exec would allow; O_EXEC is set for root even if
- no executable bits are on (in which case file_exec should fail) and
- O_WRITE is set a directory can be modified, even though it can't be
+ no executable bits are on (in which case file_exec_paths should fail)
+ and O_WRITE is set a directory can be modified, even though it can't be
written directly. */
routine file_check_access (
file: file_t;
@@ -355,3 +357,22 @@ routine file_reparent (
skip; /* Was: file_get_children. */
skip; /* Was: file_get_source. */
+
+/* Overlay a task with a file. Necessary initialization, including
+ authentication changes associated with set[ug]id execution must be
+ handled by the filesystem. Filesystems normally implement this by
+ using exec_newtask or exec_loadtask as appropriate. */
+routine file_exec_paths (
+ exec_file: file_t;
+ RPT
+ exec_task: task_t;
+ flags: int;
+ path: string_t;
+ abspath: string_t;
+ argv: data_t SCP;
+ envp: data_t SCP;
+ fdarray: portarray_t SCP;
+ portarray: portarray_t SCP;
+ intarray: intarray_t SCP;
+ deallocnames: mach_port_name_array_t SCP;
+ destroynames: mach_port_name_array_t SCP);
diff --git a/hurd/hurd_types.h b/hurd/hurd_types.h
index 2960a294..9fa9ae29 100644
--- a/hurd/hurd_types.h
+++ b/hurd/hurd_types.h
@@ -1,5 +1,6 @@
/* C declarations for Hurd server interfaces
- Copyright (C) 1993,94,95,96,98,99,2001,02 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2002,
+ 2010 Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -81,7 +82,7 @@ typedef struct timespec timespec_t;
/* Many such parameters and flags are also defined in various libc
headers. */
-/* Bits for flags in fs.defs:file_exec and exec.defs:exec_* calls: */
+/* Bits for flags in fs.defs:file_exec_paths and exec.defs:exec_* calls: */
#define EXEC_NEWTASK 0x00000001 /* Create new task; kill old one. */
#define EXEC_SECURE 0x00000002 /* Use secure values of portarray, etc. */
#define EXEC_DEFAULTS 0x00000004 /* Use defaults for unspecified ports. */
@@ -350,7 +351,7 @@ typedef int *procinfo_t;
#define FSTYPE_MEMFS 0x00000019 /* In-core filesystem */
#define FSTYPE_ISO9660 0x0000001a /* ISO9660 */
-/* Standard port assignments for file_exec and exec_* */
+/* Standard port assignments for file_exec_paths and exec_* */
enum
{
INIT_PORT_CWDIR,
@@ -364,7 +365,7 @@ enum
INIT_PORT_MAX
};
-/* Standard ints for file_exec and exec_* */
+/* Standard ints for file_exec_paths and exec_* */
enum
{
INIT_UMASK,
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index 1b76ebde..01548548 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -202,7 +202,7 @@ diskfs_start_bootstrap ()
diskfs_exec_ctl = MACH_PORT_NULL; /* Not used after this. */
}
- /* Cache the exec server port for file_exec to use. */
+ /* Cache the exec server port for file_exec_paths to use. */
_hurd_port_set (&_diskfs_exec_portcell, diskfs_exec);
if (_diskfs_boot_command)
diff --git a/libdiskfs/file-exec.c b/libdiskfs/file-exec.c
index e544b14a..3e830161 100644
--- a/libdiskfs/file-exec.c
+++ b/libdiskfs/file-exec.c
@@ -1,5 +1,6 @@
-/* File execution (file_exec RPC) for diskfs servers, using exec server.
- Copyright (C) 1993,94,95,96,97,98,2000,02 Free Software Foundation, Inc.
+/* File execution (file_exec_paths RPC) for diskfs servers, using exec server.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002,
+ 2010 Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -47,6 +48,41 @@ diskfs_S_file_exec (struct protid *cred,
mach_port_t *destroynames,
size_t destroynameslen)
{
+ return diskfs_S_file_exec_paths (cred,
+ task,
+ flags,
+ "",
+ "",
+ argv, argvlen,
+ envp, envplen,
+ fds, fdslen,
+ portarray, portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+}
+
+kern_return_t
+diskfs_S_file_exec_paths (struct protid *cred,
+ task_t task,
+ int flags,
+ char *path,
+ char *abspath,
+ char *argv,
+ size_t argvlen,
+ char *envp,
+ size_t envplen,
+ mach_port_t *fds,
+ size_t fdslen,
+ mach_port_t *portarray,
+ size_t portarraylen,
+ int *intarray,
+ size_t intarraylen,
+ mach_port_t *deallocnames,
+ size_t deallocnameslen,
+ mach_port_t *destroynames,
+ size_t destroynameslen)
+{
struct node *np;
uid_t uid;
gid_t gid;
@@ -136,9 +172,9 @@ diskfs_S_file_exec (struct protid *cred,
if (! err)
/* Make a new peropen for the exec server to access the file, since any
- seeking the exec server might want to do should not affect the
- original peropen on which file_exec was called. (The new protid for
- this peropen clones the caller's iouser to preserve the caller's
+ seeking the exec server might want to do should not affect the original
+ peropen on which file_exec_paths was called. (The new protid
+ for this peropen clones the caller's iouser to preserve the caller's
authentication credentials.) The new peropen's openmodes must have
O_READ even if the caller had only O_EXEC privilege, so the exec
server can read the executable file. We also include O_EXEC so that
@@ -159,14 +195,31 @@ diskfs_S_file_exec (struct protid *cred,
do
{
right = ports_get_send_right (newpi);
- err = exec_exec (execserver,
- right, MACH_MSG_TYPE_COPY_SEND,
- task, flags, argv, argvlen, envp, envplen,
- fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
- portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
- intarray, intarraylen,
- deallocnames, deallocnameslen,
- destroynames, destroynameslen);
+#ifdef HAVE_EXEC_EXEC_PATHS
+ err = exec_exec_paths (execserver,
+ right, MACH_MSG_TYPE_COPY_SEND,
+ task, flags, path, abspath,
+ argv, argvlen, envp, envplen,
+ fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+ portarray, MACH_MSG_TYPE_COPY_SEND,
+ portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+ /* For backwards compatibility. Just drop it when we kill
+ exec_exec. */
+ if (err == MIG_BAD_ID)
+#endif
+ err = exec_exec (execserver,
+ right, MACH_MSG_TYPE_COPY_SEND,
+ task, flags, argv, argvlen, envp, envplen,
+ fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+ portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+
+
mach_port_deallocate (mach_task_self (), right);
if (err == MACH_SEND_INVALID_DEST)
{
diff --git a/libfshelp/start-translator-long.c b/libfshelp/start-translator-long.c
index e1aea3c4..707b59ef 100644
--- a/libfshelp/start-translator-long.c
+++ b/libfshelp/start-translator-long.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 1995,96,99,2000,02, 04 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1999, 2000, 2002, 2004, 2010
+ Free Software Foundation, Inc.
Written by Miles Bader and Michael I. Bushnell.
This file is part of the GNU Hurd.
@@ -273,12 +274,22 @@ fshelp_start_translator_long (fshelp_open_fn_t underlying_open_fn,
saveport = ports[INIT_PORT_BOOTSTRAP];
ports[INIT_PORT_BOOTSTRAP] = bootstrap;
+#ifdef HAVE_FILE_EXEC_PATHS
/* Try and exec the translator in TASK... */
- err = file_exec (executable, task, EXEC_DEFAULTS,
- argz, argz_len, 0, 0,
- fds, fds_type, fds_len,
- ports, ports_type, ports_len,
- ints, ints_len, 0, 0, 0, 0);
+ err = file_exec_paths (executable, task, EXEC_DEFAULTS, name, name,
+ argz, argz_len, 0, 0,
+ fds, fds_type, fds_len,
+ ports, ports_type, ports_len,
+ ints, ints_len, 0, 0, 0, 0);
+ /* For backwards compatibility. Just drop it when we kill file_exec. */
+ if (err == MIG_BAD_ID)
+#endif
+ err = file_exec (executable, task, EXEC_DEFAULTS,
+ argz, argz_len, 0, 0,
+ fds, fds_type, fds_len,
+ ports, ports_type, ports_len,
+ ints, ints_len, 0, 0, 0, 0);
+
ports_moved = 1;
if (ports_type == MACH_MSG_TYPE_COPY_SEND)
diff --git a/libnetfs/file-exec.c b/libnetfs/file-exec.c
index 638f0ae8..8153b1f4 100644
--- a/libnetfs/file-exec.c
+++ b/libnetfs/file-exec.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 1996,97,2000,01,02 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 2000, 2001, 2002, 2010
+ Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -49,6 +50,41 @@ netfs_S_file_exec (struct protid *cred,
mach_port_t *destroynames,
size_t destroynameslen)
{
+ return netfs_S_file_exec_paths (cred,
+ task,
+ flags,
+ "",
+ "",
+ argv, argvlen,
+ envp, envplen,
+ fds, fdslen,
+ portarray, portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+}
+
+kern_return_t
+netfs_S_file_exec_paths (struct protid *cred,
+ task_t task,
+ int flags,
+ char *path,
+ char *abspath,
+ char *argv,
+ size_t argvlen,
+ char *envp,
+ size_t envplen,
+ mach_port_t *fds,
+ size_t fdslen,
+ mach_port_t *portarray,
+ size_t portarraylen,
+ int *intarray,
+ size_t intarraylen,
+ mach_port_t *deallocnames,
+ size_t deallocnameslen,
+ mach_port_t *destroynames,
+ size_t destroynameslen)
+{
struct node *np;
error_t err;
uid_t uid;
@@ -133,14 +169,31 @@ netfs_S_file_exec (struct protid *cred,
if (newpi)
{
right = ports_get_send_right (newpi);
- err = exec_exec (_netfs_exec,
- right, MACH_MSG_TYPE_COPY_SEND,
- task, flags, argv, argvlen, envp, envplen,
- fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
- portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
- intarray, intarraylen,
- deallocnames, deallocnameslen,
- destroynames, destroynameslen);
+#ifdef HAVE_EXEC_EXEC_PATHS
+ err = exec_exec_paths (_netfs_exec,
+ right, MACH_MSG_TYPE_COPY_SEND,
+ task, flags, path, abspath,
+ argv, argvlen, envp, envplen,
+ fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+ portarray, MACH_MSG_TYPE_COPY_SEND,
+ portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+ /* For backwards compatibility. Just drop it when we kill
+ exec_exec. */
+ if (err == MIG_BAD_ID)
+#endif
+ err = exec_exec (_netfs_exec,
+ right, MACH_MSG_TYPE_COPY_SEND,
+ task, flags, argv, argvlen, envp, envplen,
+ fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+ portarray, MACH_MSG_TYPE_COPY_SEND,
+ portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+
mach_port_deallocate (mach_task_self (), right);
ports_port_deref (newpi);
}
diff --git a/libtrivfs/file-exec.c b/libtrivfs/file-exec.c
index b353d8a3..a0a2a50c 100644
--- a/libtrivfs/file-exec.c
+++ b/libtrivfs/file-exec.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1994,2002 Free Software Foundation, Inc.
+ Copyright (C) 1994, 2002, 2010 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -41,3 +41,29 @@ trivfs_S_file_exec (trivfs_protid_t exec_file,
{
return EOPNOTSUPP;
}
+
+kern_return_t
+trivfs_S_file_exec_paths (trivfs_protid_t exec_file,
+ mach_port_t reply,
+ mach_msg_type_name_t replyPoly,
+ mach_port_t exec_task,
+ int flags,
+ string_t path,
+ string_t abspath,
+ data_t argv,
+ mach_msg_type_number_t argvCnt,
+ data_t envp,
+ mach_msg_type_number_t envpCnt,
+ portarray_t fdarray,
+ mach_msg_type_number_t fdarrayCnt,
+ portarray_t portarray,
+ mach_msg_type_number_t portarrayCnt,
+ intarray_t intarray,
+ mach_msg_type_number_t intarrayCnt,
+ mach_port_array_t deallocnames,
+ mach_msg_type_number_t deallocnamesCnt,
+ mach_port_array_t destroynames,
+ mach_msg_type_number_t destroynamesCnt)
+{
+ return EOPNOTSUPP;
+}
diff --git a/startup/startup.c b/startup/startup.c
index 7c3fbf0b..81a67716 100644
--- a/startup/startup.c
+++ b/startup/startup.c
@@ -1,7 +1,7 @@
/* Start and maintain hurd core servers and system run state
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2005, 2008, 2013 Free Software Foundation, Inc.
+ 2005, 2008, 2010, 2013 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
@@ -402,13 +402,28 @@ run (const char *server, mach_port_t *ports, task_t *task,
fprintf (stderr, "Pausing for %s\n", prog);
getchar ();
}
- err = file_exec (file, *task, 0,
- argz, argz_len, /* Args. */
- startup_envz, startup_envz_len,
- default_dtable, MACH_MSG_TYPE_COPY_SEND, 3,
- ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
- default_ints, INIT_INT_MAX,
- NULL, 0, NULL, 0);
+#ifdef HAVE_FILE_EXEC_PATHS
+ err = file_exec_paths (file, *task, 0, (char *)prog, (char *)prog,
+ argz,
+ argz_len, /* Args. */
+ startup_envz, startup_envz_len,
+ default_dtable,
+ MACH_MSG_TYPE_COPY_SEND, 3,
+ ports, MACH_MSG_TYPE_COPY_SEND,
+ INIT_PORT_MAX,
+ default_ints, INIT_INT_MAX,
+ NULL, 0, NULL, 0);
+ /* For backwards compatibility. Just drop it when we kill
+ file_exec. */
+ if (err == MIG_BAD_ID)
+#endif
+ err = file_exec (file, *task, 0,
+ argz, argz_len, /* Args. */
+ startup_envz, startup_envz_len,
+ default_dtable, MACH_MSG_TYPE_COPY_SEND, 3,
+ ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
+ default_ints, INIT_INT_MAX,
+ NULL, 0, NULL, 0);
if (!err)
break;
@@ -538,14 +553,27 @@ run_for_real (char *filename, char *args, int arglen, mach_port_t ctty,
++progname;
else
progname = filename;
- err = file_exec (file, task, 0,
- args, arglen,
- startup_envz, startup_envz_len,
- default_dtable, MACH_MSG_TYPE_COPY_SEND, 3,
- default_ports, MACH_MSG_TYPE_COPY_SEND,
- INIT_PORT_MAX,
- default_ints, INIT_INT_MAX,
- NULL, 0, NULL, 0);
+#ifdef HAVE_FILE_EXEC_PATHS
+ err = file_exec_paths (file, task, 0, filename, filename,
+ args, arglen,
+ startup_envz, startup_envz_len,
+ default_dtable, MACH_MSG_TYPE_COPY_SEND, 3,
+ default_ports, MACH_MSG_TYPE_COPY_SEND,
+ INIT_PORT_MAX,
+ default_ints, INIT_INT_MAX,
+ NULL, 0, NULL, 0);
+ /* For backwards compatibility. Just drop it when we kill file_exec. */
+ if (err == MIG_BAD_ID)
+#endif
+ err = file_exec (file, task, 0,
+ args, arglen,
+ startup_envz, startup_envz_len,
+ default_dtable, MACH_MSG_TYPE_COPY_SEND, 3,
+ default_ports, MACH_MSG_TYPE_COPY_SEND,
+ INIT_PORT_MAX,
+ default_ints, INIT_INT_MAX,
+ NULL, 0, NULL, 0);
+
mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]);
mach_port_deallocate (mach_task_self (), task);
if (ctty != MACH_PORT_NULL)
@@ -1244,13 +1272,26 @@ start_child (const char *prog, char **progargs)
getchar ();
}
- err = file_exec (file, child_task, 0,
- args, arglen,
- startup_envz, startup_envz_len,
- NULL, MACH_MSG_TYPE_COPY_SEND, 0, /* No fds. */
- default_ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
- default_ints, INIT_INT_MAX,
- NULL, 0, NULL, 0);
+#ifdef HAVE_FILE_EXEC_PATHS
+ err = file_exec_paths (file, child_task, 0, args, args,
+ args, arglen,
+ startup_envz, startup_envz_len,
+ NULL, MACH_MSG_TYPE_COPY_SEND, 0, /* No fds. */
+ default_ports, MACH_MSG_TYPE_COPY_SEND,
+ INIT_PORT_MAX,
+ default_ints, INIT_INT_MAX,
+ NULL, 0, NULL, 0);
+ /* For backwards compatibility. Just drop it when we kill file_exec. */
+ if (err == MIG_BAD_ID)
+#endif
+ err = file_exec (file, child_task, 0,
+ args, arglen,
+ startup_envz, startup_envz_len,
+ NULL, MACH_MSG_TYPE_COPY_SEND, 0, /* No fds. */
+ default_ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
+ default_ints, INIT_INT_MAX,
+ NULL, 0, NULL, 0);
+
proc_mark_important (default_ports[INIT_PORT_PROC]);
mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]);
mach_port_deallocate (mach_task_self (), file);
diff --git a/trans/fakeroot.c b/trans/fakeroot.c
index df47b00f..711a8565 100644
--- a/trans/fakeroot.c
+++ b/trans/fakeroot.c
@@ -882,23 +882,25 @@ netfs_file_get_storage_info (struct iouser *cred,
}
kern_return_t
-netfs_S_file_exec (struct protid *user,
- task_t task,
- int flags,
- char *argv,
- size_t argvlen,
- char *envp,
- size_t envplen,
- mach_port_t *fds,
- size_t fdslen,
- mach_port_t *portarray,
- size_t portarraylen,
- int *intarray,
- size_t intarraylen,
- mach_port_t *deallocnames,
- size_t deallocnameslen,
- mach_port_t *destroynames,
- size_t destroynameslen)
+netfs_S_file_exec_paths (struct protid *user,
+ task_t task,
+ int flags,
+ char *path,
+ char *abspath,
+ char *argv,
+ size_t argvlen,
+ char *envp,
+ size_t envplen,
+ mach_port_t *fds,
+ size_t fdslen,
+ mach_port_t *portarray,
+ size_t portarraylen,
+ int *intarray,
+ size_t intarraylen,
+ mach_port_t *deallocnames,
+ size_t deallocnameslen,
+ mach_port_t *destroynames,
+ size_t destroynameslen)
{
error_t err;
file_t file;
@@ -917,14 +919,30 @@ netfs_S_file_exec (struct protid *user,
if (!err)
{
+#ifdef HAVE_FILE_EXEC_PATHS
/* We cannot use MACH_MSG_TYPE_MOVE_SEND because we might need to
retry an interrupted call that would have consumed the rights. */
- err = file_exec (netfs_node_netnode (user->po->np)->file,
- task, flags, argv, argvlen,
- envp, envplen, fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
- portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
- intarray, intarraylen, deallocnames, deallocnameslen,
- destroynames, destroynameslen);
+ err = file_exec_paths (netfs_node_netnode (user->po->np)->file,
+ task, flags,
+ path, abspath,
+ argv, argvlen,
+ envp, envplen,
+ fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+ portarray, MACH_MSG_TYPE_COPY_SEND,
+ portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+ /* For backwards compatibility. Just drop it when we kill
+ file_exec. */
+ if (err == MIG_BAD_ID)
+#endif
+ err = file_exec (user->po->np->nn->file, task, flags, argv, argvlen,
+ envp, envplen, fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+ portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen,
+ intarray, intarraylen, deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+
mach_port_deallocate (mach_task_self (), file);
}
@@ -940,6 +958,39 @@ netfs_S_file_exec (struct protid *user,
return err;
}
+kern_return_t
+netfs_S_file_exec (struct protid *user,
+ task_t task,
+ int flags,
+ char *argv,
+ size_t argvlen,
+ char *envp,
+ size_t envplen,
+ mach_port_t *fds,
+ size_t fdslen,
+ mach_port_t *portarray,
+ size_t portarraylen,
+ int *intarray,
+ size_t intarraylen,
+ mach_port_t *deallocnames,
+ size_t deallocnameslen,
+ mach_port_t *destroynames,
+ size_t destroynameslen)
+{
+ return netfs_S_file_exec_paths (user,
+ task,
+ flags,
+ "",
+ "",
+ argv, argvlen,
+ envp, envplen,
+ fds, fdslen,
+ portarray, portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+}
+
error_t
netfs_S_io_map (struct protid *user,
mach_port_t *rdobj, mach_msg_type_name_t *rdobjtype,
diff --git a/utils/login.c b/utils/login.c
index 1a12c3cd..8d0cf92a 100644
--- a/utils/login.c
+++ b/utils/login.c
@@ -1,6 +1,7 @@
/* Hurdish login
- Copyright (C) 1995,96,97,98,99,2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2010
+ Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.org>
@@ -882,12 +883,22 @@ main(int argc, char *argv[])
}
}
- err = file_exec (exec, mach_task_self (), EXEC_DEFAULTS,
- sh_args, sh_args_len, env, env_len,
- fds, MACH_MSG_TYPE_COPY_SEND, 3,
- ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
- ints, INIT_INT_MAX,
- 0, 0, 0, 0);
+#ifdef HAVE_FILE_EXEC_PATHS
+ err = file_exec_paths (exec, mach_task_self (), EXEC_DEFAULTS, shell, shell,
+ sh_args, sh_args_len, env, env_len,
+ fds, MACH_MSG_TYPE_COPY_SEND, 3,
+ ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
+ ints, INIT_INT_MAX,
+ 0, 0, 0, 0);
+ /* Fallback in case the file server hasn't been restarted. */
+ if (err == MIG_BAD_ID)
+#endif
+ err = file_exec (exec, mach_task_self (), EXEC_DEFAULTS,
+ sh_args, sh_args_len, env, env_len,
+ fds, MACH_MSG_TYPE_COPY_SEND, 3,
+ ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
+ ints, INIT_INT_MAX,
+ 0, 0, 0, 0);
if (err)
error(5, err, "%s", shell);