[2060] in bugtraq
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."