| 778 | } |
| 779 | |
| 780 | static char *activation_posix_walk_path(const char *directory) { |
| 781 | #ifdef __APPLE__ |
| 782 | static const char *const aliases[] = {"/tmp", "/var"}; |
| 783 | for (size_t index = 0; index < sizeof(aliases) / sizeof(aliases[0]); index++) { |
| 784 | const char *alias = aliases[index]; |
| 785 | size_t alias_length = strlen(alias); |
| 786 | if (strncmp(directory, alias, alias_length) != 0 || |
| 787 | (directory[alias_length] != '\0' && directory[alias_length] != '/')) { |
| 788 | continue; |
| 789 | } |
| 790 | struct stat alias_status; |
| 791 | char resolved[4096]; |
| 792 | if (lstat(alias, &alias_status) != 0 || !S_ISLNK(alias_status.st_mode) || |
| 793 | alias_status.st_uid != 0 || !realpath(alias, resolved)) { |
| 794 | return NULL; |
| 795 | } |
| 796 | struct stat resolved_status; |
| 797 | if (lstat(resolved, &resolved_status) != 0 || !S_ISDIR(resolved_status.st_mode) || |
| 798 | resolved_status.st_uid != 0) { |
| 799 | return NULL; |
| 800 | } |
| 801 | size_t needed = strlen(resolved) + strlen(directory + alias_length) + 1U; |
| 802 | char *mapped = malloc(needed); |
| 803 | if (!mapped) { |
| 804 | return NULL; |
| 805 | } |
| 806 | int written = snprintf(mapped, needed, "%s%s", resolved, directory + alias_length); |
| 807 | if (written <= 0 || (size_t)written >= needed) { |
| 808 | free(mapped); |
| 809 | return NULL; |
| 810 | } |
| 811 | return mapped; |
| 812 | } |
| 813 | #endif |
| 814 | return activation_string_copy(directory); |
| 815 | } |
| 816 | |
| 817 | /* ANCESTOR policy (#1535). World-writable is still fatal: any local user could |
| 818 | * swap a path component mid-transaction. GROUP-writable is not — it is the |
no test coverage detected