Hello,
This patch (4/5) fixes various bugs and refines the I/O server routines, notification handlers and task numbering on the boot server. Key Changes: Selection and Readable Routines: The S_io_readable function has been made to safely check ioctl return values. The `S_io_select` and `S_io_select_timeout` functions have been redirected via the new `queue_select` mechanism, which includes appropriate time validation (EINVAL check). `S_io_stat` and Character Devices: The `S_io_stat` function has been updated to explicitly report a character device (`S_IFCHR | 0666`). Authentication Clean-up: `S_io_reauthenticate` now checks for valid objects and the authentication server. Memory deallocation errors in `S_io_reauthenticate`, where incorrect array sizes and pointers were passed to the `mig_deallocate` function, have been fixed. Security and Port Checks: A pseudo_privileged_host_port validation has been added to the S_host_reboot function. printf format strings for Mach ports have been corrected (%lu). Task Notification and Listing: Error handling in the `S_mach_notify_new_task` function has been updated to correctly deallocate memory for tasks and parent ports in the event of an error. The `S_processor_set_tasks` function has been updated with overflow checks, and it has been ensured that `pseudo_kernel` is listed correctly even if it is not present in the hash table. The patch is provided below for your reference: --- >From 6a9ac9915e800ddc9fe597d17f84bae441d13f30 Mon Sep 17 00:00:00 2001 From: Alperen ERKAN <[email protected]> Date: Sat, 16 Sep 2026 12:50:33 +0300 Subject: [PATCH 4/5] boot: fix io server routines, notifications and task listing Fix S_io_readable, route S_io_select/S_io_select_timeout through the new select queue, report a character device from S_io_stat, make S_io_reauthenticate check its arguments and fix the deallocation of the auth arrays, validate S_host_reboot, fix printf formats for mach ports, handle errors in S_mach_notify_new_task and list the pseudo kernel task in S_processor_set_tasks. --- hurd/boot/boot.c | 133 +++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------- 1 file changed, 63 insertions(+), 70 deletions(-) diff --git a/hurd/boot/boot.c b/hurd/boot/boot.c --- a/hurd/boot/boot.c +++ b/hurd/boot/boot.c @@ -1957,9 +1961,13 @@ S_io_readable (mach_port_t object, mach_msg_type_name_t reply_type, vm_size_t *amt) { + int avail; + if (object != pseudo_console) return EOPNOTSUPP; - ioctl (0, FIONREAD, amt); + if (ioctl (0, FIONREAD, &avail) < 0) + return errno; + *amt = avail; return 0; } @@ -2043,60 +1999,16 @@ S_io_get_icky_async_id (mach_port_t object, return EOPNOTSUPP; } -static kern_return_t -io_select_common (mach_port_t object, - mach_port_t reply_port, - mach_msg_type_name_t reply_type, - struct timespec *tsp, int *type) -{ - struct timeval tv, *tvp; - fd_set r, w, x; - int n; - - if (object != pseudo_console) - return EOPNOTSUPP; - - FD_ZERO (&r); - FD_ZERO (&w); - FD_ZERO (&x); - FD_SET (0, &r); - FD_SET (0, &w); - FD_SET (0, &x); - - if (tsp == NULL) - tvp = NULL; - else - { - tv.tv_sec = tsp->tv_sec; - tv.tv_usec = tsp->tv_nsec / 1000; - tvp = &tv; - } - - n = select (1, - (*type & SELECT_READ) ? &r : 0, - (*type & SELECT_WRITE) ? &w : 0, - (*type & SELECT_URG) ? &x : 0, - tvp); - if (n < 0) - return errno; - - if (! FD_ISSET (0, &r)) - *type &= ~SELECT_READ; - if (! FD_ISSET (0, &w)) - *type &= ~SELECT_WRITE; - if (! FD_ISSET (0, &x)) - *type &= ~SELECT_URG; - - return 0; -} - kern_return_t S_io_select (mach_port_t object, mach_port_t reply_port, mach_msg_type_name_t reply_type, int *type) { - return io_select_common (object, reply_port, reply_type, NULL, type); + if (object != pseudo_console) + return EOPNOTSUPP; + + return queue_select (reply_port, reply_type, *type, 0, NULL); } kern_return_t @@ -2062,7 +2068,13 @@ S_io_select_timeout (mach_port_t object, struct timespec ts, int *type) { - return io_select_common (object, reply_port, reply_type, &ts, type); + if (object != pseudo_console) + return EOPNOTSUPP; + + if (ts.tv_sec < 0 || ts.tv_nsec < 0 || ts.tv_nsec >= 1000000000L) + return EINVAL; + + return queue_select (reply_port, reply_type, *type, 1, &ts); } kern_return_t @@ -2081,6 +2082,7 @@ S_io_stat (mach_port_t object, return EOPNOTSUPP; memset (st, 0, sizeof(struct stat)); + st->st_mode = S_IFCHR | 0666; st->st_blksize = 1024; return 0; } @@ -2097,11 +2104,18 @@ S_io_reauthenticate (mach_port_t object, mach_msg_type_number_t gulen = 0, aulen = 0, gglen = 0, aglen = 0; error_t err; - /* XXX: This cannot possibly work, authserver is 0. */ + if (object != pseudo_console) + return EOPNOTSUPP; + + /* Without an auth server there is nobody to reauthenticate + against. */ + if (authserver == MACH_PORT_NULL) + return EOPNOTSUPP; err = mach_port_insert_right (mach_task_self (), object, object, MACH_MSG_TYPE_MAKE_SEND); - assert_perror_backtrace (err); + if (err) + return err; do err = auth_server_authenticate (authserver, @@ -2120,17 +2120,17 @@ S_io_reauthenticate (mach_port_t object, &ag, &aglen); while (err == EINTR); - if (!err) + if (! err) { mig_deallocate ((vm_address_t) gu, gulen * sizeof *gu); - mig_deallocate ((vm_address_t) au, aulen * sizeof *gu); - mig_deallocate ((vm_address_t) gg, gglen * sizeof *gu); - mig_deallocate ((vm_address_t) au, aulen * sizeof *gu); + mig_deallocate ((vm_address_t) au, aulen * sizeof *au); + mig_deallocate ((vm_address_t) gg, gglen * sizeof *gg); + mig_deallocate ((vm_address_t) ag, aglen * sizeof *ag); } mach_port_deallocate (mach_task_self (), rend); mach_port_deallocate (mach_task_self (), object); - return 0; + return err; } kern_return_t @@ -2419,6 +2422,9 @@ kern_return_t S_host_reboot (mach_port_t host_priv, int flags) { + if (host_priv != pseudo_privileged_host_port) + return KERN_INVALID_HOST; + fprintf (stderr, "Would %s the system. Bye.\r\n", flags & RB_HALT? "halt": "reboot"); host_exit (0); @@ -2475,7 +2475,7 @@ static void task_died (mach_port_t name) { if (verbose > 1) - fprintf (stderr, "Task '%u' died.\r\n", name); + fprintf (stderr, "Task '%lu' died.\r\n", (unsigned long) name); hurd_ihash_remove (&task_ihash, (hurd_ihash_key_t) name); } @@ -2493,7 +2494,8 @@ S_mach_notify_new_task (mach_port_t notify, return EOPNOTSUPP; if (verbose > 1) - fprintf (stderr, "Task '%u' created by task '%u'.\r\n", task, parent); + fprintf (stderr, "Task '%lu' created by task '%lu'.\r\n", + (unsigned long) task, (unsigned long) parent); err = mach_port_request_notification (mach_task_self (), task, MACH_NOTIFY_DEAD_NAME, 0, @@ -2505,15 +2505,15 @@ S_mach_notify_new_task (mach_port_t notify, goto fail; assert_backtrace (! MACH_PORT_VALID (previous)); - mach_port_mod_refs (mach_task_self (), task, MACH_PORT_RIGHT_SEND, +1); + err = mach_port_mod_refs (mach_task_self (), task, MACH_PORT_RIGHT_SEND, + +1); + if (err) + goto fail; err = hurd_ihash_add (&task_ihash, (hurd_ihash_key_t) task, (hurd_ihash_value_t)(uintptr_t) task); if (err) - { - mach_port_deallocate (mach_task_self (), task); - goto fail; - } + goto fail; if (MACH_PORT_VALID (new_task_notification)) /* Relay the notification. This consumes task and parent. */ @@ -2525,6 +2527,8 @@ S_mach_notify_new_task (mach_port_t notify, fail: task_terminate (task); + mach_port_deallocate (mach_task_self (), task); + mach_port_deallocate (mach_task_self (), parent); return err; } @@ -2536,16 +2549,29 @@ S_processor_set_tasks(mach_port_t processor_set, mach_msg_type_number_t *task_listCnt) { error_t err; - size_t i; + size_t i, count; + int kernel_in_hash = 0; + hurd_ihash_value_t value; - if (!task_ihash.nr_items) + if (processor_set != pseudo_pset) + return KERN_INVALID_ARGUMENT; + + if (! MACH_PORT_VALID (pseudo_kernel)) { *task_listCnt = 0; return 0; } + HURD_IHASH_ITERATE (&task_ihash, value) + if ((task_t) (uintptr_t) value == pseudo_kernel) + kernel_in_hash = 1; + + count = task_ihash.nr_items + (kernel_in_hash ? 0 : 1); + if (count > SIZE_MAX / sizeof **task_list) + return KERN_RESOURCE_SHORTAGE; + err = vm_allocate (mach_task_self (), (vm_address_t *) task_list, - task_ihash.nr_items * sizeof **task_list, 1); + count * sizeof **task_list, 1); if (err) return err; @@ -2568,14 +2568,14 @@ S_processor_set_tasks(mach_port_t processor_set, i = 1; HURD_IHASH_ITERATE (&task_ihash, value) { - task_t task = (task_t)(uintptr_t) value; + task_t task = (task_t) (uintptr_t) value; if (task == pseudo_kernel) - continue; + continue; (*task_list)[i] = task; i += 1; } - *task_listCnt = task_ihash.nr_items; + *task_listCnt = i; return 0; } -- 2.43.0
