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

Nor*_*sey 12 c malloc setrlimit

我试图阻止学生代码在分配中运行,并拖延我的测试机器.我试过了

setrlimit(RLIMIT_DATA, r);
Run Code Online (Sandbox Code Playgroud)

哪个r是持有限制的结构.但不幸的是,虽然这个限制停止brk并且sbrk分配,但是C库只是故障转移mmap并保持正确分配.

我也试过了

setrlimit(RLIMIT_AS, r)
Run Code Online (Sandbox Code Playgroud)

并且这会使进程停止,但是这种补救措施太严重了 - 进程无法从ENOMEM错误中恢复,因为代码在遇到NULL返回的值时所进行的调用没有堆栈空间malloc().

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

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

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

jsc*_*ier 5

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

您将需要动态加载的指针到原来的malloc()使用dlsym().您不能直接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;
}
Run Code Online (Sandbox Code Playgroud)

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


一种替代使用dlsym()是使用GNU链接--wrap symbol选项.


pmg*_*pmg 3

你能对毫无戒心的学生强行使用宏吗?:-)

#define malloc(bytes) limited_malloc(bytes)
Run Code Online (Sandbox Code Playgroud)

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