bug-hurd
[Top][All Lists]
Advanced

[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 <address@hidden>
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
 
address@hidden file_exec
address@hidden file_exec_file_name
 Execution of programs on the Hurd is done through fileservers with the
address@hidden RPC.  The fileserver is expected to verify that the
-user is allowed to execute the file, make whatever modifications to the
address@hidden 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 <address@hidden>
 
@@ -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



reply via email to

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