如何限制使用“malloc()”获取的内存而不限制堆栈?
我试图阻止学生代码因分配而疯狂运行并拖累我的测试机器停止运行。我尝试过
setrlimit(RLIMIT_DATA, r);
,其中 r
是一个具有限制的结构。但不幸的是,尽管此限制阻止 brk
和 sbrk
进行分配,但 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
基于 failmalloc 使用的想法,您可以使用 LD_PRELOAD*
环境变量和函数插入,以围绕
malloc()
构建包装器并在那里施加任何限制。您需要使用
dlsym()
。您不能直接从包装器调用原始malloc()
,因为它将被解释为对包装器本身的递归调用。* 请注意,
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()
usingdlsym()
. You cannot directly call the originalmalloc()
from the wrapper because it will be interpreted as a recursive call to the wrapper itself.* 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.你能对毫无戒心的学生强行使用宏吗? :-)
以及
limited_malloc
的定义,限制了可以做的事情。Can you force a macro on the unsuspecting students? :-)
and also a definition for
limited_malloc
that limits what can be done.