[18323] in bugtraq

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

Re: Solaris patchadd(1) (3) symlink vulnerabilty

daemon@ATHENA.MIT.EDU (Darren Moffat)
Fri Dec 22 14:54:32 2000

Mime-Version: 1.0
Content-Type: MULTIPART/mixed; BOUNDARY=Drey_of_Squirrels_554_000
Message-Id:  <200012221726.eBMHQGO515697@jurassic.eng.sun.com>
Date:         Fri, 22 Dec 2000 09:26:16 -0800
Reply-To: Darren Moffat <Darren.Moffat@eng.sun.com>
From: Darren Moffat <Darren.Moffat@ENG.SUN.COM>
To: BUGTRAQ@SECURITYFOCUS.COM

--Drey_of_Squirrels_554_000
Content-Type: TEXT/plain; charset=us-ascii
Content-MD5: 0KSpqLSeUAEgus/c7ygCBQ==

Since patchadd is a script the bug it pretty easy to fix, Sun does intend
to release patches but it would have helped if we had been given notification
of the bug first, I don't believe we were.

So here is a set of diffs to patchadd for those that really can't wait.

Please note these are my personal diffs they do not reflect the official
opinion of those in Sun responsible for the patchadd command and may not
reflect the fix that is eventually released.  Do NOT under any circumstances
log any support calls with Sun regarding these diffs, they are intended
only to show the true nature of the fix and to illustrate to those concerned
how it could be fixed.  If you decide to apply these diffs to your production
servers it is enterly your risk.

==============================================================================

    The contents of the attached document are intended to be read as an
    example.
    This is not a supported product of Sun Microsystems and no hotline
    calls will be accepted which directly relate to this information.

    NO LIABILITY WILL BE ACCEPTED BY SUN MICROSYSTEMS FOR ANY LOSS (DIRECT
    OR CONSEQUENTIAL) INCURRED IN ANY WAY BY ANY PARTY THROUGH THE USE OF
    THIS INFORMATION.

    NO WARRANTY OF ANY SORT IS IMPLIED OR GIVEN FOR ANY CODE DERIVED FROM
    THIS INFORMATION.

==============================================================================


--Drey_of_Squirrels_554_000
Content-Type: TEXT/plain; name="patchadd.diff"; charset=us-ascii; x-unix-mode=0644
Content-Description: patchadd.diff
Content-MD5: TcCLRwbzVniqYRasqfidAw==

*** patchadd.orig	Wed Dec 20 11:21:38 2000
--- patchadd	Wed Dec 20 11:21:42 2000
***************
*** 161,182 ****
  function set_globals
  {

! 	EXISTFILES=/tmp/existfiles.$$
! 	PATCHFILES=/tmp/patchfiles.$$
! 	PKGCOFILE=/tmp/pkgchk.out.$$
! 	VALERRFILE=/tmp/valerr.$$
! 	VALWARNFILE=/tmp/valwarn.$$
! 	ADMINTFILE=/tmp/admin.tmp.$$
! 	ADMINFILE=/tmp/admin.$$
! 	LOGFILE=/tmp/pkgaddlog.$$
! 	TMP_ARCHIVE=/tmp/TmpArchive.$$
! 	TMP_FILELIST=/tmp/FileList.$$
! 	TMP_LIB_DIR=/tmp/TmpLibDir.$$
! 	INSTPATCHES_FILE=/tmp/MyShowrevFile.$$
! 	PARAMS_FILE=/tmp/ParamsFile.$$
! 	RESPONSE_FILE=/tmp/response.$$
! 	TEMP_REMOTE=/tmp/temp_remote.$$

  	Obsoletes=
  	Incompat=
  	Requires=
--- 161,192 ----
  function set_globals
  {

! 	if [ -z "$WORKDIR" ]; then
! 		safedir=${TMPDIR:-/tmp}/patchadd${RANDOM}$$
! 		mkdir -m 700 $safedir
! 		if [ $? != 0 ]; then
! 			exit 1;
! 		fi
! 		WORKDIR=$safedir
! 		unset safedir
! 	fi

+ 	EXISTFILES=${WORKDIR}/existfiles.$$
+ 	PATCHFILES=${WORKDIR}/patchfiles.$$
+ 	PKGCOFILE=${WORKDIR}/pkgchk.out.$$
+ 	VALERRFILE=${WORKDIR}/valerr.$$
+ 	VALWARNFILE=${WORKDIR}/valwarn.$$
+ 	ADMINTFILE=${WORKDIR}/admin.tmp.$$
+ 	ADMINFILE=${WORKDIR}/admin.$$
+ 	LOGFILE=${WORKDIR}/pkgaddlog.$$
+ 	TMP_ARCHIVE=${WORKDIR}/TmpArchive.$$
+ 	TMP_FILELIST=${WORKDIR}/FileList.$$
+ 	TMP_LIB_DIR=${WORKDIR}/TmpLibDir.$$
+ 	INSTPATCHES_FILE=${WORKDIR}/MyShowrevFile.$$
+ 	PARAMS_FILE=${WORKDIR}/ParamsFile.$$
+ 	RESPONSE_FILE=${WORKDIR}/response.$$
+ 	TEMP_REMOTE=${WORKDIR}/temp_remote.$$
+
  	Obsoletes=
  	Incompat=
  	Requires=
***************
*** 305,314 ****
  	fi

  	$RM -f $INSTPATCHES_FILE
- 	$RM -f /tmp/*.$$.1
- 	$RM -f /tmp/archive.cpio*
- 	$RM -fr /tmp/*.$$
  	$RM -f $patchFileStripped
  }

  #
--- 315,322 ----
  	fi

  	$RM -f $INSTPATCHES_FILE
  	$RM -f $patchFileStripped
+ 	$RM -rf ${WORKDIR}
  }

  #
***************
*** 435,441 ****
  			/usr/bin/gettext "The postpatch script exited with return code $retcode.\n"
  			if [[ "$isapplied" = "no" ]]
  			then
! 				$CP $1/$2/log /tmp/log.$2
  				/usr/bin/gettext "Backing out patch:\n"
  				cd $3
  				if [[ "$ROOTDIR" != "/" ]]
--- 443,449 ----
  			/usr/bin/gettext "The postpatch script exited with return code $retcode.\n"
  			if [[ "$isapplied" = "no" ]]
  			then
! 				$CP $1/$2/log ${WORKDIR}/log.$2
  				/usr/bin/gettext "Backing out patch:\n"
  				cd $3
  				if [[ "$ROOTDIR" != "/" ]]
***************
*** 444,450 ****
  				else
  					/usr/sbin/patchrm $2
  				fi
! 				/usr/bin/gettext "See /tmp/log.$2 for more details.\n"
  			else
  				/usr/bin/gettext "Not backing out patch because this is a re-installation.\nThe system may be in an unstable state!\nSee $1/$2/log for more details.\n"  |tee -a $1/$2/log
  			fi
--- 452,458 ----
  				else
  					/usr/sbin/patchrm $2
  				fi
! 				/usr/bin/gettext "See ${WORKDIR}/log.$2 for more details.\n"
  			else
  				/usr/bin/gettext "Not backing out patch because this is a re-installation.\nThe system may be in an unstable state!\nSee $1/$2/log for more details.\n"  |tee -a $1/$2/log
  			fi
***************
*** 1527,1533 ****
  #
  function check_for_symbolic_link
  {
! 	$RM -f /tmp/symlink.$$ > /dev/null 2>&1
  	olddir=$(pwd)
  	cd $patchdir
  	for ii in * X
--- 1535,1541 ----
  #
  function check_for_symbolic_link
  {
! 	$RM -f ${WORKDIR}/symlink.$$ > /dev/null 2>&1
  	olddir=$(pwd)
  	cd $patchdir
  	for ii in * X
***************
*** 1551,1562 ****
  		symlinks=
  		symlinks=$($SED -n '/^[^ 	]*[ 	]*s[ 	]/p' $1/$2/$ii/pkgmap)
  		if [[ "$symlinks" != "" ]]; then
! 			/usr/bin/gettext "Symbolic link in package $ii.\n" >> /tmp/symlink.$$
  		fi
  	done
! 	if [[ -s /tmp/symlink.$$ ]]
  	then
! 		cat /tmp/symlink.$$
  		/usr/bin/gettext "Symbolic links cannot be part of a patch.\n"
  		patch_quit 13 "no"
  		return 0
--- 1559,1570 ----
  		symlinks=
  		symlinks=$($SED -n '/^[^ 	]*[ 	]*s[ 	]/p' $1/$2/$ii/pkgmap)
  		if [[ "$symlinks" != "" ]]; then
! 			/usr/bin/gettext "Symbolic link in package $ii.\n" >> ${WORKDIR}/symlink.$$
  		fi
  	done
! 	if [[ -s ${WORKDIR}/symlink.$$ ]]
  	then
! 		cat ${WORKDIR}/symlink.$$
  		/usr/bin/gettext "Symbolic links cannot be part of a patch.\n"
  		patch_quit 13 "no"
  		return 0
***************
*** 1840,1848 ****
  		return
  	fi

! 	pkgfiles=/tmp/pkgfiles.$$
! 	resfiles=/tmp/resolvedfiles.$$
! 	macrofiles=/tmp/pkgmacros.$$
  	pkginst=
  	pkginfofile=
  	patchpkg=
--- 1848,1856 ----
  		return
  	fi

! 	pkgfiles=${WORKDIR}/pkgfiles.$$
! 	resfiles=${WORKDIR}/resolvedfiles.$$
! 	macrofiles=${WORKDIR}/pkgmacros.$$
  	pkginst=
  	pkginfofile=
  	patchpkg=
***************
*** 2343,2350 ****
  			/usr/bin/gettext "Pkgadd of $i package failed with error code $pkgadderr.\n" |tee -a $1/$2/log
  			if [ "$isapplied" = "no" ]
  			then
! 				/usr/bin/gettext "See /tmp/log.$2 for reason for failure.\n"
! 				$CP $1/$2/log /tmp/log.$2
  				/usr/bin/gettext "Backing out patch:\n"
  				cd $3
  				if [ "$ROOTDIR" != "/" ]
--- 2351,2358 ----
  			/usr/bin/gettext "Pkgadd of $i package failed with error code $pkgadderr.\n" |tee -a $1/$2/log
  			if [ "$isapplied" = "no" ]
  			then
! 				/usr/bin/gettext "See ${WORKDIR}/log.$2 for reason for failure.\n"
! 				$CP $1/$2/log ${WORKDIR}/log.$2
  				/usr/bin/gettext "Backing out patch:\n"
  				cd $3
  				if [ "$ROOTDIR" != "/" ]
***************
*** 2988,2998 ****
  			$FIND . -print > $TMP_FILELIST

  			cd $ROOTDIR
! 			cpio -oL -O /tmp/archive.cpio < $EXISTFILES >/dev/null 2>&1
  			exit_code=$?

  			cd $TMP_ARCHIVE
! 			cpio -oAL -O /tmp/archive.cpio < $TMP_FILELIST >/dev/null 2>&1
  			exit_code=exit_code+$?

  			cd $ROOTDIR
--- 2996,3006 ----
  			$FIND . -print > $TMP_FILELIST

  			cd $ROOTDIR
! 			cpio -oL -O ${WORKDIR}/archive.cpio < $EXISTFILES >/dev/null 2>&1
  			exit_code=$?

  			cd $TMP_ARCHIVE
! 			cpio -oAL -O ${WORKDIR}/archive.cpio < $TMP_FILELIST >/dev/null 2>&1
  			exit_code=exit_code+$?

  			cd $ROOTDIR
***************
*** 3022,3028 ****
  			then
  				compress $archive_path/archive.cpio
  			else
! 				compress /tmp/archive.cpio
  			fi
  			if [ $? = 0 ]
  			then
--- 3030,3036 ----
  			then
  				compress $archive_path/archive.cpio
  			else
! 				compress ${WORKDIR}/archive.cpio
  			fi
  			if [ $? = 0 ]
  			then
***************
*** 3035,3041 ****
  		fi
  		if [ "$isapplied" = "yes" ]
  		then
! 			$CP /tmp/archive.cpio* $1/$2/save
  		fi
  		chmod 600 $archive_path/archive.cpio*
  		$TOUCH $1/$2/.oldfilessaved
--- 3043,3049 ----
  		fi
  		if [ "$isapplied" = "yes" ]
  		then
! 			$CP ${WORKDIR}/archive.cpio* $1/$2/save
  		fi
  		chmod 600 $archive_path/archive.cpio*
  		$TOUCH $1/$2/.oldfilessaved
***************
*** 3057,3063 ****
  	then
  		$MD -m 750 -p $1/$2
  	fi
! 	$MV -f /tmp/ACTION.$PatchNum $1/$2 >/dev/null 2>&1
  	$CP -p README.$2 $1/$2 >/dev/null 2>&1
  	
  	# Note the following line should be removed for 2.7.
--- 3065,3071 ----
  	then
  		$MD -m 750 -p $1/$2
  	fi
! 	$MV -f ${WORKDIR}/ACTION.$PatchNum $1/$2 >/dev/null 2>&1
  	$CP -p README.$2 $1/$2 >/dev/null 2>&1
  	
  	# Note the following line should be removed for 2.7.
***************
*** 3092,3102 ****
  	else
  		if [[ "$PATCH_UNDO_ARCHIVE" != "none" ]]
  		then
! 			$CP /tmp/archive.cpio* $PATCH_UNDO_ARCHIVE/$2
  		else
! 			$CP /tmp/archive.cpio* $1/$2/save
  		fi
! 		$RM -f /tmp/archive.cpio*
  		/usr/bin/gettext "Patchadd Interrupted.\n" >> $1/$2/log
  	fi
  	patch_quit 12 "yes"
--- 3100,3110 ----
  	else
  		if [[ "$PATCH_UNDO_ARCHIVE" != "none" ]]
  		then
! 			$CP ${WORKDIR}/archive.cpio* $PATCH_UNDO_ARCHIVE/$2
  		else
! 			$CP ${WORKDIR}/archive.cpio* $1/$2/save
  		fi
! 		$RM -f ${WORKDIR}/archive.cpio*
  		/usr/bin/gettext "Patchadd Interrupted.\n" >> $1/$2/log
  	fi
  	patch_quit 12 "yes"
***************
*** 3119,3125 ****
  	fi
  	if [[ "$isapplied" = "yes" ]]
  	then
! 		$RM -f /tmp/archive.cpio*
  	fi
  	patch_quit 12 "yes"
  }
--- 3127,3133 ----
  	fi
  	if [[ "$isapplied" = "yes" ]]
  	then
! 		$RM -f ${WORKDIR}/archive.cpio*
  	fi
  	patch_quit 12 "yes"
  }
***************
*** 3132,3138 ****
  function trap_notinstalled
  {
  	/usr/bin/gettext "Interrupt signal detected. Patch not installed.\n"
! 	$RM -fr /tmp/*.$$
  	$RM -f $INSTPATCHES_FILE
  	if [[ "$isapplied" = "no" ]]
  	then
--- 3140,3146 ----
  function trap_notinstalled
  {
  	/usr/bin/gettext "Interrupt signal detected. Patch not installed.\n"
! 	$RM -fr ${WORKDIR}/*.$$
  	$RM -f $INSTPATCHES_FILE
  	if [[ "$isapplied" = "no" ]]
  	then
***************
*** 3411,3417 ****
  	typeset -i insPs=0

  	patchFile=""
! 	patchFileStripped=/tmp/patchDBstripped.$$

  	if [[ "$validate" = "no" ]]
  	then
--- 3419,3425 ----
  	typeset -i insPs=0

  	patchFile=""
! 	patchFileStripped=${WORKDIR}/patchDBstripped.$$

  	if [[ "$validate" = "no" ]]
  	then
***************
*** 3796,3802 ****
      else
  		if [[ "$netImage" = "boot" ]]
  		then
!         	backout_dir=$ROOTDIR/tmp
  		else
          	backout_dir=$PKGDB
  		fi
--- 3804,3810 ----
      else
  		if [[ "$netImage" = "boot" ]]
  		then
!         	backout_dir=$ROOTDIR${WORKDIR}
  		else
          	backout_dir=$PKGDB
  		fi
***************
*** 3850,3856 ****
  	dryrunExit=
  	dryrunDir=

! 	dryrunDir="/tmp/$PatchNum.$$"

  	if [[ ! -d "$dryrunDir"  || "$1" != "0" ]]; then
  		dryrunFailure="yes"
--- 3858,3864 ----
  	dryrunExit=
  	dryrunDir=

! 	dryrunDir="${WORKDIR}/$PatchNum.$$"

  	if [[ ! -d "$dryrunDir"  || "$1" != "0" ]]; then
  		dryrunFailure="yes"
***************
*** 3955,3967 ****
  		restore_net_image
  	fi

! 	# The .../Boot/.tmp_proto/root needs to be re-mapped to .../Boot/tmp in order
  	# for the boot image to be patched successfully.

  	if [[ -z "$RE_MINIROOT_PATCH" ]]; then
! 		$MOUNT -F lofs -O $ROOTDIR/tmp $ROOTDIR/mnt
! 		$MOUNT -F lofs -O $ROOTDIR/.tmp_proto $ROOTDIR/tmp
! 		$MOUNT -F lofs -O $ROOTDIR/mnt/root/var $ROOTDIR/tmp/root/var
  	fi

  	# At this point patchadd thinks the net install image is just like
--- 3963,3975 ----
  		restore_net_image
  	fi

! 	# The .../Boot/.tmp_proto/root needs to be re-mapped to .../Boot${WORKDIR} in order
  	# for the boot image to be patched successfully.

  	if [[ -z "$RE_MINIROOT_PATCH" ]]; then
! 		$MOUNT -F lofs -O $ROOTDIR${WORKDIR} $ROOTDIR/mnt
! 		$MOUNT -F lofs -O $ROOTDIR/.tmp_proto $ROOTDIR${WORKDIR}
! 		$MOUNT -F lofs -O $ROOTDIR/mnt/root/var $ROOTDIR${WORKDIR}/root/var
  	fi

  	# At this point patchadd thinks the net install image is just like
***************
*** 3983,3990 ****
  	fi

  	if [[ -z "$RE_MINIROOT_PATCH" ]]; then
! 		$UMOUNT $ROOTDIR/tmp/root/var
! 		$UMOUNT $ROOTDIR/tmp
  		$UMOUNT $ROOTDIR/mnt
  	fi
  }
--- 3991,3998 ----
  	fi

  	if [[ -z "$RE_MINIROOT_PATCH" ]]; then
! 		$UMOUNT $ROOTDIR${WORKDIR}/root/var
! 		$UMOUNT $ROOTDIR${WORKDIR}
  		$UMOUNT $ROOTDIR/mnt
  	fi
  }
***************
*** 4168,4176 ****

      if [[ $pkgadd_code == 5 ]]  # administration
      then
! 		mv $LOGFILE /var/tmp/$PatchNum.log.$$ > /dev/null 2>&1
  		[ $? = 0 ] && ! 			/usr/bin/gettext "\nPkgadd failed. See /var/tmp/$PatchNum.log.$$ for details\n"

  		remove_patch_meta_data "$pkg"
  		[ -n "$pkgsAlreadyInstalled" ] && remove_patch
--- 4176,4184 ----

      if [[ $pkgadd_code == 5 ]]  # administration
      then
! 		mv $LOGFILE /var${WORKDIR}/$PatchNum.log.$$ > /dev/null 2>&1
  		[ $? = 0 ] && ! 			/usr/bin/gettext "\nPkgadd failed. See /var${WORKDIR}/$PatchNum.log.$$ for details\n"

  		remove_patch_meta_data "$pkg"
  		[ -n "$pkgsAlreadyInstalled" ] && remove_patch
***************
*** 4188,4196 ****
  		fi
      elif [[ $pkgadd_code != 0 ]]
      then
! 		mv $LOGFILE /var/tmp/$PatchNum.log.$$ > /dev/null 2>&1
  		[ $? = 0 ] && ! 			/usr/bin/gettext "\nPkgadd failed. See /var/tmp/$PatchNum.log.$$ for details\n"

  		# If there are more pkgs in the list skip them
  		# since this patch will not be installed.
--- 4196,4204 ----
  		fi
      elif [[ $pkgadd_code != 0 ]]
      then
! 		mv $LOGFILE /var${WORKDIR}/$PatchNum.log.$$ > /dev/null 2>&1
  		[ $? = 0 ] && ! 			/usr/bin/gettext "\nPkgadd failed. See /var${WORKDIR}/$PatchNum.log.$$ for details\n"

  		# If there are more pkgs in the list skip them
  		# since this patch will not be installed.
***************
*** 4321,4331 ****
  				if [[ "$firstTimeThru" = "yes" ]]
  				then
  					if [[ "$PKGADD_DEBUG" = "yes" ]]; then
! 						pkgadd -v -D /tmp/$PatchNum.$$ -S -n -a $ADMINTFILE   					  		$MOPTION -r $RESPONSE_FILE.1 -R $ROOTDIR   							-d . $pkglist
  					else
! 						pkgadd -D /tmp/$PatchNum.$$ -S -n -a $ADMINTFILE   					  		$MOPTION -r $RESPONSE_FILE.1   			    	  		-R $ROOTDIR -d . $pkglist   							1>>$LOGFILE </dev/null 2>&1
--- 4329,4339 ----
  				if [[ "$firstTimeThru" = "yes" ]]
  				then
  					if [[ "$PKGADD_DEBUG" = "yes" ]]; then
! 						pkgadd -v -D ${WORKDIR}/$PatchNum.$$ -S -n -a $ADMINTFILE   					  		$MOPTION -r $RESPONSE_FILE.1 -R $ROOTDIR   							-d . $pkglist
  					else
! 						pkgadd -D ${WORKDIR}/$PatchNum.$$ -S -n -a $ADMINTFILE   					  		$MOPTION -r $RESPONSE_FILE.1   			    	  		-R $ROOTDIR -d . $pkglist   							1>>$LOGFILE </dev/null 2>&1

--Drey_of_Squirrels_554_000--

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