Hi,

Simon Kelley wrote:

>  dnsmasq (2.63-4) unstable; urgency=low
>  .
>     * Make pid-file creation immune to symlink attacks. (closes: #686484)

How about this patch to fix the same in squeeze?

Thanks,
Jonathan
---
 debian/changelog |  7 +++++++
 src/dnsmasq.c    | 45 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 3955c750..23cfa0da 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+dnsmasq (2.55-2+squeeze0.1) stable; urgency=low
+
+   [ Simon Kelley ]
+   * Make pid-file creation immune to symlink attacks. (closes: #686484)
+
+ -- Jonathan Nieder <jrnie...@gmail.com>  Mon, 22 Oct 2012 00:21:24 -0700
+
 dnsmasq (2.55-2) unstable; urgency=high
   
    * Fix crash on double free. (closes: #597205)
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 727d5e2e..d607e26d 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -327,16 +327,47 @@ int main (int argc, char **argv)
       /* write pidfile _after_ forking ! */
       if (daemon->runfile)
        {
-         FILE *pidfile;
+         int fd, err = 0;
+
+         sprintf(daemon->namebuff, "%d\n", (int) getpid());
+
+         /* Explanation: Some installations of dnsmasq (eg Debian/Ubuntu) 
locate the pid-file
+            in a directory which is writable by the non-privileged user that 
dnsmasq runs as. This
+            allows the daemon to delete the file as part of its shutdown. This 
is a security hole to the
+            extent that an attacker running as the unprivileged  user could 
replace the pidfile with a
+            symlink, and have the target of that symlink overwritten as root 
next time dnsmasq starts.
+
+            The folowing code first deletes any existing file, and then opens 
it with the O_EXCL flag,
+            ensuring that the open() fails should there be any existing file 
(because the unlink() failed,
+            or an attacker exploited the race between unlink() and open()). 
This ensures that no symlink
+            attack can succeed.
+
+            Any compromise of the non-privileged user still theoretically 
allows the pid-file to be
+            replaced whilst dnsmasq is running. The worst that could allow is 
that the usual
+            "shutdown dnsmasq" shell command could be tricked into stopping 
any other process.
+
+            Note that if dnsmasq is started as non-root (eg for testing) it 
silently ignores
+            failure to write the pid-file.
+         */
+
+         unlink(daemon->runfile);
          
-         /* only complain if started as root */
-         if ((pidfile = fopen(daemon->runfile, "w")))
+         if ((fd = open(daemon->runfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 
S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1)
            {
-             fprintf(pidfile, "%d\n", (int) getpid());
-             fclose(pidfile);
+             /* only complain if started as root */
+             if (getuid() == 0)
+               err = 1;
+         else
+           {
+             if (!read_write(fd, (unsigned char *)daemon->namebuff, 
strlen(daemon->namebuff), 0))
+               err = 1;
+
+             while (!err && close(fd) == -1)
+               if (!retry_send())
+                 err = 1;
            }
-         else if (getuid() == 0)
-           {
+
+         if (err)
              send_event(err_pipe[1], EVENT_PIDFILE, errno);
              _exit(0);
            }
-- 
1.8.0


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to