Bug 190901 - Bug in memory management of pdksh (alloc.c)
Bug in memory management of pdksh (alloc.c)
Status: CLOSED ERRATA
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: pdksh (Show other bugs)
3.0
All Linux
medium Severity medium
: ---
: ---
Assigned To: Karsten Hopp
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2006-05-06 02:49 EDT by tsunenoyama
Modified: 2007-11-30 17:07 EST (History)
0 users

See Also:
Fixed In Version: pdksh-5.2.14-21.9
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2007-04-05 05:52:17 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description tsunenoyama 2006-05-06 02:49:59 EDT
Description of problem:
Bug in memory management of pdksh (alloc.c)

Version-Release number of selected component (if applicable):
All version of pdksh
RHEL AS2.1 pdksh-5.2.14-21
RHEL AS3 pdksh-5.2.14-22
RHEL AS4 pdksh-5.2.14-30.3

How reproducible:

Steps to Reproduce:
1.download and extract source of pdksh.
  I used pdksh-5.2.14-21.

2.make "TEST_ALLOC" tool in alloc.c
  % cd pdksh-5.2.14-21
  % gcc -o ../test_alloc -DTEST_ALLOC=1 -DDEBUG_ALLOC=1 -O2 -march=i386 -
mcpu=i686 alloc.c
  % cd ..
  % ls -l test_alloc
  -rwxr-xr-x  1 root 1101  11637 May  5  2006 test_alloc

3.run test_alloc and test
  % ./test_alloc
  INPUT > alloc 800 = i1
  OUTPUT> 0x804b028 = alloc(800) [1,i1]
  INPUT > alloc 792 = i2
  OUTPUT> 0x804b358 = alloc(792) [2,i2]
  INPUT > alloc 10 = i3
  OUTPUT> 0x804b680 = alloc(10) [3,i3]
  INPUT > aprint 0
  OUTPUT> aprint(0, 0) [4]
  OUTPUT> aprint: block  0 (p=0x804b008,0x804b008,n=0x804b008): 0x0x804b018 ..
  OUTPUT> 0x0x804b988 (2416)
  OUTPUT> aprint:   0x0x804b018 .. 0x0x804b348 (816) allocated
  OUTPUT> aprint:   0x0x804b348 .. 0x0x804b670 (808) allocated
  OUTPUT> aprint:   0x0x804b670 .. 0x0x804b690 (32) allocated
  OUTPUT> aprint:   0x0x804b690 .. 0x0x804b988 (760) free

  INPUT > afree i1
  OUTPUT> afree(0x804b028) [5,i1]
  INPUT > afree i2
  OUTPUT> afree(0x804b358) [6,i2]
  INPUT > aprint 0
  OUTPUT> aprint(0, 0) [7]
  OUTPUT> aprint: block  0 (p=0x804b008,0x804b008,n=0x804b008): 0x0x804b018 ..  
0x0x804b988 (2416)
  OUTPUT> aprint:   0x0x804b018 .. 0x0x804b670 (1624) free
  OUTPUT> aprint:   0x0x804b670 .. 0x0x804b690 (32) allocated
  OUTPUT> aprint:   0x0x804b690 .. 0x0x804b988 (760) free

  INPUT > alloc 1591 = i4
  OUTPUT> acheck: big cell doesn't make up whole block
  OUTPUT> aerror: acheck failed

  The test_alloc failed in acheck().
 
Actual results:
  Freeing of memory area even though it is under use.
  After that, memory corruption, SIGSEGV, ...

Expected results:

Additional info:
  "INPUT > alloc 1591 = i4" ==> alloc(1591,ap) ==> ...

  alloc.c
  ---------------------------------------------------
  166 alloc(size, ap)
  169 {
          :
  177     cells = (unsigned)(size + sizeof(Cell) - 1) / sizeof(Cell);
  *****>> cells = ( 1591 + 8 - 1 ) / 8 = 199
          :
  182     /*
  183      * Only attempt to track small objects - let malloc deal
  184      * with larger objects. (this way we don't have to deal with
  185      * coalescing memory, or with releasing it to the system)
  186      */
  187     if (cells <= ICELLS) {
  *****>> if (199   <= 200   ) {
  188         /* find free Cell large enough */
  189         for (bp = ap->freelist; ; bp = bp->next) {
  190             for (fpp = NULL, fp = bp->freelist;
  191                  fp != bp->last; fpp = fp, fp = fp->next)
  192             {
  193                 if ((fp-1)->size >= cells)
  194                     goto Found;
  *********************>> fp is "aprint: 0x0x804b018 .. 0x0x804b670 (1624) free"
  *********************>> (fp-1)->size = 1624/8 - NOBJECT_FIELDS(2) = 201 cells
  195             }
          :
  226   Found:
  227     return asplit(ap, bp, fp, fpp, cells);
  228 }
          :
  234 asplit(ap, bp, fp, fpp, cells)
  240 {
  241     Cell *dp = fp;  /* allocated object */
  242     int split = (fp-1)->size - cells;
  *****>> int split = 201 - 199 = 2
  243
  244     ACHECK(ap);
  245     if (split < 0)
  246         aerror(ap, "allocated object too small");
  247     if (split <= NOBJECT_FIELDS) {  /* allocate all */
  *****>> if (2     <= 2             ) {  /* allocate all */
  248         fp = fp->next;
  249     } else {        /* allocate head, free tail */
          :
  262     ACHECK(ap);
  *****>> acheck: big cell doesn't make up whole block
  263     return (void*) dp;
  264 }
          :
  485 acheck(ap)
  487 {
          :
  529             if ((dp-1)->size > ICELLS
  530                 && !isfree
  531                 && (dp != &bp->cell[NOBJECT_FIELDS]
  532                 || dp + (dp-1)->size != bp->last))
  533             {
  534                 shellf("acheck: big cell doesn't make up whole block\n");
  *****************>> The test_alloc failed in acheck().
  535                 ok = 0;
  536             }
  ---------------------------------------------------

  "alloc(1591,ap)" allocate "201 cells + NOBJECT_FIELDS(2)"
  for 1591 bytes request.
  Because it's size greater than ICELLS(200),
  it is "big cell doesn't make up whole block" error.

  If "afree(0x804b028)" was done, it will free all memory of the block.
  Even though "aprint: 0x0x804b670 .. 0x0x804b690 (32) allocated"
  exists on the block.

  ---------------------------------------------------
  404 afree(ptr, ap)
  407 {
          :
  417     /* If this is a large object, just free it up... */
  418     /* Release object... */
  419     if ((dp-1)->size > ICELLS) {
  420         ablockfree(bp, ap);
  421         ACHECK(ap);
  422         return;
  423     }
  ---------------------------------------------------

Thanks.

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