<pre style='margin:0'>
Clemens Lang (neverpanic) pushed a commit to branch master
in repository macports-base.
</pre>
<p><a href="https://github.com/macports/macports-base/commit/4a1b0c70c41473882f9fc1cb994487ac3855d884">https://github.com/macports/macports-base/commit/4a1b0c70c41473882f9fc1cb994487ac3855d884</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 4a1b0c70c41473882f9fc1cb994487ac3855d884
</span>Author: Clemens Lang <neverpanic@gmail.com>
AuthorDate: Wed Sep 27 21:13:47 2023 +0200
<span style='display:block; white-space:pre;color:#404040;'> darwintrace: Resign with codesign when copying
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> macOS Ventura seems to have broken trace mode because it kills signed
</span><span style='display:block; white-space:pre;color:#404040;'> processes when preload libraries are present. Fix this by re-signing
</span><span style='display:block; white-space:pre;color:#404040;'> binaries when copying them.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> I tested this on x86_64 Ventura, where it works as expected.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Closes: https://trac.macports.org/ticket/66358
</span>---
src/pextlib1.0/sip_copy_proc.c | 81 ++++++++++++++++++++++++++++++++++++------
1 file changed, 70 insertions(+), 11 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/pextlib1.0/sip_copy_proc.c b/src/pextlib1.0/sip_copy_proc.c
</span><span style='display:block; white-space:pre;color:#808080;'>index e7b5c4009..7394d3fe0 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/pextlib1.0/sip_copy_proc.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/pextlib1.0/sip_copy_proc.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -277,6 +277,61 @@ static copy_needed_return_t copy_needed(const char *path, char *const argv[],
</span> #endif /* defined(SF_RESTRICTED) */
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+static int resign(const char *filepath) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int result = -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int exitstatus = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ pid_t pid = (pid_t) -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ posix_spawn_file_actions_t action = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *path = strdup(filepath);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!path) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ goto resign_out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char * const argv[] = {"codesign", "-s", "-", "-f", path, NULL};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char * const envp[] = {NULL};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((errno = posix_spawn_file_actions_init(&action)) != 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "posix_spawn_file_actions_init() failed: %s\n", strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ goto resign_out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((errno = posix_spawn_file_actions_addopen(&action, STDOUT_FILENO, "/dev/null", O_WRONLY|O_APPEND, 0)) != 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "posix_spawn_file_actions_addopen(STDOUT_FILENO, /dev/null) failed: %s", strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ goto resign_out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((errno = posix_spawn_file_actions_addopen(&action, STDERR_FILENO, "/dev/null", O_WRONLY|O_APPEND, 0)) != 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "posix_spawn_file_actions_addopen(STDERR_FILENO, /dev/null) failed: %s", strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ goto resign_out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (0 != (errno = posix_spawn(&pid, "/usr/bin/codesign", &action, NULL, argv, envp))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "Failed to spawn /usr/bin/codesign -s - -f %s: %s\n", path, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ goto resign_out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (pid != waitpid(pid, &exitstatus, 0)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "waitpid(%d): %s\n", pid, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ goto resign_out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (WIFEXITED(exitstatus) && WEXITSTATUS(exitstatus) == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ result = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (WIFSIGNALED(exitstatus)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "codesign %s terminated with signal %d\n", path, WTERMSIG(exitstatus));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "codesign %s exited with non-zero status %d\n", path, WEXITSTATUS(exitstatus));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ goto resign_out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+resign_out:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (action != NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ posix_spawn_file_actions_destroy(&action);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ free(path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> static char *lazy_copy(const char *path, struct stat *in_st) {
char *retval = NULL;
uid_t euid = geteuid();
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -363,15 +418,6 @@ static char *lazy_copy(const char *path, struct stat *in_st) {
</span> #endif
goto lazy_copy_out;
}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // Since we removed COPYFILE_STAT from the copyfile(3) invocation above, we
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // need to restore the permissions on the copy. Note that the futimes(2)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // later on should still succeed even if we remove write permissions here,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // because we already have a file descriptor open.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if (-1 == fchmod(outfd, in_st->st_mode)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- fprintf(stderr, "sip_copy_proc: fchmod(%s, %o): %s\n", target_path_temp, in_st->st_mode, strerror(errno));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- goto lazy_copy_out;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span> #else /* !HAVE_COPYFILE */
// create temporary file to copy into and then later atomically replace
// target file
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -434,11 +480,24 @@ static char *lazy_copy(const char *path, struct stat *in_st) {
</span> }
#endif /* HAVE_COPYFILE */
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == resign(target_path_temp)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "sip_copy_proc: resign(%s) failed\n", target_path_temp);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ goto lazy_copy_out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> struct timeval times[2];
TIMESPEC_TO_TIMEVAL(×[0], &in_st->st_mtimespec);
TIMESPEC_TO_TIMEVAL(×[1], &in_st->st_mtimespec);
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if (-1 == futimes(outfd, times)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- fprintf(stderr, "sip_copy_proc: futimes(%s): %s\n", target_path_temp, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == utimes(target_path_temp, times)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "sip_copy_proc: utimes(%s): %s\n", target_path_temp, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ goto lazy_copy_out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // Since we removed COPYFILE_STAT from the copyfile(3) invocation above, we
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // need to restore the permissions on the copy. Keep this after the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // utimes(2) call, or setting the times may fail due to lack of write permissions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (-1 == chmod(target_path_temp, in_st->st_mode)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "sip_copy_proc: chmod(%s, %o): %s\n", target_path_temp, in_st->st_mode, strerror(errno));
</span> goto lazy_copy_out;
}
</pre><pre style='margin:0'>
</pre>