Bug 642508 - ksh doesn't close the file including the function definition
Summary: ksh doesn't close the file including the function definition
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: ksh
Version: 5.5
Hardware: All
OS: Linux
high
high
Target Milestone: rc
: ---
Assignee: Michal Hlavinka
QA Contact: qe-baseos-tools-bugs
URL:
Whiteboard:
Depends On:
Blocks: 643811 684832
TreeView+ depends on / blocked
 
Reported: 2010-10-13 07:13 UTC by Masahiro Matsuya
Modified: 2018-11-26 19:32 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Prior to this update, ksh did not close a file containing an auto-loaded function definition. After loading several functions, ksh could have easily exceeded the system's limit on the number of open files. With this update, files containing auto-loaded functions are properly closed, thus, the number of opened files no longer increases with usage.
Clone Of:
: 643811 (view as bug list)
Environment:
Last Closed: 2012-02-21 05:50:11 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
proposed patch (434 bytes, patch)
2010-10-13 07:22 UTC, Masahiro Matsuya
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2012:0159 0 normal SHIPPED_LIVE ksh bug fix and enhancement update 2012-02-20 14:53:47 UTC

Description Masahiro Matsuya 2010-10-13 07:13:32 UTC
Description of problem:

ksh doesn't close the file including the function definition. So, when it reaches the system limit of the number of files, the ksh script failed on the way. The following is the reproducer.


# cat test.sh
#!/bin/ksh
main()
{
typeset i=0;
typeset a="";
FPATH="lib";
autoload ftest;
 while (( ${i} < 100000 ))
 do a=$(ftest "${i}") || {
        print -r -- "number of transactions : ${i}";
        return 1;
         }
         (( i = ${i} + 1 ))
        done
        print -r -- "number of transactions : ${i}";
}
main "$@";

# cat /lib/ftest
function ftest
{
        print -r -- "$*";
}


# ./test.ksh
test.ksh: line 9: function: not found
number of transactions : 1021


# lsof -p `pgrep ksh`
COMMAND  PID USER   FD   TYPE DEVICE     SIZE    NODE NAME
ksh     3810 root  cwd    DIR  253,0     4096 1104407 /root/ksh
ksh     3810 root  rtd    DIR  253,0     4096       2 /
ksh     3810 root  txt    REG  253,0  1301832  682138 /bin/ksh93
ksh     3810 root  mem    REG  253,0   139416  132340 /lib64/ld-2.5.so
ksh     3810 root  mem    REG  253,0  1717800  132341 /lib64/libc-2.5.so
ksh     3810 root  mem    REG  253,0   615136  132349 /lib64/libm-2.5.so
ksh     3810 root  mem    REG  253,0    23360  132347 /lib64/libdl-2.5.so
ksh     3810 root  mem    REG  253,0 56466976 1563157 /usr/lib/locale/locale-archive
ksh     3810 root    0u   CHR  136,2                4 /dev/pts/2
ksh     3810 root    1u   CHR  136,2                4 /dev/pts/2
ksh     3810 root    2u   CHR  136,2                4 /dev/pts/2
ksh     3810 root    3r  FIFO    0,6            13787 pipe
ksh     3810 root    4w  FIFO    0,6            13787 pipe
ksh     3810 root    5r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root    6r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root    7r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root    8r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root    9r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   10r   REG  253,0      323 1104413 /root/ksh/test.ksh
ksh     3810 root   11r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   12r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   13r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   14r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   15r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   16r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   17r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   18r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   19r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   20r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root   21r   REG  253,0       47 1104416 /root/ksh/lib/ftest
...
ksh     3810 root 1019r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root 1020r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root 1021r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root 1022r   REG  253,0       47 1104416 /root/ksh/lib/ftest
ksh     3810 root 1023r   REG  253,0       47 1104416 /root/ksh/lib/ftest


