【发布时间】:2015-06-22 10:02:27
【问题描述】:
我注意到我的一些用户在崩溃后根本没有得到核心转储,即使他们的配置中的其他所有内容似乎都正确。
在多次阅读core(5) 手册页后,我注意到了这一点:
[如果不生成核心转储文件] 进程正在执行一个由用户(组)拥有的 set-user-ID (set-group-ID) 程序,而不是进程的真实用户(组)ID。
我的守护进程不是 setuid root,但在很多配置中它是以 root 身份启动的,如果 .conf 文件指定了用户名,它会放弃特权,使用通常的组合:
setgid(gid);
setuid(uid);
执行此操作时,不再生成核心转储。环境中的其他一切似乎都是正确的,删除这些调用(并保持 root 身份)让我像往常一样获得核心转储。
我试图更改“真正的”uid/gid,正如手册页所暗示的那样,通过调用似乎经常被建议永久放弃特权的不太便携的 setresgid/uid:
setresgid(gid, gid, gid);
setresuid(uid, uid, uid);
我希望这能解决问题,但是......它根本没有改善。仍然没有核心转储。
太好了……现在呢?
测试代码:
#include <stdlib.h>
int main(int argc, char **argv) {
if (argc > 1) {
setgid(atoi(argv[2]));
setuid(atoi(argv[1]));
}
abort();
}
用法:
-
./a.out任何用户都可以在没有 setgid/setuid 的情况下中止 -
./a.out 1000 100(其中 1000 是 uid,100 是 gid)以 root 身份删除权限并观察不会发生核心转储。 - 额外的无意功能:传递一个参数,而不是两个参数,以获取 SIGSEGV 而不是 SIGABRT。
我已经在 arch linux、centos 6.5 和 openbsd 5.3 中测试过这个
【问题讨论】:
-
并且非特权用户/组没有禁用核心转储(
ulimit -c不报告0)? -
是的,双方无限制。在没有 setuid/gid 调用的情况下以 uid(0 和 1000)的形式运行它会导致核心转储。
-
你真的必须对这类东西更具体,Linux 发行版在这里做不同的事情。特别是,那里有 PAM 模块,记住 ubuntu,它们与生成核心转储交互。
-
我已经在 arch linux、centos 6.5 和 openbsd 中重现了这种行为(这是我在 vagrant 中所拥有的)。将我的测试代码添加到问题中