我知道如何使用setrlimit()和getrlimit()系统调用。我试图对儿童过程施加一些限制。首先,我要求孩子,然后我在孩子中设置了各种限制,之后我使用exec调用替换真实孩子的过程图像(限制存活exec调用)。我有几个问题:
1.限制内存使用 - 目前我并不清楚我应该使用哪个标志。 RLIMIT_DATA是控制sbrk()和brk()调用的一个,但是我发现glibc malloc实现使用的是用RLIMIT_AS标志控制的mmap()。因此,如果我想将内存使用量限制为16MB,我应该致电:
struct rlimit mlimit;
mlimit.rlim_cur = 1 << 23;
mlimit.rlim_max = mlimit.rlim_cur;
::setrlimit(RLIMIT_DATA, &mlimit);
::setrlimit(RLIMIT_AS, &mlimit);
或者我应该只使用一个选项?
2.限制打开文件描述符的数量 - 如果我想阻止子进程打开任何其他文件描述符,除了 stdin , stdout 和< i> stderr 我应该将RLIMIT_NOFILE设置为4(比手册页中指定的最大文件描述符号大1)?
3.限制文件写入的总量 - 有一个RLIMIT_FSIZE标志,并在手册页中声明该标志具有下一个语义:
进程可能创建的文件的最大大小。尝试将文件扩展超出此限制会导致传送SIGXFSZ信号。
如果我理解正确,则此标志对单个文件的最大大小施加限制 - 而不是由进程写入的所有文件的累积大小。因此,问题是我是否应该将此标志与RLIMIT_NOFILE结合使用以限制可以将多少数据写入磁盘,或者有更好的方法来执行此操作?
4.防止孩子改变这个限制 - 不受信任的代码将用exec调用执行,所以我想知道这个子进程是否有办法覆盖fork()之后但在exec调用之前设置的限制?如果可以做到,我该如何预防呢?我已经阅读了一些关于功能和CAP_SYS_RESOURCE的内容,但我不清楚如何正确地完成它。
答案 0 :(得分:0)
这些限制并不准确,使用它们会导致很多问题。值得注意的是:
当你使用RLIMIT_AS
时,你限制了可以加载到进程的共享库 - 如果你更新了Glibc,那么新的Glibc可能会超出限制并且你的程序会不再运行
对于文件描述符 - 进程总是可以关闭标准流描述符以打开更多,但是如果提供的太少,动态链接器将无法为您链接C库。
< / LI>正如您所知,RLIMIT_FSIZE
将是每个文件。
setrlimit
文档说非特权进程只能降低硬限制,而不是增加硬限制,因此当您设置硬限制时,该进程或其子进程无法增加它,除非它们具有{{1默认情况下,没有非root进程。