Opened 6 years ago

Last modified 4 months ago

#60818 reopened enhancement

darwintrace cannot inject into binaries of a different architecture (missing arm64e)

Reported by: saagarjha (Saagar Jha) Owned by:
Priority: Normal Milestone:
Component: base Version:
Keywords: tracemode Cc: herbygillot (Herby Gillot)
Port:

Description

darwintrace injects code into every process during installation, and these processes can have different architectures. If darwintrace does not have a slice that matches the process, it will fail to load; it might be worth compiling it as universal (including arm64e–note this requires undocumented ptrauth ABI) regardless of configure flags.

Change History (10)

comment:1 Changed 6 years ago by ryandesign (Ryan Carsten Schmidt)

Type: defectenhancement

We already do compile darwintrace universal for this reason, though it would not surprise me if arm64 is not among the architectures it uses for that yet, since arm64 Macs were only just announced.

comment:2 Changed 4 years ago by neverpanic (Clemens Lang)

Resolution: fixed
Status: newclosed

Ever since [de1977a709f86b2e663ffc1f43ae70b075fc4e9a/macports-base], trace mode is compiled with CFLAGS += $(UNIVERSAL_ARCHFLAGS). [6eaa8d5ee9e8f05ece837bcecdc5abda882e584b/macports-base] changed that to include arm64, so this should now be solved.

Please re-open if this still occurs.

comment:3 Changed 4 years ago by saagarjha (Saagar Jha)

Not sure if this need to be reopened, for users with SIP disabled trace mode will attempt to inject into system tooling as well (which it did so successfully on x86_64). On Apple silicon these tools are compiled as "arm64e" and this will fail, so I was wondering if we should also include this slice.

comment:4 Changed 4 years ago by miriam-rittenberg (Miriam Rittenberg)

Resolution: fixed
Status: closedreopened

Yes, darwintrace does not work for me with SIP disabled on an arm mac, though it works fine with SIP enabled:

Executing:  cd "/opt/local/var/macports/build/_Users_mrittenb_programming_macports-ports_net_ldapvi/ldapvi/work/ldapvi-1.7" && /usr/bin/make -w install prefix=/opt/local/var/macports/build/_Users_mrittenb_programming_macports-ports_net_ldapvi/ldapvi/work/destroot/opt/local 
dyld[52238]: terminating because inserted dylib '/opt/local/libexec/macports/lib/darwintrace1.0/darwintrace.dylib' could not be loaded: tried: '/opt/local/libexec/macports/lib/darwintrace1.0/darwintrace.dylib' (fat file, but missing compatible architecture (have 'x86_64,arm64', need 'arm64e')), '/usr/local/lib/darwintrace.dylib' (no such file), '/usr/lib/darwintrace.dylib' (no such file)
Last edited 3 years ago by ryandesign (Ryan Carsten Schmidt) (previous) (diff)

comment:5 Changed 4 years ago by raimue (Rainer Müller)

Summary: darwintrace cannot inject into binaries of a different architecturedarwintrace cannot inject into binaries of a different architecture (missing arm64e)

The missing part is arm64e, which is a new ABI to support Pointer Authentication as specified with ARMv8.3.

https://developer.apple.com/documentation/security/preparing_your_app_to_work_with_pointer_authentication

However, Apple does not consider this ABI as stable. The use of arm64e seems to be limited to binaries signed by Apple. As I have read, it is actually used in binaries in /usr/bin but I cannot confirm this. I assume (!) this limitation also applies to libraries and therefore we cannot just build darwintrace.dylib for arm64e and inject it into the process.

Maybe a possible workaround would be to force use of arm64 for such binaries with something like arch -arm64 /usr/bin/...? This could be done in the SIP workaround that we have to use anyway.

comment:6 Changed 4 months ago by herbygillot (Herby Gillot)

We're seeing test failures because of this issue. Here's a PR addressing that: https://github.com/macports/macports-base/pull/387

comment:7 Changed 4 months ago by herbygillot (Herby Gillot)

In f392589709732a3cdb82f134666fde33880861b2/macports-base (master):

tests: avoid arm64e dyld failures in darwintrace tests

Replace darwintrace test setup and cleanup steps that invoke system
binaries under DYLD_INSERT_LIBRARIES.

On macOS 15 arm64 GitHub runners, some Apple binaries used by the
tests are arm64e, while darwintrace.dylib is built with x86_64 and
arm64 slices. Injecting the library into those helpers causes dyld to
abort before the test body runs.

Use Pextlib symlink creation in the affected tests and add a local rmrf
helper for the long-path cleanup case so the suite no longer depends on
traced system ln/rm binaries.

See: #60818

comment:8 Changed 4 months ago by ryandesign (Ryan Carsten Schmidt)

Cc: herbygillot added

That causes test failure on OS X 10.9 and earlier.

