gpt4 book ai didi

c - 如何创建一个轻量级的 C 代码沙箱?

转载 作者:太空狗 更新时间:2023-10-29 16:20:56 25 4
gpt4 key购买 nike

我想构建一个 C 预处理器/编译器,允许从本地和在线资源收集函数。 IE:

#fetch MP3FileBuilder http://scripts.com/MP3Builder.gz
#fetch IpodDeviceReader http://apple.com/modules/MP3Builder.gz

void mymodule_main() {
MP3FileBuilder(&some_data);
}

这是容易的部分。

硬的部分是 我需要一种可靠的方法来“沙箱”导入的代码,使其直接或不受限制地访问磁盘或系统资源(包括内存分配和堆栈) .我想要一种安全运行的方法 不受信任的 C 代码的小片段 (模块)没有将它们放在单独的进程、VM 或解释器中的开销(尽管可以接受单独的线程)。

要求
  • 我需要对其访问数据和资源(包括 CPU 时间)设置配额。
  • 我将阻止直接访问标准库
  • 我想阻止产生无限递归的恶意代码
  • 我想将静态和动态分配限制为特定限制
  • 我想捕获模块可能引发的所有异常(例如除以 0)。
  • 模块只能通过核心接口(interface)与其他模块交互
  • 模块只能通过核心接口(interface)与系统(I/O 等)交互
  • 模块必须允许位操作、数学、数组、枚举、循环和分支。
  • 模块不能使用 ASM
  • 我想限制对为模块保留的内存的指针和数组访问(通过自定义 safe_malloc())
  • 必须支持 ANSI C 或子集(见下文)
  • 系统必须是轻量级和跨平台的(包括嵌入式系统)。
  • 系统必须与 GPL 或 LGPL 兼容。

  • 我很乐意接受 C 的一个子集。我不需要模板或类之类的东西。我主要对高级语言不擅长的事情感兴趣,比如快速数学、位运算以及二进制数据的搜索和处理。

    不是 旨在无需修改即可重用现有 C 代码以创建模块。目的是要求模块符合一组规则和限制,旨在将模块限制为基本逻辑和转换操作(例如视频转码或压缩操作)。

    这种编译器/预处理器的理论输入将是一个带有 module_main 函数的单个 ANSI C 文件(或安全子集),没有包含或预处理器指令,没有 ASM,它将允许循环、分支、函数调用、指针数学(仅限于分配给模块的范围)、位移、位域、强制转换、枚举、数组、整数、浮点数、字符串和数学。其他任何东西都是可选的。

    示例实现

    这是一个伪代码片段,可以更好地解释这一点。这里一个模块超出了它的内存分配配额,并且还会创建无限递归。
    buffer* transcodeToAVI_main( &in_buffer ) {
    int buffer[1000000000]; // allocation exceeding quota
    while(true) {} // infinite loop
    return buffer;
    }

    这是一个转换后的版本,我们的预处理器添加了观察点来检查内存使用和递归,并将整个内容包装在异常处理程序中。
    buffer* transcodeToAVI_main( &in_buffer ) {
    try {
    core_funcStart(__FILE__,__FUNC__); // tell core we're executing this function
    buffer = core_newArray(1000000000, __FILE__, __FUNC__); // memory allocation from quota
    while(true) {
    core_checkLoop(__FILE__, __FUNC__, __LINE__) && break; // break loop on recursion limit
    }
    core_moduleEnd(__FILE__,__FUNC__);
    } catch {
    core_exceptionHandler(__FILE__, __FUNC__);
    }
    return buffer;
    }

    我意识到执行这些检查会影响模块性能,但我怀疑它在要解决的任务方面仍会胜过高级语言或 VM 语言。我并不是要阻止模块直接做危险的事情,我只是试图以可控的方式(例如通过用户反馈)强制这些危险的事情发生。即:“模块 X 已超出其内存分配,是继续还是中止?”。

    更新

    到目前为止,我所拥有的最好的方法是使用带有边界检查的自定义编译器(如被黑的 TCC)以及一些自定义函数和循环代码来捕获递归。我仍然想听听关于我还需要检查什么或有什么解决方案的想法。我想在使用前删除 ASM 并检查指针可以解决以下先前答案中表达的许多问题。我添加了一个赏金来从 SO 社区中 pry 出更多反馈。

    对于我正在寻找的赏金:
  • 针对上面定义的理论系统的潜在漏洞利用的详细信息
  • 对每次访问时检查指针的可能优化
  • 概念的实验性开源实现(如 Google Native Client)
  • 支持多种操作系统和设备的解决方案(无基于操作系统/硬件的解决方案)
  • 支持最多 C 操作甚至 C++(如果可能)的解决方案

  • 可以与 GCC 一起使用的方法(即预处理器或小型 GCC 补丁)的额外奖励。

    我也会考虑任何能够最终证明我所尝试的事情根本无法完成的人。不过,您需要非常有说服力,因为到目前为止,没有任何反对意见真正说明了他们认为不可能的原因的技术方面。为那些说不的人辩护,这个问题最初是作为安全运行 C++ 的一种方式提出的。我现在已将要求缩减到 C 的有限子集。

    我对 C 的理解可以归类为“中级”,我对 PC 硬件的理解可能比“高级”低一步。如果可以,请尝试针对该级别指导您的答案。由于我不是 C 专家,我将主要基于对答案的投票以及答案与我的要求的接近程度。您可以通过为您的主张(答辩人)和投票(其他所有人)提供足够的证据来提供帮助。一旦赏金倒计时达到 6 小时,我将分配一个答案。

    最后,我相信解决这个问题将是在日益网络化和偏执的世界中保持 C 相关性的重要一步。随着其他语言在性能方面缩小差距和计算能力的增长,越来越难证明 C 开发增加的风险是合理的(就像现在的 ASM)。我相信您的答案将比获得一些 SO 点具有更大的相关性,因此即使赏金已过期,也请尽您所能。

    最佳答案

    由于 C 标准太宽泛而不允许,因此您需要反过来:指定您需要的 C 的最小子集,并尝试实现它。即使是 ANSI C 也已经太复杂了,并且允许出现不需要的行为。

    C 最有问题的方面是指针:C 语言需要指针算术,而这些没有被检查。例如:

    char a[100];
    printf("%p %p\n", a[10], 10[a]);

    都将打印相同的地址。自 a[10] == 10[a] == *(10 + a) == *(a + 10) .

    在编译时无法检查所有这些指针访问。这与要求编译器提供“程序中的所有错误”相同的复杂性,这需要解决停机问题。

    由于您希望此函数能够在同一个进程中运行(可能在不同的线程中),因此您在应用程序和“安全”模块之间共享内存,因为这是拥有线程的全部意义:共享数据以加快访问速度。但是,这也意味着两个线程可以读写相同的内存。

    并且由于您无法证明指针结束的编译时间,因此您必须在运行时执行此操作。这意味着像 'a[10]' 这样的代码必须被翻译成像 'get_byte(a + 10)' 这样的代码,在这一点上我不会再称它为 C 了。

    谷歌原生客户端

    那么如果这是真的,那么谷歌是如何做到的呢?好吧,与这里的要求(跨平台(包括嵌入式系统))相反,Google 专注于 x86,它除了具有页面保护的分页外,还具有分段寄存器。这允许它创建一个沙箱,其中另一个线程不以相同的方式共享相同的内存:沙箱被分段限制为仅更改其自己的内存范围。此外:
  • 组装了安全的 x86 程序集结构列表
  • gcc 更改为发出那些安全构造
  • 此列表是以可验证的方式构建的。
  • 加载模块后,此验证完成

  • 所以这是特定于平台的,虽然是一个可行的解决方案,但它不是一个“简单”的解决方案。在他们的 research paper 阅读更多信息.

    结论

    所以无论你走哪条路,你都需要从一些可验证的新事物开始
    只有这样,您才能开始调整现有的编译器或生成新的编译器。然而,试图模仿 ANSI C 需要考虑指针问题。 Google 的沙箱模型不是基于 ANSI C,而是基于 x86 的一个子集,这允许他们在很大程度上使用现有的编译器,但缺点是绑定(bind)到 x86。

    关于c - 如何创建一个轻量级的 C 代码沙箱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/980170/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com