Hello,
Attached are two small patches to enable the third argument of adjtime() to be
NULL, see adjtime(3). Calling __host_adjust_time() with a third argument being
NULL, causes a segfault due to the *old_adjustment = OutP->old_adjustment
statement in RPC_host_adjust_time.c.
The glibc patch sysdeps_mach_hurd_adjtime.c.diff use a dummy struct timeval to
avoid calling ___host_adjust_time() in _adjtime() with a NULL third argument.
Smarter solutions can probably be found, comments are welcome.
The gnumach patch, 80_mach_clock.patch sets the old_adjustment to oadj only if
old_adjustment is non-null. This patch is probably redundant but included here
anyway.
TODO: EINVAL should also be returned if the supplied delta is too large, as
described in adjtime(3). This would be easy to fix, by a slight modification of
adjtime.c and/or mach_clock.c.
Thanks!
Index: gnumach-1.7+git20160809/kern/mach_clock.c
===================================================================
--- gnumach-1.7+git20160809.orig/kern/mach_clock.c
+++ gnumach-1.7+git20160809/kern/mach_clock.c
@@ -533,7 +533,9 @@ host_adjust_time(host, new_adjustment, o
thread_bind(current_thread(), PROCESSOR_NULL);
#endif /* NCPUS > 1 */
- *old_adjustment = oadj;
+ /* Allow *old_adjustment to be NULL: see man adjtime(3) */
+ if (old_adjustment)
+ *old_adjustment = oadj;
return (KERN_SUCCESS);
}
Index: glibc-2.23/sysdeps/mach/hurd/adjtime.c
===================================================================
--- glibc-2.23.orig/sysdeps/mach/hurd/adjtime.c
+++ glibc-2.23/sysdeps/mach/hurd/adjtime.c
@@ -28,16 +28,25 @@ __adjtime (const struct timeval *delta,
{
error_t err;
mach_port_t hostpriv;
+ struct timeval dummy = {0, 0};
err = __get_privileged_ports (&hostpriv, NULL);
if (err)
return __hurd_fail (EPERM);
- err = __host_adjust_time (hostpriv,
- /* `time_value_t' and `struct timeval' are in
- fact identical with the names changed. */
- *(time_value_t *) delta,
- (time_value_t *) olddelta);
+ if (olddelta)
+ err = __host_adjust_time (hostpriv,
+ /* `time_value_t' and `struct timeval' are in
+ fact identical with the names changed. */
+ *(time_value_t *) delta,
+ (time_value_t *) olddelta);
+ else
+ /* Handle the case when olddelta is NULL, see man adjtime(3) */
+ err = __host_adjust_time (hostpriv,
+ /* `time_value_t' and `struct timeval' are in
+ fact identical with the names changed. */
+ *(time_value_t *) delta,
+ (time_value_t *) &dummy);
__mach_port_deallocate (__mach_task_self (), hostpriv);
if (err)