Skip to content

Commit 17cb4f9

Browse files
fhgwrightmascguy
authored andcommitted
time.c: Fix overflow in high-precision thread time.
Using the generic syscall() to obtain the high-precision thread time is problematic because its declared return type is only int, which is inadequate for a runtime in nanoseconds. What was originally missed is that a proper function wrapper already exists in the 10.10+ libSystem, albeit undocumented and with no published prototype. The correct approach is simply to provide the missing prototype and call the function. Thanks to Un1q32@github for the bug report. TESTED: Passes all tests, including updated clock test with "slowness".
1 parent 361b32f commit 17cb4f9

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

src/time.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,6 @@ uint64_t mach_continuous_approximate_time(void)
316316
#include <unistd.h>
317317

318318
#include <sys/resource.h>
319-
#include <sys/syscall.h>
320319
#include <sys/time.h>
321320

322321
#include <mach/mach_init.h>
@@ -616,7 +615,7 @@ tvdiff2mach(const struct timeval *tv1, const struct timeval *tv2)
616615
}
617616

618617
/*
619-
* Get the best available thread time, using the syscall on 10.10+,
618+
* Get the best available thread time, using __thread_selfusage() on 10.10+,
620619
* but falling back to thread_info() on <10.10.
621620
*
622621
* In the latter case, a thread which has just started may not yet have
@@ -685,11 +684,14 @@ get_thread_usage_ts(struct timespec *ts)
685684

686685
#else /* __MPLS_TARGET_OSVER >= 101000 */
687686

688-
/* Get the CPU usage of the current thread via syscall, in nanoseconds. */
687+
/* Provide the missing prototype for the undocumented __thread_selfusage(). */
688+
extern uint64_t __thread_selfusage(void);
689+
690+
/* Get the CPU usage of the current thread, in nanoseconds. */
689691
static inline uint64_t
690692
get_thread_usage_ns(void)
691693
{
692-
uint64_t mach_time = syscall(SYS_thread_selfusage);
694+
uint64_t mach_time = __thread_selfusage();
693695

694696
return mach2nanos(mach_time);
695697
}
@@ -698,7 +700,7 @@ get_thread_usage_ns(void)
698700
static inline int
699701
get_thread_usage_ts(struct timespec *ts)
700702
{
701-
uint64_t mach_time = syscall(SYS_thread_selfusage);
703+
uint64_t mach_time = __thread_selfusage();
702704

703705
mach2timespec(mach_time, ts);
704706
return mach_time ? 0 : -1;

0 commit comments

Comments
 (0)