12

我试图阻止学生代码在分配中乱跑并将我的测试机器拖到停止状态。我试过了

setrlimit(RLIMIT_DATA, r);

r保持限制的结构在哪里。但不幸的是,尽管这个限制停止brk并停止sbrk分配,C 库只是故障转移到mmap并继续分配。

我也试过

setrlimit(RLIMIT_AS, r)

这会使进程停止在其轨道上,但是这种补救措施太严重了——进程不可能从ENOMEM错误中恢复,因为没有堆栈空间用于代码在遇到NULL从返回的值时进行的调用malloc()

我对二进制文件的控制有限,所以如果可以使用系统调用,我会更喜欢。但我需要一些限制分配的方法,而不会破坏进程的恢复能力。有人有建议吗?

更新:我发现了一个叫做failmalloc的东西,但它不是很复杂,虽然我可以用它导致失败,但我总是得到一个 gdb 无法诊断的段错误。

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

4

2 回答 2

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;
}

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


使用的替代方法dlsym()是使用 GNU 链接器--wrap symbol选项。

于 2010-10-06T04:24:15.553 回答
3

你能对毫无戒心的学生强加一个宏吗?:-)

#define malloc(bytes) limited_malloc(bytes)

还有一个定义limited_malloc限制了可以做的事情。

于 2010-10-06T01:36:09.023 回答