From: solar@openwall.com To: zenith parsec <zenith_parsec@the-astronaut.com> Subject: Re: RH7.0: man local gid 15 (man) exploit Date: Tue, 15 May 2001 05:00:28 +0400 Cc: bugtraq@securityfocus.com On Sun, May 13, 2001 at 08:07:34PM -0000, zenith parsec wrote: > man -S `perl -e 'print ":" x 100'` > > Will cause a seg fault if you are vulnerable. This and several other man vulnerabilities have been discussed on security-audit last year. See: MARC: thrd 'Multiple man vulnerabilities with Red Hat Linux 6.2' http://marc.theaimsgroup.com/?t=97096128600001&w=2&r=1 MARC: thrd 'More fun with man 1.5h1' http://marc.theaimsgroup.com/?t=97135295400001&w=2&r=1 I don't think your analysis of the possibilities to exploit this is entirely correct. The buffer is in the bss, not on the heap. In fact, the builds of man-1.5h1 I have here won't even segfault on the command you mention, not even when given 400 colons -- but they do misbehave in other ways. (I am willing to believe that this really is exploitable on the RH 7.0 build, which I don't have.) Of course, this is just one reason why SGID man is bad. > GID man allows a race condition for root via > /etc/cron.daily/makewhatis and /sbin/makwhatis Yes, due to their security fix. I haven't seen this mentioned before (but I'm not using this broken fix, anyway). -TMPFILE=$HOME/whatis$$ -TMPFILEDIR=/tmp/whatis$$ +TMPFILE=/var/cache/man/whatis$$ +TMPFILEDIR=/var/cache/man/whatis$$ where /var/cache/man is writable by group man. :-( The makewhatis patch we have in Owl (http://www.openwall.com/Owl/) is attached. The section list overflow bug you mention isn't a security problem on Owl for obvious reasons, but is on my TODO for fixing (has been there since the security-audit discussion). -- /sd diff -ur man-1.5h1.orig/src/makewhatis.sh man-1.5h1/src/makewhatis.sh --- man-1.5h1.orig/src/makewhatis.sh Tue Jun 29 06:20:59 1999 +++ man-1.5h1/src/makewhatis.sh Thu Aug 10 02:56:57 2000 @@ -3,6 +3,7 @@ # Created: Sun Jun 14 10:49:37 1992 # Revised: Sat Jan 8 14:12:37 1994 by faith@cs.unc.edu # Revised: Sat Mar 23 17:56:18 1996 by micheal@actrix.gen.nz +# Revised: Thu Aug 10 02:17:50 2000 by solar@owl.openwall.com # Copyright 1992, 1993, 1994 Rickard E. Faith (faith@cs.unc.edu) # May be freely distributed and modified as long as copyright is retained. # @@ -24,6 +25,7 @@ # 960510 - added fixes by brennan@raven.ca.boeing.com, author of mawk. # 971012 - replaced "test -z" - it doesnt work on SunOS 4.1.3_U1. # 980710 - be more careful with TMPFILE +# 000810 - solar: use mktemp, keep whatis files consistent while running. # # Note for Slackware users: "makewhatis -v -w -c" will work. # @@ -39,23 +41,7 @@ # AWK=/usr/bin/gawk AWK=%gawk% -# Find a place for our temporary files. If security is not a concern, use -# TMPFILE=/tmp/whatis$$; TMPFILEDIR=none -# Of course makewhatis should only have the required permissions -# (for reading and writing directories like /usr/man). -# We try here to be careful (and avoid preconstructed symlinks) -# in case makewhatis is run as root, by creating a subdirectory of /tmp. -# If that fails we use $HOME. -# The code below uses test -O which doesnt work on all systems. -TMPFILE=$HOME/whatis$$ -TMPFILEDIR=/tmp/whatis$$ -if [ ! -d $TMPFILEDIR ]; then - mkdir $TMPFILEDIR - chmod 0700 $TMPFILEDIR - if [ -O $TMPFILEDIR ]; then - TMPFILE=$TMPFILEDIR/w - fi -fi +TMPFILE=`mktemp /tmp/$program.XXXXXX` || exit 1 topath=manpath @@ -74,6 +60,7 @@ case $name in --version|-V) echo "$program from %version%" + rm $TMPFILE exit 0;; -c) topath=catpath defmanpath= @@ -97,12 +84,14 @@ echo " [manpath]: man directories (default: $DEFMANPATH)" echo " [catpath]: cat directories (default: the first existing" echo " directory in $DEFCATPATH)" + rm $TMPFILE exit;; *) if [ -d $name ] then eval $topath="\$$topath":$name else echo "No such directory $name" + rm $TMPFILE exit fi;; esac @@ -117,7 +106,7 @@ fi catpath=`echo ${catpath} | tr : ' '` -# first truncate all the whatis files that will be created new, +# first mark all the whatis files that will be created new, # then only update - we might visit the same directory twice if [ x$update = x ]; then for pages in man cat @@ -125,7 +114,7 @@ eval path="\$$pages"path for mandir in $path do - cp /dev/null $mandir/whatis + touch $mandir/whatis.update done done fi @@ -139,7 +128,7 @@ if [ x$verbose != x ]; then echo "about to enter $mandir" > /dev/tty fi - if [ -s ${mandir}/whatis -a $pages = man -a x$update = x ]; then + if [ ! -f ${mandir}/whatis.update -a $pages = man -a x$update = x ]; then if [ x$verbose != x ]; then echo skipping $mandir - we did it already > /dev/tty fi @@ -338,15 +327,12 @@ then cat ${mandir1}/whatis >> $TMPFILE fi - sed '/^$/d' < $TMPFILE | sort | uniq > ${mandir1}/whatis + touch ${mandir1}/whatis.tmp + chmod 644 ${mandir1}/whatis.tmp + sed '/^$/d' < $TMPFILE | sort -u > ${mandir1}/whatis.tmp - chmod 644 ${mandir1}/whatis - rm $TMPFILE + mv -f ${mandir1}/whatis.tmp ${mandir1}/whatis + rm $TMPFILE ${mandir1}/whatis.update fi done done - -# remove the dir if we created it -if [ $TMPFILE = $TMPFILEDIR/w ]; then - rmdir $TMPFILEDIR -fi