[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

start-stop-daemon: pid_is_exec may fails to achieve its goal.


While looking at start-stop-daemon source to help solving #151996 and
#151992, I noticed this piece of code :

static int
pid_is_exec(pid_t pid, const struct stat *esb)
        struct stat sb;
        char buf[32];

        sprintf(buf, "/proc/%d/exe", pid);
        if (stat(buf, &sb) != 0)
                return 0;
        return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino);

I guess this is meant to check that the process whose PID is found in
/var/run/foo.pid is actually a process executing the daemon started with
the foo command (with something like '--startas /usr/bin/foo').

Not to mention the fact that the test will fail achieving its goal for
daemons which exec() an other program (eg. java|python|perl daemon, or a
daemon started with a shell script), I can also see a case where the test
will fail, even for a more standard program.


- let foo by a very simple daemon (no interpreter, just daemonize)
- start-stop-daemon --start --startas /usr/bin/foo --pid-file /var/run/foo.pid
- then for some reason (mount partition over /usr/bin, replace /usr/bin/foo
using mv, etc.) the (inode,dev) of /usr/bin/foo gets changed.
- then start-stop-daemon --stop --startas /usr/bin/foo --pid-file
/var/run/foo.pid won't stop foo, because it will conclude that the process
which PID is in /var/run/foo.pid is not running foo
This inode change can happen very easily if the package is removed and then
reinstalled ; perhaps even when it is upgraded (I didn't check dpkg
internals to see if it uses cp-like overwrite of files, or mv-like).

Perhaps comparing path instead of inodes would be better.
Maybe symlinks would be problematic (?).



PS: Please Cc: me, I'm not subscribed to debian-dpkg.

To UNSUBSCRIBE, email to debian-dpkg-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org

Reply to: