Mac sandbox: running a binary tool that needs / tmp

I have a Cocoa sandbox application that should run a third-party command line tool during the export process. This tool looks hardcoded to use /tmp for its temporary files; the sandbox does not allow access to this folder, so the export does not work.

How can I run this tool? I do not have access to its source code, so I cannot modify it to use NSTemporaryDirectory() , and it does not match the TMP or TEMPDIR environment variables. For reasons I don’t understand, granting me the right com.apple.security.temporary-exception.files.absolute-path.read-write does not work either.

Is there a way to reinstall folders in my sandbox? Is there any obscure trick I can use? Should I try to fix the binary somehow? I am here here.

+7
c macos appstore-sandbox
source share
3 answers

Since @ BrentRoyal-Gordon has already posted a working solution, I just duplicate my comment that inspired him to create the solution:

To fix the behavior of the program, I would intercept and cancel some system calls using DYLD_INSERT_LIBRARIES and a custom shared library with a custom implementation of these system calls.

The exact list of system calls that need to be redefined depends on the nature of the application and can be studied using a number of tools based on the MacOS DTrace kernel. For example. dtruss or hopper . @ BrentRoyal-Gordon researched that an application can only be installed with / appropriate / mkstemp implementation.

What is it. I'm still not sure I deserve a reward :)

+2
source share

I was able to access user3159253 DYLD_INSERT_LIBRARIES . I hope they write an answer describing how this works, so I will leave the details of this and explain the parts that turned out to be specific to this case.

Thanks to LLDB, ulnar lubrication, and helping Hopper a lot, I was able to determine that a third-party tool used mkstemp() to generate its temporary file names, and some calls (not all) used a fixed pattern starting with /tmp . Then I wrote libtmphack.dylib, which intercepted calls to mkstemp() and changed the parameters before calling the standard version of the library.

Since mkstemp() takes a pointer to a previously allocated buffer, I did not want to rewrite the path starting with a short line, such as "/ tmp", to the very long line needed to go to the Caches folder inside the sandbox. Instead, I decided to create a symlink named "$ tmp" in the current working directory. This may break if the chdir() 'd tool is at the wrong time, but, fortunately, it doesn't look like this.

Here is my code:

 // // libtmphack.c // Typesetter // // Created by Brent Royal-Gordon on 8/27/14. // Copyright (c) 2014 Groundbreaking Software. This file is MIT licensed. // #include "libtmphack.h" #include <dlfcn.h> #include <stdlib.h> #include <unistd.h> //#include <errno.h> #include <string.h> static int gbs_has_prefix(char * needle, char * haystack) { return strncmp(needle, haystack, strlen(needle)) == 0; } int mkstemp(char *template) { static int (*original_mkstemp)(char * template) = NULL; if(!original_mkstemp) { original_mkstemp = dlsym(RTLD_NEXT, "mkstemp"); } if(gbs_has_prefix("/tmp", template)) { printf("libtmphack: rewrote mkstemp(\"%s\") ", template); template[0] = '$'; printf("to mkstemp(\"%s\")\n", template); // If this isn't successful, we'll presume it because it already been made symlink(getenv("TEMP"), "$tmp"); int ret = original_mkstemp(template); // Can't do this, the caller needs to be able to open the file // int retErrno = errno; // unlink("$tmp"); // errno = retErrno; return ret; } else { printf("libtmphack: OK with mkstemp(\"%s\")\n", template); return original_mkstemp(template); } } 

Very fast and dirty, but it works like a charm.

+6
source share

Another solution would be to use chroot in the child process (or posix_spawn options) to change its root directory to the directory that is in your sandbox. Its “/ tmp” will then be the “tmp” directory in this directory.

+2
source share

All Articles