aboutsummaryrefslogtreecommitdiff
path: root/utils/login.c
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2022-01-02 01:23:27 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2022-01-04 01:09:32 +0100
commita179160d41424813a2cf07ab554180804ae14fdf (patch)
tree1a9eaa1fc2e5f38c98f421488791614023aad0ce /utils/login.c
parenta8d51bf0ce26fd26e00338540857f43b8a99e126 (diff)
downloadhurd-a179160d41424813a2cf07ab554180804ae14fdf.tar.gz
hurd-a179160d41424813a2cf07ab554180804ae14fdf.tar.bz2
hurd-a179160d41424813a2cf07ab554180804ae14fdf.zip
Fix leaking auth ports
We need to be extremely careful with auth ports since leaking them into subprocesses may expose a root-auth port to non-root processes. Notably, get_nonsugid_ids was caching it, thus preventing glibc's exec implementation from dropping it. Login is also reimplementing hurdexec but without all the cloexec logic. This commit fixes various auth leaks.
Diffstat (limited to 'utils/login.c')
-rw-r--r--utils/login.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/utils/login.c b/utils/login.c
index 44bce2fd..eb0ed845 100644
--- a/utils/login.c
+++ b/utils/login.c
@@ -415,6 +415,9 @@ main(int argc, char *argv[])
mach_port_t auth; /* The new shell's authentication. */
mach_port_t proc_server = getproc ();
pid_t pid = getpid (), sid;
+ mach_port_t *please_dealloc, *pdp;
+ struct hurd_userlink ulink_ports[INIT_PORT_MAX];
+ mach_port_t port;
/* These three functions are to do child-authenticated lookups. See
<hurd/lookup.h> for an explanation. */
@@ -684,16 +687,30 @@ main(int argc, char *argv[])
else
proc_setowner (proc_server, 0, 1); /* Clear the owner. */
+ /* XXX: we should be sharing the implementation with glibc's hurdexec */
+ please_dealloc = alloca ((3 + INIT_PORT_MAX + 1) * sizeof(mach_port_t));
+ pdp = please_dealloc;
+
/* Now start constructing the exec arguments. */
memset (ints, 0, sizeof (*ints) * INIT_INT_MAX);
arg = envz_get (args, args_len, "UMASK");
ints[INIT_UMASK] = arg && *arg ? strtoul (arg, 0, 8) : umask (0);
for (i = 0; i < 3; i++)
- fds[i] = getdport (i);
+ {
+ fds[i] = getdport (i);
+ *pdp++ = fds[i];
+ }
for (i = 0; i < INIT_PORT_MAX; i++)
+ {
ports[i] = MACH_PORT_NULL;
+
+ port = _hurd_port_get (&_hurd_ports[i], &ulink_ports[i]);
+ if (port != MACH_PORT_NULL)
+ *pdp++ = port;
+ }
+
ports[INIT_PORT_PROC] = getproc ();
ports[INIT_PORT_CTTYID] = getcttyid ();
ports[INIT_PORT_CRDIR] = getcrdir (); /* May be replaced below. */
@@ -850,7 +867,10 @@ main(int argc, char *argv[])
{
mach_port_t motd_node = child_lookup (arg, 0, O_RDONLY);
if (motd_node != MACH_PORT_NULL)
- cat (motd_node, arg);
+ {
+ cat (motd_node, arg);
+ mach_port_deallocate (mach_task_self (), motd_node);
+ }
}
else
mach_port_deallocate (mach_task_self (), hush_node);
@@ -890,7 +910,7 @@ main(int argc, char *argv[])
fds, MACH_MSG_TYPE_COPY_SEND, 3,
ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
ints, INIT_INT_MAX,
- 0, 0, 0, 0);
+ please_dealloc, pdp-please_dealloc, 0, 0);
/* Fallback in case the file server hasn't been restarted. */
if (err == MIG_BAD_ID)
#endif
@@ -899,7 +919,7 @@ main(int argc, char *argv[])
fds, MACH_MSG_TYPE_COPY_SEND, 3,
ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
ints, INIT_INT_MAX,
- 0, 0, 0, 0);
+ please_dealloc, pdp-please_dealloc, 0, 0);
if (err)
error(5, err, "%s", shell);