clang -std=gnu11 -g -O2 -std=c99 -Wextra -Wall -pedantic  -DHAVE_CONFIG_H -I/opt/bblocal/var/buildworker/base/build/src -I/opt/bblocal/var/buildworker/base/build/src -I. -I/opt/bblocal/var/buildworker/base/build/vendor/vendor-destroot/opt/bblocal/var/buildworker/base/base-10_9_x86_64/opt/local/libexec/macports/include  -c -o rmrf.o rmrf.c
rmrf.c:14:9: warning: implicit declaration of function 'fstatat' is invalid in C99 [-Wimplicit-function-declaration]
    if (fstatat(parentfd, name, &st, AT_SYMLINK_NOFOLLOW) != 0) {
        ^
rmrf.c:14:38: error: use of undeclared identifier 'AT_SYMLINK_NOFOLLOW'
    if (fstatat(parentfd, name, &st, AT_SYMLINK_NOFOLLOW) != 0) {
                                     ^
rmrf.c:19:18: warning: implicit declaration of function 'openat' is invalid in C99 [-Wimplicit-function-declaration]
        int fd = openat(parentfd, name, O_RDONLY | O_DIRECTORY);
                 ^
rmrf.c:24:20: warning: implicit declaration of function 'fdopendir' is invalid in C99 [-Wimplicit-function-declaration]
        DIR *dir = fdopendir(fd);
                   ^
rmrf.c:24:14: warning: incompatible integer to pointer conversion initializing 'DIR *' with an expression of type 'int' [-Wint-conversion]
        DIR *dir = fdopendir(fd);
             ^     ~~~~~~~~~~~~~
rmrf.c:57:13: warning: implicit declaration of function 'unlinkat' is invalid in C99 [-Wimplicit-function-declaration]
        if (unlinkat(parentfd, name, AT_REMOVEDIR) != 0) {
            ^
rmrf.c:57:38: error: use of undeclared identifier 'AT_REMOVEDIR'
        if (unlinkat(parentfd, name, AT_REMOVEDIR) != 0) {
                                     ^
rmrf.c:75:21: error: use of undeclared identifier 'AT_FDCWD'
        if (rmrf_at(AT_FDCWD, argv[i]) != 0) {
                    ^
5 warnings and 3 errors generated.
make[3]: *** [rmrf.o] Error 1
make[2]: *** [test] Error 2
make[1]: *** [test] Error 1
make: *** [test] Error 1
program finished with exit code 2

comment:9 in reply to:  8 Changed 4 months ago by herbygillot (Herby Gillot)

Replying to ryandesign:

That causes test failure on OS X 10.9 and earlier.

clang -std=gnu11 -g -O2 -std=c99 -Wextra -Wall -pedantic  -DHAVE_CONFIG_H -I/opt/bblocal/var/buildworker/base/build/src -I/opt/bblocal/var/buildworker/base/build/src -I. -I/opt/bblocal/var/buildworker/base/build/vendor/vendor-destroot/opt/bblocal/var/buildworker/base/base-10_9_x86_64/opt/local/libexec/macports/include  -c -o rmrf.o rmrf.c
rmrf.c:14:9: warning: implicit declaration of function 'fstatat' is invalid in C99 [-Wimplicit-function-declaration]
    if (fstatat(parentfd, name, &st, AT_SYMLINK_NOFOLLOW) != 0) {
        ^
rmrf.c:14:38: error: use of undeclared identifier 'AT_SYMLINK_NOFOLLOW'
    if (fstatat(parentfd, name, &st, AT_SYMLINK_NOFOLLOW) != 0) {
                                     ^
rmrf.c:19:18: warning: implicit declaration of function 'openat' is invalid in C99 [-Wimplicit-function-declaration]
        int fd = openat(parentfd, name, O_RDONLY | O_DIRECTORY);
                 ^
rmrf.c:24:20: warning: implicit declaration of function 'fdopendir' is invalid in C99 [-Wimplicit-function-declaration]
        DIR *dir = fdopendir(fd);
                   ^
rmrf.c:24:14: warning: incompatible integer to pointer conversion initializing 'DIR *' with an expression of type 'int' [-Wint-conversion]
        DIR *dir = fdopendir(fd);
             ^     ~~~~~~~~~~~~~
rmrf.c:57:13: warning: implicit declaration of function 'unlinkat' is invalid in C99 [-Wimplicit-function-declaration]
        if (unlinkat(parentfd, name, AT_REMOVEDIR) != 0) {
            ^
rmrf.c:57:38: error: use of undeclared identifier 'AT_REMOVEDIR'
        if (unlinkat(parentfd, name, AT_REMOVEDIR) != 0) {
                                     ^
rmrf.c:75:21: error: use of undeclared identifier 'AT_FDCWD'
        if (rmrf_at(AT_FDCWD, argv[i]) != 0) {
                    ^
5 warnings and 3 errors generated.
make[3]: *** [rmrf.o] Error 1
make[2]: *** [test] Error 2
make[1]: *** [test] Error 1
make: *** [test] Error 1
program finished with exit code 2

PR to fix is here: https://github.com/macports/macports-base/pull/393

comment:10 Changed 4 months ago by herbygillot (Herby Gillot)

In 48bd88581cdc269e74b5dbbb413d9b562e091b67/macports-base (master):

tests: fix rmrf helper to compile on OS X 10.5+

Replace POSIX.1-2008 *at() functions (fstatat, openat, unlinkat,
fdopendir) with traditional alternatives (lstat, opendir, rmdir,
unlink). The *at() family was introduced in macOS 10.10, so the
previous implementation failed to compile on 10.9 and earlier.

See: #60818

Co-Authored-By: Claude Opus 4.6 <noreply@…>

Note: See TracTickets for help on using tickets.