Note: This is a beta release of Red Hat Bugzilla 5.0. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Also email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback here.

Bug 85917

Summary: buffer overrun in _dl_important_hw_caps
Product: [Retired] Red Hat Linux Reporter: John Reiser <jreiser>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED CURRENTRELEASE QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 9CC: fweimer
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: 2.3.2-27.9 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2003-04-17 05:41:04 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description John Reiser 2003-03-10 20:22:32 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020529

Description of problem:
When there is only one important hardware capability, then the terminating slash
'/' is stored beyond the the end of a malloc()ed block.

The bug [fix] is at line 334; the existing overrun occurs at line 356:
-----sysdeps/generic/dl-sysdep.c line 332
  /* Determine the total size of all strings together.  */
  if (cnt == 1)
    total = temp[0].len;   /* BUG: forgot +1 */
  else
    {
      total = (1UL << (cnt - 2)) * (temp[0].len + temp[cnt - 1].len + 2);
      for (n = 1; n + 1 < cnt; ++n)
        total += (1UL << (cnt - 3)) * (temp[n].len + 1);
    }

  /* The result structure: we use a very compressed way to store the
     various combinations of capability names.  */
  *sz = 1 << cnt;
  result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
  if (result == NULL)
    goto no_memory;

  if (cnt == 1)
    {
      result[0].str = (char *) (result + *sz);
      result[0].len = temp[0].len + 1; 
      result[1].str = (char *) (result + *sz);
      result[1].len = 0;
      cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len);
      *cp = '/';   /* OVERRUN here */
-----


Version-Release number of selected component (if applicable):
Source is glibc-2.3.1-20021219

How reproducible:
Always

Steps to Reproduce:
1.Run any program using ld-linux.so.2 on a machine with only one important
hardware capability.  Total capability of 0x383f9ff, from a i686 (PentiumIII
Mobile) seems to be such a box.
2.
3.
    

Actual Results:  Terminating '/' is stored beyond the end of a malloc()ed block.

Expected Results:  Terminating '/' is stored within the malloc()ed block.

Additional info:

Comment 1 Ulrich Drepper 2003-04-17 05:41:04 UTC
This has been fixed some time ago in the glibc CVS version and should already be
in glibc 2.3.2-27.9.