Patch Name: PHCO_30316 Patch Description: s700_800 11.11 ksh(1) cumulative patch Creation Date: 04/07/14 Post Date: 04/08/10 Hardware Platforms - OS Releases: s700: 11.11 s800: 11.11 Products: N/A Filesets: OS-Core.CORE-ENG-A-MAN,fr=B.11.11,fa=HP-UX_B.11.11_32/64,v=HP OS-Core.UX-CORE,fr=B.11.11,fa=HP-UX_B.11.11_32/64,v=HP Automatic Reboot?: No Status: General Release Critical: Yes PHCO_30316: CORRUPTION MEMORY_LEAK ksh(1) prints incorrect pid value for the signalled child. "set -A" leaks memory in ksh shell. PHCO_27019: ABORT MEMORY_LEAK CORRUPTION Category Tags: defect_repair general_release critical halts_system corruption memory_leak Path Name: /hp-ux_patches/s700_800/11.X/PHCO_30316 Symptoms: PHCO_30316: ( SR:8606340439 CR:JAGaf01358 ) The ksh shell displays wrong pid for the signalled child. ( SR:8606369178 CR:JAGaf29722 ) "set -A" leaks memory in ksh shell. PHCO_30000: ( SR:8606330785 CR:JAGae91908 ) Large number of background jobs running on an interactive ksh shell terminates it. PHCO_27019: ( SR:8606273772 CR:JAGae37860 ) 1. Repeated use of getopts builtin in ksh(1) causes memory leak. ( SR:8606179356 CR:JAGad48580 ) 2. ksh(1) makes improper use of the file system. ( SR:8606226600 CR:JAGad95665 ) 3. Script using eval special builtin exits for ALL errors. ( SR:8606273770 CR:JAGae37858 ) 4. ksh(1) corrupts memory in emacs mode of editing. ( SR:8606284030 CR:JAGae47976 ) 5. ksh(1) does not handle filesystem related failures properly. ( SR:8606271856 CR:JAGae36035 ) 6. trap builtin fails to disable signal SIGQUIT on some condition. ( SR:8606249921 CR:JAGae16307 ) 7. ksh(1) does not work as expected, when trying to make a ~user substitution after login. ( SR:8606267591 CR:JAGae31833 ) 8. "set --" corrupts $0 when called using ksh(1). ( SR:8606186029 CR:JAGad55234 ) 9. ksh(1) ulimit does not report 'unlimited' for filesize. This causes users to incorrectly assume that ksh does not handle large files. ( SR:8606187216 CR:JAGad56424 ) 10. ksh(1) coredumps if SIGWINCH is sent early. ( SR:8606199752 CR:JAGad68938 ) Duplicate ( SR:8606216997 CR:JAGad86152 ) 11. ksh(1) removes here-document before RHS of pipe can read it. ( SR:8606189689 CR:JAGad58902 ) 12. While using getopts, incrementing OPTIND causes ksh(1) to coredump with SIGSEGV. Defect Description: PHCO_30316: ( SR:8606340439 CR:JAGaf01358 ) For any signalled child, ksh(1) generates a message of the form "command[]: ". The pid that gets printed will be incorrect most of the time. The problem can be reproduced as follows:- $ cat myscript #!/usr/bin/ksh -p # Lots of comments so # that the lines below # are after 10 just so # the affect of the bug # is easily seen. # 8 # 9 # 10 print "mypid=$$" ksh -c 'kill -9 $$' ksh -c 'kill -9 $$' ksh -c 'kill -9 $$' ksh -c 'kill -9 $$' $ /usr/bin/ksh myscript mypid=25632 myscript[12]: 25612 Killed myscript[13]: 25613 Killed myscript[14]: 25614 Killed myscript[15]: 25615 Killed $ In the above case,the shell prints the wrong pid. For instance, the "12" in the pid "25612" of line "myscript[12]: 25612 Killed" is actually the line number "12". The ksh shell uses a global array to store the string representation of the integer. In this case, it converts the process pid to its string format and store it in the global array. Before it is copied to the actual error message, it tries to convert the line number into its string format and store its value in the global array which corrupts the pid value stored earlier in it. Resolution: Now ksh(1) is modified such that the string representation of the pid will be copied to a temporary buffer before it tries to store the string representation of line number in the global array. ( SR:8606369178 CR:JAGaf29722 ) In ksh shell, "set -A" is used to unset the current variable and assign array elements to the variable. If the variable is already an array, it frees the memory allocated for the existing array elements before creating the new array elements. The code for freeing the memory of the existing array elements was returning without freeing the memory allocated to the last element in the array causing the memory leak. The problem can be reproduced as follows: $cat leak.ksh #!/usr/bin/ksh typeset -i N=0 while [[ $N -le $1 ]];do set -A arr 1 2 (( N = N + 1 )) done UNIX95=1 ps -osz,comm -p$$; exit $ The above script will print the size of the shell. 2. Run the above script with the argument let's say 1 and 50000 and compare the size of the shell. E.g. $/usr/bin/ksh leak.ksh 1 SZ COMMAND 56 ksh $/usr/bin/ksh leak.ksh 50000 SZ COMMAND 403 ksh $ Resolution: Now ksh(1) is modified to free the memory associated with all the existing array elements. PHCO_30000: ( SR:8606330785 CR:JAGae91908 ) Large number of background jobs running on an interactive ksh shell terminates it. The problem can be reproduced as follows: $/usr/bin/ksh $set -o vi $for i in `perl -e '@a=(1..50); print "@a"'` >do >sleep 15 & >done. $ Now wait for around 15 to 20 seconds without entering any input on the standard input. After 15 or 20 seconds, the ksh shell will be terminated automatically. Root Cause: When the ksh shell fails to read from the standard input due to the interruption by SIGCHLD signals generated after the termination of each background job, it tries to read again for a fixed number of times. The shell exits if it doesn't succeed within the fixed number of tries. Resolution: Now the code is modified so that the shell will always try to read again from the standard input if it fails to read due to the SIGCHLD interruption. PHCO_27019: ( SR:8606273772 CR:JAGae37860 ) 1. Repeated use of getopts builtin in ksh(1) causes memory leak. Problem Reproduction: --------------------- Step 1. Run the below script $ cat ./script #!/usr/bin/ksh function leak { while getopts b: name "-b king" do case $name in b) ;; ?) echo "Test failed\n" exit 2;; esac done OPTIND=1 return } i=0 while test $i -le 3 do leak i=$(($i+1)) done i=0 UNIX95=1 ps -p$$ -osz | paste - - while test $i -le 30000 do leak i=$(($i+1)) done UNIX95=1 ps -p$$ -osz | paste - - #end of script $ ./script The below output shows the increase in the physical page size of ksh. SZ 52 SZ 146 Executing "getopts" assigns new value to shell variable OPTARG. ksh(1) does this by allocating a new memory for holding the value of OPTARG. However, the previous memory to which OPTARG was pointing was not freed resulting in memory leak. Resolution: Now the old memory location pointed to by OPTARG is freed before OPTARG is assigned new values. ( SR:8606179356 CR:JAGad48580 ) 2. ksh(1) makes improper use of the file system. Resolution: The file system usage corrected. ( SR:8606226600 CR:JAGad95665 ) 3. Scripts using special builtin commands like eval, exit for All kinds of errors that occur during the execution of the special builtin commands. This behavior was introduced to meet the ksh(1) man page documentation. ksh(1) man page documented that errors in special builtin commands cause the scripts containing them to abort. Problem Reproduction: -------------------- Run the following script. Script - eval.scr #!/usr/bin/ksh eval cd /abc # /abc should not exist!!! echo hello #script ends. The script exits with the following output: ./eval.scr[3]: /abc: not found The correct behavior would be to produce the following output: ./eval.scr[3]: /abc: not found hello Resolution: The earlier behavior of ksh(1) wrt. handling errors in special builtins has been restored. ksh(1) man page has been corrected. ( SR:8606273770 CR:JAGae37858 ) 4. ksh(1) corrupts memory in emacs mode of editing. The corruption occurs when the user repeatedly types <.> to insert the last word of the previous command on the same line. Problem Reproduction: --------------------- Step 1. On a ksh interactive shell set the editor mode to emacs. $ set -o emacs Step 2. Create and store a data to be yanked later. $ abcdefghijklmnopqrstuvwxyz

