Author: pigfoot
9 Sep
前一子上班r, Samuel 跑^:
“咦? 你之前某 Server 的r候, 怎N程式自己a生 Core dump 啊?”
“就是用 setrlimit(2) 的啊!”
“那我看一下樯段艺罩不..”
]想到就_始了酷的~ 我花M了不少工夫才lF樯觞N.
在 Linux 上, AO是不 Core dump 的, 而要程式a生 Core dump 的方法就是利用 bash built-in 的 ulimit 指令. 我去年@篇 How to enlarge Coredump Size and File Descriptor Limitations 好也有到.
不^意外常常有, 所以除了 System administrator O ulimit -c unlimited 之外, 我自己也诔淌窖e面利用 setrlimit(2) @b system call, 程式在绦r, 能虿还 administrator 有]有用 ulimit O定 Core dumpsize, 保C一定a生 Core dump. 在程式 crash 的r候, Core dump 是很重要索啊! 就像 CSI 一, Cf.
可是在看完 Samuel 的程式r, 我和他就X得很奇怪, 是 work 才, 因橥拥 code 的程式已在 production server 上跑了一段rg, 不}才, @r候, 我才猛然想起, 管C器的 administrator 曾f^有r候 Core dump 不霈F. “God! 不褪峭}吧?”
和 Samuel 人找完Y料的答案, 就是@篇文章的C了. 我lF, 如果一程式按照上面的方法都o法a生 Core dump, 那要看看@程式是否是用了 setuid(2) @ System call. 我lF, 一 setuid(2) 或 seteuid(2) ^後的程式, 是]有k法a生 Core dump 的.
好巧不巧, 通常 Server 榱艘恍┌踩缘目剂, 也作 setuid(2) 或 seteuid(2) 磉_到 Running with Least Privilege (相 Windows 的指令就是 Run As). 也就是f, setuid(2) 一定是不能略^的. 解Q方法有煞N.
第一N是只有@程式有效. 用的方法就是 prctl(2). @方法是可以改 source, 然後 rebuild 的r下才能用. Sample code 如下:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#define SU_USER "nobody"
int main(void)
{
struct rlimit corelimit;
struct passwd *pw = NULL;
char *cp = NULL;
/* if switch to nobody failed */
if (NULL == (pw = getpwnam(SU_USER)))
{
fprintf(stderr, "Cannot get uid from user(%s). Error: %s\n",
SU_USER, strerror(errno));
return -1;
}
/* try to switch to nobody */
if ((setuid(pw->pw_uid) < 0) || (seteuid(pw->pw_uid) < 0))
{
fprintf(stderr, "Cannot switch to user(%s). Error: %s\n",
SU_USER, strerror(errno));
return -2;
}
/* force to make coredump */
if (prctl(PR_SET_DUMPABLE, 1) < 0)
{
fprintf(stderr, "Cannot enable core dumping. Error: %s\n",
strerror(errno));
return -3;
}
/* set core size to unlimited */
corelimit.rlim_cur = RLIM_INFINITY;
corelimit.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &corelimit) < 0)
{
fprintf(stderr, "Setrlimit failed! Error: %s\n",
strerror(errno));
return -4;
}
/* force to coredump */
*cp = ‘1′;
return 0;
}
@N方法要注意的事情有:
第二N方法是 system-wide 的, 也就是绊到所有在系y绦械某淌. 方法就是/proc/sys/fs/suid_dumpable. 因檫@和 kernel 的版本有P, man 5 proc 比^保U. @是在o法 source code, 而且原程式]有用 prctl(2) 情r下的⑹昼.
要注意的事情和第一N方法一, 把 /proc/sys/fs/suid_dumpable O成 1 或 2 的差e, 是Q定 core dumpfile 的碛姓. 如果O成 1, 就偷谝环N方法一邮潜 switch 的 owner (本例是 nobody). 如果O 2 就一定是 root, 但是@似乎要 kernel 2.6.13 以上才有 support? 我不是很_定.
希望@篇文章o大家作⒖!
PS: @篇竟然了快二周末, 真是蚓玫~