gpt4 book ai didi

c - 从包装器中锁定程序

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:48:58 25 4
gpt4 key购买 nike

只是一个简短的问题(我希望如此)。您将如何通过 mlock 分配地址空间,然后在该空间内启动应用程序?

例如,我有一个从配置环境的包装程序启动的二进制文件。我只能访问包装器代码,并希望在某个地址空间中启动二进制文件。是否可以从包装器中执行此操作?

谢谢!

最佳答案

如果您有该程序的源代码,请添加一个命令行选项,以便该程序在某个时候调用 mlockall(MCL_CURRENT | MCL_FUTURE)。这会将它锁定在内存中。

如果你想控制内核加载程序的地址空间,你需要深入研究内核内部。很可能没有理由这样做;只有拥有真正时髦硬件的人才会。

如果您没有源码,或者不想重新编译程序,那么您可以创建一个执行命令的动态库,并通过LD_PRELOAD 将其注入(inject)到进程中。

将以下内容保存为 lockall.c:

#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>

static void wrerr(const char *p)
{
if (p) {
const char *q = p + strlen(p);
ssize_t n;

while (p < q) {
n = write(STDERR_FILENO, p, (size_t)(q - p));
if (n > 0)
p += n;
else
if (n != -1 || errno != EINTR)
return;
}
}
}

static void init(void) __attribute__((constructor));
static void init(void)
{
int saved_errno = errno;

if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
const char *errmsg = strerror(errno);
wrerr("Cannot lock all memory: ");
wrerr(errmsg);
wrerr(".\n");
exit(127);
} else
wrerr("All memory locked.\n");

errno = saved_errno;
}

编译成动态库liblockall.so使用

gcc -Wall -O2 -fPIC -shared lockall.c -Wl,-soname,liblockall.so -o liblockall.so

例如将库安装在典型的地方

sudo install -o 0 -g 0 -m 0664 liblockall.so /usr/lib/

因此您可以运行任何二进制文件,并将其锁定到内存中,使用

LD_PRELOAD=liblockall.so binary arguments..

如果您将库安装在其他地方(未在 /etc/ld.so.conf 中列出),则需要指定库的路径,例如

LD_PRELOAD=/usr/lib/liblockall.so binary arguments..

通常,当以普通用户身份运行命令时,您会看到消息 无法锁定所有内存:无法分配内存。 由插入的库打印。 ( super 用户或 root 通常没有这样的限制。)这是因为显而易见的原因,大多数 Linux 发行版都限制了非特权用户可以锁定到内存中的内存量;这是 RLIMIT_MEMLOCK resource limit 。运行 ulimit -l 查看当前设置的每个进程的资源限制(显然是针对当前用户)。

我建议您为进程可以运行多少内存设置一个合适的限制,例如运行ulimit -l 16384 bash 内置在执行之前(将限制设置为 16384*1024 字节,或 16 MiB),如果以 super 用户 (root) 身份运行。如果进程泄漏内存,而不是让你的机器崩溃(因为它锁定了所有可用内存),如果它超过限制,进程就会死掉(来自 SIGSEGV)。也就是说,您将使用

ulimit -l 16384
LD_PRELOAD=/usr/lib/liblockall.so binary arguments..

如果使用 Bash 或 dash shell。

如果以专用用户身份运行,大多数发行版使用 pam_limits.so PAM 模块“自动”设置资源限制。限制列在 /etc/security/limits.conf 文件中,或列在 /etc/security/limits.d/ 子目录中的文件中,使用 this format ; memlock 项指定每个进程可以锁定的内存量,以 1024 字节为单位。因此,如果您的服务以用户 mydev 身份运行,并且您希望允许用户锁定每个进程最多 16 兆字节 = 16384*1024 字节,则添加行 mydev - memlock 16384/etc/security/limits.conf/etc/security/limits.d/mydev.conf,以您的 Linux 发行版偏好/建议为准。

在 PAM 之前,shadow-utils 用于控制资源限制。 memlock资源限制以1024字节为单位指定;将使用 M16384 设置 16 兆字节的限制。因此,如果使用 shadow-utils 而不是 PAM,将 mydev M16384 行(后跟您希望指定的任何其他限制)添加到 /etc/limits 应该可以解决问题.

关于c - 从包装器中锁定程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37818335/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com