The following is the place where the error message "not found" is outputed.

    653 int sh_exec(register const Shnode_t *t, int flags)
    654 {
...
   1098                                         if(!np->nvalue.ip)
   1099                                         {
   1100                                                 indx = path_search(com0,NIL(Pathcomp_t**),0);
   1101                                                 if(indx==1)
   1102                                                         np = nv_search(com0,shp->fun_tree,HASH_NOSCOPE);
   1103 
   1104                                                 if(!np->nvalue.ip)
   1105                                                 {
   1106                                                         if(indx==1)
   1107                                                         {
   1108                                                                 errormsg(SH_DICT,ERROR_exit(0),e_defined,com0);
   1109                                                                 shp->exitval = ERROR_NOEXEC;
   1110                                                         }
   1111                                                         else
   1112                                                         {
   1113                                                                 errormsg(SH_DICT,ERROR_exit(0),e_found,"function");
   1114                                                                 shp->exitval = ERROR_NOENT;
   1115                                                         }
   1116                                                         goto setexit;
   1117                                                 }
   1118                                         }

Also, this is the backtrace.

(gdb) bt
#0  sh_exec (t=0x947560, flags=1) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/xec.c:1159
#1  0x00000000004456b2 in sh_subshell (t=0x947560, flags=1, comsub=1) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/subshell.c:573
#2  0x0000000000429fec in comsubst (mp=0x93d0f0, t=0x947560, type=1) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/macro.c:1999
#3  0x000000000042ce05 in varsub (mp=0x93d0f0) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/macro.c:1106
#4  0x000000000042ba30 in copyto (mp=0x93d0f0, endch=0, newquote=<value optimized out>) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/macro.c:587
#5  0x0000000000429d75 in sh_mactrim (shp=<value optimized out>, str=0x94ee81 "a=$(ftest \"${i}\")", mode=-1) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/macro.c:173
#6  0x0000000000435cda in nv_setlist (arg=0x94ee70, flags=131584, typ=0x0) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/name.c:325
#7  0x000000000044c723 in sh_exec (t=0x94eea0, flags=0) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/xec.c:830
#8  0x000000000044a51c in sh_exec (t=0x94f180, flags=4) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/xec.c:1578
#9  0x000000000044b0f9 in sh_exec (t=0x94f200, flags=4) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/xec.c:1560
#10 0x000000000044a4ba in sh_exec (t=0x94eda0, flags=4) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/xec.c:1759
#11 0x000000000044b0f9 in sh_exec (t=0x94f380, flags=4) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/xec.c:1560
#12 0x000000000045b07e in b_dot_cmd (n=<value optimized out>, argv=<value optimized out>, extra=<value optimized out>) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/bltins/misc.c:289
#13 0x000000000044f288 in sh_funct (shp=0x73c140, np=0x94f470, argn=1, argv=0x9474e8, envlist=<value optimized out>, execflg=5) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/xec.c:2719
#14 0x000000000044e4ab in sh_exec (t=0x947480, flags=37) at /usr/src/debug/ksh-20100202/src/cmd/ksh93/sh/xec.c:1138
#15 0x0000000000407c23 in exfile ()
#16 0x00000000004070b9 in sh_main ()
#17 0x00000038c7c1d994 in __libc_start_main () from /lib64/libc.so.6
#18 0x00000000004062d9 in _start ()


The file "/lib/ftest" is opened in path_search(), which calls path_opentype() which calls sh_open(). But, it's not closed anywhere.


I will attach the proposed patch for this problem.


Version-Release number of selected component (if applicable):
ksh-20100202-1.el5
This problem doesn't occur with ksh-20080202-2.el5. 

How reproducible:
Always

Steps to Reproduce:
1. create the reproducer written in Descritpion of Problem.
2. and run.

Actual results:
The opened file "lib/ftest" is not closed properly, and the ksh script aborts on the way.

Expected results:
The opened file "lib/ftest" is closed properly, and the ksh script finishes correctly.

Comment 1 Masahiro Matsuya 2010-10-13 07:22:43 UTC
Created attachment 453099 [details]
proposed patch

Comment 2 Michal Hlavinka 2010-10-13 13:52:22 UTC
thanks, I can reproduce this

Comment 6 Martin Prpič 2011-03-16 15:57:23 UTC
    Technical note added. If any revisions are required, please edit the "Technical Notes" field
    accordingly. All revisions will be proofread by the Engineering Content Services team.
    
    New Contents:
Prior to this update, ksh did not close a file containing an auto-loaded function definition. After loading several functions, ksh could have easily exceeded the system's limit on the number of open files. With this update, files containing auto-loaded functions are properly closed, thus, the number of opened files no longer increases with usage.

Comment 12 errata-xmlrpc 2012-02-21 05:50:11 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHBA-2012-0159.html


Note You need to log in before you can comment on or make changes to this bug.