Mac沙箱:运行需要/ tmp的二进制工具

时间:2014-08-25 01:26:02

标签: c macos appstore-sandbox

我有一个沙盒Cocoa应用程序,在导出过程中,需要运行第三方命令行工具。此工具似乎是硬编码的,以便将/tmp用于其临时文件;沙盒不允许访问此文件夹,因此导出失败。

如何运行此工具?我无法访问其源代码,因此我无法修改它以使用NSTemporaryDirectory(),并且它似乎不尊重TMPTEMPDIR环境变量。由于我不理解的原因,给自己一个com.apple.security.temporary-exception.files.absolute-path.read-write权利似乎也不起作用。

有没有办法在我的沙箱中重新映射文​​件夹?我可以使用一些不起眼的技巧吗?我应该尝试以某种方式修补工具的二进制文件吗?我在这里结束了我的智慧。

3 个答案:

答案 0 :(得分:6)

我能够获得user3159253的DYLD_INSERT_LIBRARIES方法。我希望他们会写一个回答来描述它是如何运作的,所以我会留下详细说明并解释最终具体针对这个案例的部分。

感谢LLDB,肘部油脂,而不是Hopper的一点帮助,我能够确定第三方工具使用mkstemp()生成临时文件名和一些调用(并非所有)使用以/tmp开头的固定模板。然后我编写了一个libtmphack.dylib,它拦截了对mkstemp()的调用,并在调用标准库版本之前修改了参数。

由于mkstemp()获取指向预分配缓冲区的指针,我不觉得我可以重写一个以" / tmp"等短字符串开头的路径。到达沙箱内的Caches文件夹所需的非常长的字符串。相反,我选择创建一个名为" $ tmp"的符号链接。在当前的工作目录中。如果工具chdir()处于不合适的时间,这可能会中断,但幸运的是它似乎并没有这样做。

这是我的代码:

//
//  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's because it's 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);
    }
}

非常快速和肮脏,但它就像一个魅力。

答案 1 :(得分:2)

另一种解决方案是在子进程(或chroot选项)中使用posix_spawn将其根目录更改为沙箱中的目录。它的“/ tmp”将成为该目录中的“tmp”目录。

答案 2 :(得分:2)

由于@ BrentRoyal-Gordon已经发布了一个有效的解决方案,我只是复制了我的评论,这激发了他制作解决方案的目的:

为了修复程序行为,我会在DYLD_INSERT_LIBRARIES的帮助下拦截并覆盖一些系统调用,并使用自定义共享库和给定系统调用的自定义实现。

需要覆盖的系统调用的确切列表取决于应用程序的性质,可以使用基于MacOS DTrace内核工具构建的许多工具进行研究。例如。 dtrussHopper。 @ BrentRoyal-Gordon调查了该应用程序只能通过mkstemp的/适当/实现进行修复。

那就是它。我还不确定我是否应该获得赏金:)