Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dropping root privileges and still generate coredumps

I've noticed that some of my users didn't get a coredump at all after crashing, even when everything else in their configuration seemed correct.

After reading the core(5) man page a bunch of times I noticed this particular point:

[A core dump file is not produced if] The process is executing a set-user-ID (set-group-ID) program that is owned by a user (group) other than the real user (group) ID of the process.

My daemon isn't setuid root, but in a lot of configurations it's started as root, and if the .conf file specifies a username, it drops privileges, with the usual combination:

setgid(gid);
setuid(uid);

When it does this, coredumps are not generated anymore. Everything else in the environment seems to be correct, removing those calls (and staying as root) gets me coredumps as usual.

I tried to change the "real" uid/gid as the man page seemed to suggest, by calling the less-portable setresgid/uid which seem to be suggested often to drop privileges permanently:

setresgid(gid, gid, gid);
setresuid(uid, uid, uid);

I expected that to solve the problem but... it didn't improve at all. Still no coredumps.

Sooo... now what?


Test code:

#include <stdlib.h>

int main(int argc, char **argv) {
        if (argc > 1) {
                setgid(atoi(argv[2]));
                setuid(atoi(argv[1]));
        }
        abort();
}

Usage:

  • ./a.out as any user to just abort without setgid/setuid
  • ./a.out 1000 100 (where 1000 is uid and 100 is gid) as root to drop privileges and watch coredumps not happen.
  • Bonus unintentional feature: pass one parameter, not two, to get SIGSEGV instead of SIGABRT.

I've already tested this in arch linux, centos 6.5 and openbsd 5.3

like image 216
dequis Avatar asked Apr 16 '15 06:04

dequis


People also ask

What causes Coredump?

Core dumps are generated when the process receives certain signals, such as SIGSEGV, which the kernels sends it when it accesses memory outside its address space. Typically that happens because of errors in how pointers are used. That means there's a bug in the program. The core dump is useful for finding the bug.

Where is the Coredump file?

By default, all core dumps are stored in /var/lib/systemd/coredump (due to Storage=external ) and they are compressed with zstd (due to Compress=yes ). Additionally, various size limits for the storage can be configured. Note: The default value for kernel.

What is Systemd Coredump?

systemd-coredump@. service is a system service to process core dumps. It will log a summary of the event to systemd-journald. service(8), including information about the process identifier, owner, the signal that killed the process, and the stack trace if possible. It may also save the core dump for later processing.


2 Answers

To force a process to always core dump use the prctl system call.

prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
like image 164
clockley1 Avatar answered Oct 03 '22 14:10

clockley1


You have to enable core dumps for applications that have their privileges changed:

echo 2 > /proc/sys/fs/suid_dumpable

I advice you to put that in /etc/rc.local.


For example, here's what I have there:

# This is to enable debugging as a normal user, rather than root
sysctl kernel.yama.ptrace_scope=0

# This is a convenient core file pattern 
# '%e' is the name of the process
# '%p' is the pid of process
sysctl kernel.core_pattern="/tmp/core.%e.%p"

# Enable dump for processes with lowered privileges
echo 2 > /proc/sys/fs/suid_dumpable

# Remove limit for the size of core files
ulimit -c unlimited

Edit:

You can take a look at this neat library, that allows you to manually write core dumps to a custom file : https://code.google.com/p/google-coredumper/

I believe it's exactly what you need.

like image 24
GreenScape Avatar answered Oct 03 '22 15:10

GreenScape