// chroot if (chroot(dir) != 0) { FAIL } if (chdir(dir) != 0) { FAIL } static void privdrop(const uid_t uid, const gid_t gid) { if (geteuid() == 0) { if (setgroups(1, &gid) != 0) { FAIL } } if (setregid(gid, gid) != 0) { FAIL } if (setreuid(uid, uid) != 0) { FAIL } if ((getuid() == 0) || (geteuid() == 0)) { FAIL } if (seteuid(0) != -1) { FAIL } } if (uid == 0) { uid = getuid() }; if (gid == 0) { gid = getgid() }; // forbid ptrace #ifdef __FreeBSD__ int procTraceCtl = PROC_TRACE_CTL_DISABLE; if (procctl(P_PID, (id_t)getpid(), PROC_TRACE_CTL, &procTraceCtl) == -1) { FAIL } #endif // __FreeBSD__ #ifdef __linux__ prctl(PR_SET_NO_NEW_PRIVS, 1); if (prctl(PR_SET_DUMPABLE, 0) != 0) { FAIL } #endif // __linux__ // close unused files if (pid == 0) { close(fileno(stdin)); close(fileno(stdout)); close(pipeR); ... } // prohibit new files/sockets struct rlimit r; if (getrlimit(RLIMIT_NOFILE,&r) == -1) { FAIL } r.rlim_cur = 0; r.rlim_max = 0; if (setrlimit(RLIMIT_NOFILE,&r) == -1) { FAIL } // prohibit fork if (getrlimit(RLIMIT_NPROC,&r) == -1) { FAIL } r.rlim_cur = 0; r.rlim_max = 0; if (setrlimit(RLIMIT_NPROC,&r) == -1) { FAIL }