[2060] in bugtraq

home help back first fref pref prev next nref lref last post

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

daemon@ATHENA.MIT.EDU (Cy Schubert - BCSC Open Systems Gr)
Fri Jul 21 14:07:18 1995

Date:         Fri, 21 Jul 1995 09:06:40 -0700
Reply-To: cschuber@uumail.gov.bc.ca
From: Cy Schubert - BCSC Open Systems Group <cschuber@uumail.gov.bc.ca>
X-To:         Zygo Blaxell <zblaxell@miranda.uwaterloo.ca>
To: Multiple recipients of list BUGTRAQ <BUGTRAQ@CRIMELAB.COM>
In-Reply-To:  Your message of "Mon, 17 Jul 95 22:42:58 EDT."
              <199507180242.WAA27383@miranda.uwaterloo.ca>

> [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."

home help back first fref pref prev next nref lref last post