[18323] in bugtraq
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--