Skip to content

Bug fixes for Mac OS - #51

Open
slipher wants to merge 5 commits into
masterfrom
slipher/mac-bugfixes
Open

Bug fixes for Mac OS#51
slipher wants to merge 5 commits into
masterfrom
slipher/mac-bugfixes

Conversation

@slipher

@slipher slipher commented Jul 26, 2026

Copy link
Copy Markdown
Member
  • Prevent NaClLog from changing errno (actually this class of bug can affect any OS)
  • Fix Mach crash forwarding on arm64
  • Fix wrong clock_gettime(CLOCK_PROCESS_CPUTIME_ID) on arm64 Mac host

slipher added 5 commits July 25, 2026 19:47
The system's user library for the 'exc' Mach message doesn't work on my ARM Mac
(version 15.6.1): upon sending a message it crashes with a GUARD_TYPE_MACH_PORT
exception. Fix that by building the MIG-generated user code also (in addition
to the server code) and using that instead of the system's exception_raise.

I find that the error occurred due to mach_msg2_trap unexpectedly being called
with the MACH64_SEND_KOBJECT_CALL option. If I use the debugger to replace that
flag with MACH64_SEND_MQ_CALL, the send can succeed.

Or at least that's how it goes with a native ARM binary. I didn't repeat these
experiments with a Rosetta'd one.
Save and restore errno around the I/O calls in the NaClLog implementation. This
prevents a class of bugs caused by carelessly inserting log messages between an
erroring function call and further errno accesses. Such a bug in
NaClHostDescMap is revealed by nacl_desc_io_alloc_ctor_test on Mac OS 15.x.
The culprit there was a successful localtime_r call modifying errno the first
time NaClTimeStampString is called. But any of the actual I/O functions could
also fail and set errno. Or even succeed and set errno, which is generally
allowed by the relevant standards.

The alternative would be fixing each logging call site individually. But that
would be annoying, particularly in the case of some ultra-verbose log calls in
untrusted code that log syscall entry/exit. Doing it inside the logger seems
better since then the push/pop can be done only in the case that the message is
actually printed.
The NACL_CLOCK_PROCESS_CPUTIME_ID timer was broken on ARM Macs, as revealed by
run_clock_cputime_test and run_nacl_clock_cputime_test.

As described in
https://eclecticlight.co/2020/11/27/inside-m1-macs-time-and-logs/, ARM Macs
have a system clock tick duration of 125/3 ns. But for Rosetta-translated
process, the system pretends that the tick duration is 1 ns as it was for Intel
Macs. Accordingly, APIs that return ticks are scaled up by the 125/3 factor.
However Apple missed a spot: task_info() with the TASK_ABSOLUTETIME_INFO query
still returns a time based on the real tick rate, making the timer too slow by
a factor of ~42. It is rather inconvenient to find out the real tick rate from
inside a translated process. Fortunately, in Mac OS 10.12 the POSIX
clock_gettime API was added. So solve the problem by removing the entire
MacOS-specific NaClClockGetTime and NaClClockGetRes implemenations and using
the Linux implementation which is a simple pass-through to the host
clock_gettime and clock_getres.
@illwieckz

Copy link
Copy Markdown
Member

What does that mean:

Or at least that's how it goes with a native ARM binary. I didn't repeat these
experiments with a Rosetta'd one.

Is it supposed to fix something on both amd64 and arm64?

@slipher

slipher commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

What does that mean:

Or at least that's how it goes with a native ARM binary. I didn't repeat these
experiments with a Rosetta'd one.

Is it supposed to fix something on both amd64 and arm64?

The bug only occurs on arm64 machines. I created a simplified test program which replicates the crash. It turned out the test program always crashes on the arm64 host even with a native build, so I did the root cause investigation on the native version of the test program for simplicity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants