Bugtraq mailing list archives
Re: Solaris patchadd(1) (3) symlink vulnerabilty
From: Darren Moffat <Darren.Moffat () eng sun com>
Date: Fri, 22 Dec 2000 09:26:16 -0800
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. ==============================================================================
*** 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
Current thread:
- Re: Solaris patchadd(1) (3) symlink vulnerabilty Darren Moffat (Dec 22)
- <Possible follow-ups>
- Re: Solaris patchadd(1) (3) symlink vulnerabilty Paul Szabo (Dec 24)