7

I have a daemon called foo. My init script /etc/init.d/foo starts the foo daemon and stores its pidfile in /var/run/foo.pid, which seems to be the standard place. Because /etc/init.d/foo must be run as root, it has no trouble creating and deleting pidfiles in /var/run.

The foo daemon is really the program /usr/sbin/foo which is intended to be invoked as root by the init script but then immediately drop its privileges to the unprivileged foo user. However, I also want this /usr/sbin/foo program to delete its pidfile when it exits due to a critical error. But since it has already dropped its privileges, it no longer has the ability to delete files from the /var/run directory.

My current approach is to use seteuid instead of setuid to drop my privileges, then re-raise the privileges immediately before exiting so that I can properly delete the pidfile from /var/run. However, I've run into many, many problems with various libraries and external programs which go haywire when invoked with a different euid than uid.

Is there any other way to accomplish this? I suppose the other option is to just put my pidfile in a directory which is writable by both the root and foo users. But all of our other pidfiles are in /var/run, including pidfiles by other programs which run as unprivileged users, so I'd like to put the foo.pid file there as well.

Is there any way to do this other than using seteuid?

3 Answers 3

10

Don't put the PID file in /var/run/foo.pid, put it in /var/run/foo/foo.pid and have /var/run/foo owned by user foo and group foo. That way you can delete the pid file before exiting and you don't have to raise your privilege level.

Note, however, that this is a bad security practice since allowing your unprivileged application mangle with its file will open a security hole: imagine that your application is hijacked (after all what was the point of dropping privileges if not to anticipate that the application can be attacked?) -- now, the attacker updates the pid file and puts, say, sshd's pid number there. Now, when system-wide scripts (running as root) will try to stop your application using that pid file, they will shutdown sshd instead. This is just an example, there are more ways to abuse your system. All in all, the pid file should be created before dropping privileges and cleanup of the pid files should be performed by the system-wide scripts. -- Dmitry D. Khlebnikov

An even better idea would be to switch to an init system like systemd or Upstart that doesn't require PID files to manage services.

2
  • That's a good idea, and I'll do that if I have to, but what are other daemons doing in order to put their pidfiles in /var/run? Are they just using seteuid and not having the problems I am because they're using different programs and libraries? Nov 3, 2010 at 14:16
  • 2
    Either they don't drop privileges or they don't clean up the PID file from within the unprivileged process.
    – jcollie
    Nov 3, 2010 at 14:31
2

You can fork a new process before running your daemon. The parent process remains with privileged user root. The child process drops its privileges to foo user. This process does the real daemon work.

The parent process will create the PID file after forking its child and will remove it when its child terminates.

2

Taking a peek at my Ubuntu system, I see that some installed software has created directories under /var/run owned by a non-root user like jcollie suggests.

Another option is to have the pidfile owned by the non-root user and zero the file instead of deleting it.

1
  • Interesting; I hadn't thought about zeroing it instead of deleting it. However, I guess I shouldn't feel about about creating a sub-directory if some other programs are doing that as well. Nov 3, 2010 at 14:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .