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

发布于 2024-09-25 22:22:52 字数 808 浏览 1 评论 0原文

我试图阻止学生代码因分配而疯狂运行并拖累我的测试机器停止运行。我尝试过

setrlimit(RLIMIT_DATA, r);

,其中 r 是一个具有限制的结构。但不幸的是,尽管此限制阻止 brksbrk 进行分配,但 C 库只是故障转移到 mmap 并继续进行分配。

我也尝试过

setrlimit(RLIMIT_AS, r)

,这会阻止进程正常运行,但这种补救措施太严重了——进程不可能从 ENOMEM 错误中恢复,因为没有堆栈空间用于调用代码遇到从 malloc() 返回的 NULL 值。

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

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

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

I'm trying to keep student code from running wild with allocations and dragging my test machine to a halt. I've tried

setrlimit(RLIMIT_DATA, r);

where r is a struct holding the limits. But unfortunately although this limit stops brk and sbrk from allocating, the C library just fails over to mmap and keeps right on allocating.

I've also tried

setrlimit(RLIMIT_AS, r)

and this stops the process in its tracks, but this remedy is too severe—it is impossible for the process to recover from the ENOMEM error because there's no stack space for the calls the code makes on encountering a NULL value returned from malloc().

I have limited controls over the binaries, so if it's possible to do with a system call, I'd prefer that. But I need some means of capping allocation without destroying the process's ability to recover. Does anyone have suggestions?

UPDATE: I found something called failmalloc, but it is not very sophisticated, and although I can cause a failure with it, I always get a segfault that gdb cannot diagnose.

FURTHER UPDATE: I found that setrlimit(RLIMIT_AS, r) does seem to do the job I want, at least in some cases—the segfaults that were occurring afterward were caused by a fault in an unrelated module. Unless somebody comes up with something interesting (or a reason to keep the question), I will probably delete the question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

信仰 2024-10-02 22:22:52

基于 failmalloc 使用的想法,您可以使用 LD_PRELOAD*
环境变量和函数插入,以围绕 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 程序禁用该库插入,以防止出现安全问题。


替代方法 /www.opengroup.org/onlinepubs/009695399/functions/dlsym.html" rel="nofollow noreferrer">dlsym() 将使用 GNU 链接器 --换行符号 选项。

Building on the idea used by failmalloc, you could use the LD_PRELOAD*
environment variable and function interposition to build a wrapper around malloc() and impose any limitations there.

You would need to dynamically load a pointer to the original malloc() using dlsym(). You cannot directly call the original malloc() from the wrapper because it will be interpreted as a recursive call to the wrapper itself.

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

* Note that LD_PRELOAD must specify the full path to the interposer library, and that library interposition is disabled for setuid programs in order to prevent security problems.


An alternative to using dlsym() would be to use the GNU linker --wrap symbol option.

青萝楚歌 2024-10-02 22:22:52

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

#define malloc(bytes) limited_malloc(bytes)

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

Can you force a macro on the unsuspecting students? :-)

#define malloc(bytes) limited_malloc(bytes)

and also a definition for limited_malloc that limits what can be done.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文