Step 3. Type the command as shown below. $ ls aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.... Step 4. Insert the last word of the previous command repeatedly as shown below. $ <.><.><.><.><.> <.><.> Step 5. Now yank the previously stored item. $ aaaaaaaaaaaaaaaaaaaaaaaaa.... Due to memory corruption the yanked data will be "aaaaaaaaaaaaaaaaaaa" instead of "abcdefghijklmnopqrstuvwxyz". Repeated typing of <.> in step 4 can cause ksh(1) to report memory fault. The problem was due to ksh(1) not checking the boundary limits of the input buffer when <.> is typed, resulting in buffer overflow. Resolution: The proper boundary check has been introduced for <.>. ( SR:8606284030 CR:JAGae47976 ) 5. ksh(1) does not handle filesystem related failures properly. Resolution: Necessary cleanup activity is done before the graceful exit of ksh. ( SR:8606271856 CR:JAGae36035 ) 6. Trap fails to disable signal SIGQUIT on certain condition. Problem Reproduction: --------------------- Step 1. Run the below script $ cat ./script #!/usr/bin/ksh function exports { eval export FOO=foo } exports trap "" QUIT print "Sleep 5" sleep 5 exit #end of script Step 2: When the above program displays "Sleep 5" type <|> "sleep" command exits dumping core (action for SIGQUIT) which is not expected. The problem was due to ksh(1) not setting the trap flags for SIGQUIT properly after a function is called. As a result if a user tries to disable the trap for SIGQUIT after calling a function, the signal handlers were not set properly. Resolution: The trap related flags are now set properly. ( SR:8606249921 CR:JAGae16307 ) 7. Soon after invoking the shell, if a tilde substitution is attempted, ksh does not correctly display the result. ~ will result in "*", instead of "/". Problem Reproduction: --------------------- Run the following commands: * Invoke ksh as - /usr/bin/ksh -ksh * set -o vi * cd ~ The display will look like - cd /mnt/vts*, which is wrong. The display should have been - cd /mnt/vts/ Resolution: The problem was in the way ksh was handling its local stak during tilde substitution and filename generation. The stak data was overwritten due to mishandling of allocated space. This has been set right now. ( SR:8606267591 CR:JAGae31833 ) 8. "set --" corrupts $0 when called using ksh(1). The problem occurs when the shell script is run using "ksh -c" or it is invoked inside another script. The shell script that is getting executed should not begin with "#!/usr/bin/ksh" or "#!/usr/bin/sh". Problem Reproduction: --------------------- Step 1. Run the below script with -c option. $ cat ./script echo $0 ACTDIR=`dirname $0` VAR02345="00000000" VAR1="11111111" set -- 12345678 VAR2="22222222" VAR3="33333333" VAR4="44444444" ADIR=`dirname $0` echo "before test of \$0 output -- $0 +" set -- abcdefghijklmnopqrstuvwxyz echo "after test of \$0 output -- $0 -" $ ksh -c ./script The output may be as shown below: ./script before test of $0 output -- ./script + after test of $0 output -- @ - "set --" should not change the value of $0. Earlier in certain cases $0 was stored along with other positional parameters in the heap memory. Calling `set --` will free this memory which resulted in the pointer to $0, pointing to a freed memory. The problem is only visible if the freed memory is reused by ksh before we try to access $0. Resolution: Now $0 is stored in a separate memory and not along with the other positional parameters. ( SR:8606186029 CR:JAGad55234 ) 9. ksh(1) ulimit does not report 'unlimited' as the value of file size limit. It reports an incorrect value. This would mislead users to conclude that large files are not supported on HPUX. Unless the file size limit is set by the user, ulimit builtin should report "unlimited", as per the ksh documentation from O'reily and other vendors. Problem Reproduction: -------------------- * Ensure that the file size limit for the current session is not set (i.e. it is unlimited). * Invoke ksh * Execute the builtin command - ulimit The shell would output: 4194303 The correct behavior would be to output: unlimited Resolution: ksh(1) used the system call ulimit() to get/set the file size limit. Now it makes use of getrlimit()/setrlimit() for this purpose which help in determining whether the limit is "unlimited" or a user defined value. ksh(1) man page has been modified to document the ulimit behavior. ( SR:8606187216 CR:JAGad56424 ) 10.ksh(1) coredumps if SIGWINCH is sent early. ksh installs a signal handler for SIGWINCH, which tries to initialize contents of pointers which are not yet allocated space. SIGWINCH was blocked after the signal handler is installed, until the various pointers were allocated space. If SIGWINCH was received in the window between the handler installation and signal blocking, the signal handler caused core dump. Problem Reproduction: --------------------- This is a race condition. It happens if an early SIGWINCH is sent during the shell startup. For this problem to be seen, the SIGWINCH has to be received by the shell during a very small window between the signal handler installation and blocking of SIGWINCH. This can not be reproduced without manipulating (introducing a delay) the source code. Resolution: The solution is to remove the window between the handler installation and the blocking of SIGWINCH. SIGWINCH is now blocked before the signal handler installation and released after the required space allocations. ( SR:8606199752 CR:JAGad68938 ) Duplicate ( SR:8606216997 CR:JAGad86152 ) 11.ksh(1) removes here-document before RHS of pipe can read it. Problem Reproduction: --------------------- Run the below script. $ cat ./script #!/usr/bin/ksh count=0 while [ count -ne 30000 ] do VAR=`echo value << end |grep -i value end` echo $VAR count=$((count+1)) done $ ./script ksh may give an error message /tmp/sh11503.1: cannot open. In the above script, shell on command substitution involving pipe forks a child to do the command substitution. This child executes the RHS of the pipe after forking another child to execute the the LHS. Before executing the RHS the first child deletes all the temporary files created by it. The problem occurred because of the race condition: RHS removed the temporary files before the LHS could open it for reading. Resolution: The problem has been solved by making the shell in RHS selective in removing the temporary files so that those files that are to be used and deleted in LHS are not deleted by RHS. Please refer to the WARNINGS section of the ksh(1) manpage for more information about here-documents. ( SR:8606189689 CR:JAGad58902 ) 12.While using getopts, incrementing OPTIND causes ksh(1) to coredump with SIGSEGV. When OPTIND is set to a value greater than the number of arguments passed to the builtin command getopts, ksh(1) tries to access memory beyond the array boundary. This causes coredump with SIGSEGV. Problem Reproduction: --------------------- Run the following script: Script getopts.scr: #!/usr/bin/ksh function CORE_ME { OPTIND=1 while getopts q:i:e:c:I:Q:t:kmswC4Tgno opt do OPTIND=$(($OPTIND+1)) done } CORE_ME -i foo.exp echo $OPTARG #script ends. The script coredumps with SIGSEGV. The correct behavior would be to produce the following output, without a coredump. foo.exp Resolution: getopts has been modified to return end-of-options, when the value of OPTIND is greater than the no. of arguments. Only if OPTIND is within the valid limit, it attempts to process the options and arguments. Enhancement: No SR: 8606179356 8606186029 8606187216 8606189689 8606199752 8606216997 8606226600 8606249921 8606267591 8606271856 8606273770 8606273772 8606284030 8606330785 8606340439 8606369178 Patch Files: OS-Core.CORE-ENG-A-MAN,fr=B.11.11,fa=HP-UX_B.11.11_32/64, v=HP: /usr/share/man/man1.Z/ksh.1 /usr/share/man/man1.Z/rksh.1 OS-Core.UX-CORE,fr=B.11.11,fa=HP-UX_B.11.11_32/64,v=HP: /usr/bin/ksh /usr/bin/rksh what(1) Output: OS-Core.CORE-ENG-A-MAN,fr=B.11.11,fa=HP-UX_B.11.11_32/64, v=HP: /usr/share/man/man1.Z/ksh.1: None /usr/share/man/man1.Z/rksh.1: None OS-Core.UX-CORE,fr=B.11.11,fa=HP-UX_B.11.11_32/64,v=HP: /usr/bin/ksh: defs.c $Date: 2002/11/18 20:42:15 $Revision: r11.11/ 2 PATCH_11.11 (PHCO_27019) edit.c $Date: 2003/12/04 01:58:17 $Revision: r11.11/ 4 PATCH_11.11 (PHCO_30000) fault.c $Date: 2003/12/04 02:02:36 $Revision: r11.11 /3 PATCH_11.11 (PHCO_30000) io.c $Date: 2003/12/04 02:04:39 $Revision: r11.11/6 PATCH_11.11 (PHCO_30000) emacs.c $Date: 2003/12/04 02:01:04 $Revision: r11.11 /3 PATCH_11.11 (PHCO_30000) vi.c $Date: 2003/12/04 02:06:52 $Revision: r11.11/2 PATCH_11.11 (PHCO_30000) cmd.c $Date: 2002/11/18 20:41:14 $Revision: r11.11/1 PATCH_11.11 (PHCO_27019) main.c $Date: 2002/11/18 20:52:03 $Revision: r11.11/ 4 PATCH_11.11 (PHCO_27019) xec.c $Date: 2002/11/18 20:52:56 $Revision: r11.11/2 PATCH_11.11 (PHCO_27019) macro.c $Date: 2002/11/18 20:51:03 $Revision: r11.11 /2 PATCH_11.11 (PHCO_27019) error.c $Date: 2002/11/18 20:44:16 $Revision: r11.11 /2 PATCH_11.11 (PHCO_27019) jobs.c $Date: 2004/07/08 23:34:44 $Revision: r11.11/ 4 PATCH_11.11 (PHCO_30316) growaray.c $Date: 2004/07/08 23:31:31 $Revision: r11 .11/1 PATCH_11.11 (PHCO_30316) unassign.c $Date: 2004/07/08 23:28:02 $Revision: r11 .11/1 PATCH_11.11 (PHCO_30316) $Revision: vw: -f selectors: R11.11_BL2004_0714_6 PHCO_30316 'R11.11_BL2004_0714_6' $ B.11.11_LR Jul 24 2003 00:43:42 $ Version 11/16/88 /usr/bin/rksh: defs.c $Date: 2002/11/18 20:42:15 $Revision: r11.11/ 2 PATCH_11.11 (PHCO_27019) edit.c $Date: 2003/12/04 01:58:17 $Revision: r11.11/ 4 PATCH_11.11 (PHCO_30000) fault.c $Date: 2003/12/04 02:02:36 $Revision: r11.11 /3 PATCH_11.11 (PHCO_30000) io.c $Date: 2003/12/04 02:04:39 $Revision: r11.11/6 PATCH_11.11 (PHCO_30000) emacs.c $Date: 2003/12/04 02:01:04 $Revision: r11.11 /3 PATCH_11.11 (PHCO_30000) vi.c $Date: 2003/12/04 02:06:52 $Revision: r11.11/2 PATCH_11.11 (PHCO_30000) cmd.c $Date: 2002/11/18 20:41:14 $Revision: r11.11/1 PATCH_11.11 (PHCO_27019) main.c $Date: 2002/11/18 20:52:03 $Revision: r11.11/ 4 PATCH_11.11 (PHCO_27019) xec.c $Date: 2002/11/18 20:52:56 $Revision: r11.11/2 PATCH_11.11 (PHCO_27019) macro.c $Date: 2002/11/18 20:51:03 $Revision: r11.11 /2 PATCH_11.11 (PHCO_27019) error.c $Date: 2002/11/18 20:44:16 $Revision: r11.11 /2 PATCH_11.11 (PHCO_27019) jobs.c $Date: 2004/07/08 23:34:44 $Revision: r11.11/ 4 PATCH_11.11 (PHCO_30316) growaray.c $Date: 2004/07/08 23:31:31 $Revision: r11 .11/1 PATCH_11.11 (PHCO_30316) unassign.c $Date: 2004/07/08 23:28:02 $Revision: r11 .11/1 PATCH_11.11 (PHCO_30316) $Revision: vw: -f selectors: R11.11_BL2004_0714_6 PHCO_30316 'R11.11_BL2004_0714_6' $ B.11.11_LR Jul 24 2003 00:43:42 $ Version 11/16/88 cksum(1) Output: OS-Core.CORE-ENG-A-MAN,fr=B.11.11,fa=HP-UX_B.11.11_32/64, v=HP: 1611916536 42262 /usr/share/man/man1.Z/ksh.1 1611916536 42262 /usr/share/man/man1.Z/rksh.1 OS-Core.UX-CORE,fr=B.11.11,fa=HP-UX_B.11.11_32/64,v=HP: 2931722248 159744 /usr/bin/ksh 2931722248 159744 /usr/bin/rksh Patch Conflicts: None Patch Dependencies: None Hardware Dependencies: None Other Dependencies: None Supersedes: PHCO_30000 PHCO_27019 Equivalent Patches: None Patch Package Size: 180 KBytes Installation Instructions: Please review all instructions and the Hewlett-Packard SupportLine User Guide or your Hewlett-Packard support terms and conditions for precautions, scope of license, restrictions, and, limitation of liability and warranties, before installing this patch. ------------------------------------------------------------ 1. Back up your system before installing a patch. 2. Login as root. 3. Copy the patch to the /tmp directory. 4. Move to the /tmp directory and unshar the patch: cd /tmp sh PHCO_30316 5. Run swinstall to install the patch: swinstall -x autoreboot=true -x patch_match_target=true \ -s /tmp/PHCO_30316.depot By default swinstall will archive the original software in /var/adm/sw/save/PHCO_30316. If you do not wish to retain a copy of the original software, include the patch_save_files option in the swinstall command above: -x patch_save_files=false WARNING: If patch_save_files is false when a patch is installed, the patch cannot be deinstalled. Please be careful when using this feature. For future reference, the contents of the PHCO_30316.text file is available in the product readme: swlist -l product -a readme -d @ /tmp/PHCO_30316.depot To put this patch on a magnetic tape and install from the tape drive, use the command: dd if=/tmp/PHCO_30316.depot of=/dev/rmt/0m bs=2k Special Installation Instructions: None