summaryrefslogtreecommitdiff
path: root/libfshelp
diff options
context:
space:
mode:
authorSergey Bugaev <bugaevc@gmail.com>2021-05-29 17:32:13 +0300
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2022-08-10 22:14:28 +0200
commit386d55dd471accafea06502c74e67de0ceb3351d (patch)
treeeb1f8bc977958f536491be750e06aca7ddbdc9d7 /libfshelp
parent865e37787d2331d2d5b18a8cfaa31ba7bec9f71b (diff)
libfshelp: Handle proc port in fshelp_start_translator_long ()
While fshelp_start_translator_long () has been calling proc_setowner () on the task it creates, it has never reauthenticated its process. This meant that the translator, once started, could access processes authenticated same as the process that called fshelp_start_translator_long (). In particular, this means that any unprivileged translator started by a privileged parent translator had in fact had a privileged proc port, and could access other processes through it. With this change, fshelp_start_translator_long () will now reauthenticate the process it creates. Moreover, it will now respect a custom proc server port passed in the given ports.
Diffstat (limited to 'libfshelp')
-rw-r--r--libfshelp/start-translator-long.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/libfshelp/start-translator-long.c b/libfshelp/start-translator-long.c
index 40491fc7..af893ba2 100644
--- a/libfshelp/start-translator-long.c
+++ b/libfshelp/start-translator-long.c
@@ -205,7 +205,8 @@ fshelp_start_translator_long (fshelp_open_fn_t underlying_open_fn,
file_t executable;
mach_port_t bootstrap = MACH_PORT_NULL;
mach_port_t task = MACH_PORT_NULL;
- mach_port_t prev_notify, proc, saveport, childproc;
+ mach_port_t prev_notify, proc, saveport;
+ int deallocate_proc;
/* While from our function signature it appears that we support passing
incomplete port arrays of any type, this is what the implementation
@@ -250,15 +251,51 @@ fshelp_start_translator_long (fshelp_open_fn_t underlying_open_fn,
if (err)
goto lose_task;
- /* Designate TASK as our child and set it's owner accordingly. */
- proc = getproc ();
+ /* Designate TASK as our child, fill in its proc port, and set its owner
+ accordingly. */
+ if (ports[INIT_PORT_PROC] == MACH_PORT_NULL)
+ {
+ proc = getproc ();
+ deallocate_proc = 1;
+ }
+ else
+ {
+ proc = ports[INIT_PORT_PROC];
+ deallocate_proc = 0;
+ }
+
proc_child (proc, task);
- err = proc_task2proc (proc, task, &childproc);
- mach_port_deallocate (mach_task_self (), proc);
+ err = proc_task2proc (proc, task, &ports[INIT_PORT_PROC]);
+ if (!err)
+ err = proc_setowner (ports[INIT_PORT_PROC],
+ owner_uid,
+ owner_uid == (uid_t) -1);
+ if (deallocate_proc)
+ mach_port_deallocate (mach_task_self (), proc);
if (err)
goto lose_task;
- err = proc_setowner (childproc, owner_uid, owner_uid == (uid_t) -1);
- mach_port_deallocate (mach_task_self (), childproc);
+
+ /* If we have been passed an auth port, and it's different from our own,
+ reauthenticate the child proc. */
+ if (MACH_PORT_VALID (ports[INIT_PORT_AUTH])
+ && HURD_PORT_USE (&_hurd_ports[INIT_PORT_AUTH],
+ port != ports[INIT_PORT_AUTH]))
+ {
+ mach_port_t rend, newport = MACH_PORT_NULL;
+
+ rend = mach_reply_port ();
+ err = proc_reauthenticate (ports[INIT_PORT_PROC],
+ rend, MACH_MSG_TYPE_MAKE_SEND);
+
+ if (!err)
+ err = auth_user_authenticate (ports[INIT_PORT_AUTH],
+ rend, MACH_MSG_TYPE_MAKE_SEND,
+ &newport);
+
+ mach_port_mod_refs (mach_task_self (), rend,
+ MACH_PORT_RIGHT_RECEIVE, -1);
+ }
+
if (err)
goto lose_task;
@@ -318,6 +355,11 @@ fshelp_start_translator_long (fshelp_open_fn_t underlying_open_fn,
mach_port_deallocate (mach_task_self (), executable);
if (task != MACH_PORT_NULL)
mach_port_deallocate (mach_task_self (), task);
+ if (ports[INIT_PORT_PROC] != MACH_PORT_NULL)
+ {
+ mach_port_deallocate (mach_task_self (), ports[INIT_PORT_PROC]);
+ ports[INIT_PORT_PROC] = MACH_PORT_NULL;
+ }
return err;
}