[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/3] Add a file_exec_file_name RPC
From: |
Emilio Pozuelo Monfort |
Subject: |
[PATCH 2/3] Add a file_exec_file_name RPC |
Date: |
Mon, 26 Jul 2010 19:32:04 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.10) Gecko/20100619 Icedove/3.0.5 |
>From 459924a5bcd33464c732befb81a2c89397d4e13d Mon Sep 17 00:00:00 2001
From: Emilio Pozuelo Monfort <pochu27@gmail.com>
Date: Wed, 26 May 2010 01:27:40 +0200
Subject: [PATCH 2/3] Add a file_exec_file_name RPC
* hurd/fs.defs (file_exec): Deprecate in favor of...
(file_exec_file_name): ...this new RPC.
Change all implementations and forward old implementations to
the new version. Change all callers but fallback to old version.
Change comments and documentation.
---
TODO | 2 +-
doc/hurd.texi | 16 ++++----
exec/hashexec.c | 32 ++++++++++----
hurd/fs.defs | 28 +++++++++++--
hurd/hurd_types.h | 9 ++--
init/init.c | 81 ++++++++++++++++++++++++++----------
libdiskfs/boot-start.c | 2 +-
libdiskfs/file-exec.c | 74 ++++++++++++++++++++++++++++------
libfshelp/start-translator-long.c | 21 +++++++---
libnetfs/file-exec.c | 67 ++++++++++++++++++++++++++----
libtrivfs/file-exec.c | 27 ++++++++++++-
trans/fakeroot.c | 59 ++++++++++++++++++++++++---
utils/login.c | 23 +++++++---
13 files changed, 349 insertions(+), 92 deletions(-)
diff --git a/TODO b/TODO
index b541f38..84c547d 100644
--- a/TODO
+++ b/TODO
@@ -136,7 +136,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_file_name 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/doc/hurd.texi b/doc/hurd.texi
index c0238f9..723e985 100644
--- a/doc/hurd.texi
+++ b/doc/hurd.texi
@@ -2741,10 +2741,10 @@ write the file.
@node Program Execution
@subsection Program Execution
-@findex file_exec
+@findex file_exec_file_name
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_file_name} 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}.
@@ -2756,13 +2756,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_file_name} 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_file_name} 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.
@@ -2777,7 +2777,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_file_name}. Whatever error code @code{exec_exec_file_name}
-returns should be returned to the caller of @code{file_exec}.
+returns should be returned to the caller of @code{file_exec_file_name}.
@node File Locking
@subsection File Locking
diff --git a/exec/hashexec.c b/exec/hashexec.c
index 929d37b..fbf2e7e 100644
--- a/exec/hashexec.c
+++ b/exec/hashexec.c
@@ -422,15 +422,29 @@ check_hashbang (struct execdata *e,
return;
/* 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_file_name (interp_file,
+ oldtask, flags, 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)
+ 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);
if (! e->error)
diff --git a/hurd/fs.defs b/hurd/fs.defs
index 52d83bd..1f33e2a 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_file_name 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_file_name 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;
@@ -352,3 +354,21 @@ routine file_reparent (
RPT
parent: mach_port_t;
out new_file: mach_port_send_t);
+
+/* 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_file_name (
+ exec_file: file_t;
+ RPT
+ exec_task: task_t;
+ flags: int;
+ filename: 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 86b9bcb..ab8f65a 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.
@@ -76,7 +77,7 @@ typedef struct statfs64 fsys_statfsbuf_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_file_name 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. */
@@ -342,7 +343,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_file_name and exec_* */
enum
{
INIT_PORT_CWDIR,
@@ -356,7 +357,7 @@ enum
INIT_PORT_MAX
};
-/* Standard ints for file_exec and exec_* */
+/* Standard ints for file_exec_file_name and exec_* */
enum
{
INIT_UMASK,
diff --git a/init/init.c b/init/init.c
index 4645729..ab2e402 100644
--- a/init/init.c
+++ b/init/init.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 Free Software Foundation, Inc.
+ 2005, 2008, 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
@@ -375,13 +375,26 @@ run (const char *server, mach_port_t *ports, task_t *task)
printf ("Pausing for %s\n", prog);
getchar ();
}
- err = file_exec (file, *task, 0,
- (char *)prog, strlen (prog) + 1, /* 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);
+ err = file_exec_file_name (file, *task, 0, (char *)prog,
+ (char *)prog,
+ strlen (prog) + 1, /* 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)
+ err = file_exec (file, *task, 0,
+ (char *)prog, strlen (prog) + 1, /* 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;
@@ -468,14 +481,25 @@ 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);
+ err = file_exec_file_name (file, task, 0, 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)
+ 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)
@@ -1059,13 +1083,24 @@ 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);
+ err = file_exec_file_name (file, child_task, 0, 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)
+ 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);
+
mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]);
mach_port_deallocate (mach_task_self (), file);
free (args);
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index ad3cf1a..ba391a2 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -277,7 +277,7 @@ diskfs_start_bootstrap ()
mach_port_deallocate (mach_task_self (), bootpt);
assert_perror (err);
- /* Cache the exec server port for file_exec to use. */
+ /* Cache the exec server port for file_exec_file_name to use. */
_hurd_port_set (&_diskfs_exec_portcell, diskfs_exec);
}
diff --git a/libdiskfs/file-exec.c b/libdiskfs/file-exec.c
index 452240c..3f0d8d4 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_file_name 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,39 @@ diskfs_S_file_exec (struct protid *cred,
mach_port_t *destroynames,
size_t destroynameslen)
{
+ return diskfs_S_file_exec_file_name (cred,
+ task,
+ flags,
+ "",
+ argv, argvlen,
+ envp, envplen,
+ fds, fdslen,
+ portarray, portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+}
+
+kern_return_t
+diskfs_S_file_exec_file_name (struct protid *cred,
+ task_t task,
+ int flags,
+ char *filename,
+ 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 +170,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_file_name 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 +193,28 @@ 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);
+ err = exec_exec_file_name (execserver,
+ right, MACH_MSG_TYPE_COPY_SEND,
+ task, flags, filename,
+ argv, argvlen, envp, envplen,
+ fds, MACH_MSG_TYPE_COPY_SEND, fdslen,
+ portarray, MACH_MSG_TYPE_COPY_SEND,
+ portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+ /* Fallback in case the exec server hasn't been restarted. */
+ if (err == MIG_BAD_ID)
+ 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 5bf1454..87abba1 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.
@@ -265,11 +266,19 @@ fshelp_start_translator_long (fshelp_open_fn_t
underlying_open_fn,
ports[INIT_PORT_BOOTSTRAP] = bootstrap;
/* 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_file_name (executable, task, EXEC_DEFAULTS, 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)
+ 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 73c125b..8f4fbb6 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,39 @@ netfs_S_file_exec (struct protid *cred,
mach_port_t *destroynames,
size_t destroynameslen)
{
+ return netfs_S_file_exec_file_name (cred,
+ task,
+ flags,
+ "",
+ argv, argvlen,
+ envp, envplen,
+ fds, fdslen,
+ portarray, portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+}
+
+kern_return_t
+netfs_S_file_exec_file_name (struct protid *cred,
+ task_t task,
+ int flags,
+ char *filename,
+ 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 +167,29 @@ 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);
+ err = exec_exec_file_name (_netfs_exec,
+ right, MACH_MSG_TYPE_COPY_SEND,
+ task, flags, filename,
+ 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)
+ 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 a3ab048..f626955 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
@@ -40,3 +40,28 @@ trivfs_S_file_exec (trivfs_protid_t exec_file,
{
return EOPNOTSUPP;
}
+
+kern_return_t
+trivfs_S_file_exec_file_name (trivfs_protid_t exec_file,
+ mach_port_t reply,
+ mach_msg_type_name_t replyPoly,
+ mach_port_t exec_task,
+ int flags,
+ string_t filename,
+ 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/trans/fakeroot.c b/trans/fakeroot.c
index c110234..101c3fb 100644
--- a/trans/fakeroot.c
+++ b/trans/fakeroot.c
@@ -1,5 +1,5 @@
/* fakeroot -- a translator for faking actions that aren't really permitted
- Copyright (C) 2002, 2003, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2008, 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
@@ -705,6 +705,39 @@ netfs_S_file_exec (struct protid *user,
mach_port_t *destroynames,
size_t destroynameslen)
{
+ return netfs_S_file_exec_file_name (user,
+ task,
+ flags,
+ "",
+ argv, argvlen,
+ envp, envplen,
+ fds, fdslen,
+ portarray, portarraylen,
+ intarray, intarraylen,
+ deallocnames, deallocnameslen,
+ destroynames, destroynameslen);
+}
+
+kern_return_t
+netfs_S_file_exec_file_name (struct protid *user,
+ task_t task,
+ int flags,
+ char *filename,
+ 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;
@@ -723,11 +756,25 @@ netfs_S_file_exec (struct protid *user,
{
/* 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 (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);
+ err = file_exec_file_name (user->po->np->nn->file, task, flags,
+ filename,
+ 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)
+ 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);
}
diff --git a/utils/login.c b/utils/login.c
index 58c8214..193d653 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>
@@ -883,12 +884,20 @@ 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);
+ err = file_exec_file_name (exec, mach_task_self (), EXEC_DEFAULTS, 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)
+ 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);
--
1.7.1