代码之家  ›  专栏  ›  技术社区  ›  Norman Ramsey

如何限制用“MalCube”获取的内存,而不限制堆栈?

  •  12
  • Norman Ramsey  · 技术社区  · 14 年前

    我正试图阻止学生代码在分配中疯狂运行,并将我的测试机器拖到停顿状态。我试过了

    setrlimit(RLIMIT_DATA, r);
    

    哪里 r 是一个保持极限的结构。但不幸的是,虽然这一限制停止了 brk sbrk 从分配开始,C库就故障转移到 mmap 并继续分配。

    我也试过

    setrlimit(RLIMIT_AS, r)
    

    这就停止了进程,但是这种补救措施太苛刻了。 ENOMEM 错误,因为没有堆栈空间用于代码遇到 NULL 返回的值 malloc() .

    我对二进制文件的控制是有限的,所以如果可以使用系统调用,我更愿意这样做。但我需要一些在不破坏进程恢复能力的情况下限制分配的方法。有人有什么建议吗?

    更新 :我发现了一个叫 failmalloc ,但它不是很复杂,虽然我可以用它造成故障,但我总是得到一个gdb无法诊断的segfault。

    进一步更新 :我发现了 setrlimit(RLIMIT_AS, r) 似乎完成了我想要的工作,至少在某些情况下,之后发生的segfults是由不相关模块中的故障引起的。除非有人提出有趣的事情(或者有理由保留这个问题),否则我可能会删除这个问题。

    2 回复  |  直到 14 年前
        1
  •  5
  •   Community datashaman    7 年前

    建立在 failmalloc ,您可以使用 LD_PRELOAD * 用于构建包装的环境变量和函数插入 malloc() 并施加任何限制。

    您需要动态加载指向原始 马尔洛() 使用 dlsym() . 不能直接调用原件 马尔洛() 因为它将被解释为对包装器本身的递归调用。

    #define _GNU_SOURCE
    #include <stdio.h>
    #include <stdint.h>
    #include <dlfcn.h>
    
    void * malloc(size_t size)
    {
       static void * (*func)(size_t) = NULL;
       void * ret;
    
       if (!func)
       {
          /* get reference to original (libc provided) malloc */
          func = (void *(*)(size_t)) dlsym(RTLD_NEXT, "malloc");
       }
    
       /* impose any necessary restrictions before calling malloc */
       ...
    
       /* call original malloc */
       ret = func(size);
    
       /* impose any necessary restrictions after calling malloc */
       ...
    
       return ret;
    }

    *注意 LD_PRELOAD 必须指定插入器库的完整路径,并且为setuid程序禁用该库插入位置,以防止出现安全问题。


    alternative 使用 dScript() 将使用GNU链接器 --wrap symbol 选项

        2
  •  3
  •   pmg    14 年前

    你能给毫无戒心的学生一个宏吗?-)

    #define malloc(bytes) limited_malloc(bytes)
    

    还有一个定义 limited_malloc 这就限制了我们的工作。