如何限制使用`malloc()`获取的内存而不限制堆栈?

时间:2010-10-06 00:20:51

标签: c malloc setrlimit

我正在尝试让学生代码不再使用分配,并拖延我的测试机器。我试过了

setrlimit(RLIMIT_DATA, r);

其中r是一个持有限制的结构。但遗憾的是,尽管此限制会使brksbrk停止分配,但C库只会故障转移到mmap并继续分配。

我也试过

setrlimit(RLIMIT_AS, r)

这会使进程停止运行,但是这个补救措施太严重了 - 进程无法从ENOMEM错误中恢复,因为代码在遇到{时所做的调用没有堆栈空间从NULL返回的{1}}值。

我对二进制文件的控制有限,所以如果可以使用系统调用,我宁愿这样做。但我需要一些方法来限制分配,而不会破坏流程的恢复能力。有没有人有建议?

更新:我找到了一个名为failmalloc的东西,但它不是很复杂,虽然我可能会导致它失败,但我总是得到gdb无法诊断的段错误。

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

2 个答案:

答案 0 :(得分:5)

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

您需要使用dlsym()动态加载指向原始malloc()的指针。您无法直接从包装器调用原始malloc(),因为它将被解释为对包装器本身的递归调用。

#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程序禁用该库插入以防止出现安全问题。


使用alternativedlsym()将使用GNU链接器--wrap symbol选项。

答案 1 :(得分:3)

你可以强迫毫无戒心的学生使用宏吗? : - )

#define malloc(bytes) limited_malloc(bytes)

以及limited_malloc的定义,限制了可以做的事情。