Bug 24093

Summary: rpm-3.0.6_IBM_patch_006 rpm --help unexpected behaviour due to format[10] buffer overrun
Product: [Retired] Red Hat Linux Reporter: Paul Shearer <paulsh>
Component: rpmAssignee: Jeff Johnson <jbj>
Status: CLOSED RAWHIDE QA Contact: David Lawrence <dkl>
Severity: high Docs Contact:
Priority: high    
Version: 7.0   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2001-01-16 06:08:25 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
rpm-3.0.6_IBM_patch_006 Patch File to fix bugzilla 24093 rpm --help problem none

Description Paul Shearer 2001-01-16 05:45:58 UTC
IBM SPTS:       254762
IBM PATCH:     rpm-3.0.6_IBM_patch_006

Submitter:      paulsh.com
                     Paul Shearer

Product:        Red Hat Linux
Version:         6.2  ALSO  7.0
Component:   rpm-3.0.6  ALSO rpm-4.0
Platform:       All
OS:              All
uname -a:     DYNIX/ptx eng2 4.0 V4.6.0 i386

Summary:

        rpm --help unexpected behaviour due to format[10] buffer overrun

Description:

OVERVIEW DESCRIPTION:

        rpm --help results in infinite loop and continuous output on IBM NUMA-Q

        This is because rpm.c:printHelpLine(): format[10] should be format[12].
        This local array format[10] is filled using sprintf() and the
        resulting 12 character string (11 plus null) overruns the
        format[10] array on the stack and on any system will cause
        unexpected behavior (possible working ok) on lines that wrap around,
        and on some systems (like IBM NUMA-Q DYNIX/ptx) this problem
        causes an infinite loop in the code when printing longer lines
        with printHelpLine(), specifically lines that wrap around.

        format[10] is too small, change to
        format[12] because it needs to be large enough to hold format string
        "%.50s\n%29s"  (i.e. 11 chars plus NULL char.)

        See patch below.

Summary:

        rpm --help unexpected behaviour since format[10] too small

Description:

OVERVIEW DESCRIPTION:

        rpm --help results in infinite loop and continuous output on IBM NUMA-Q

        This is because rpm.c:printHelpLine(): format[10] should be format[12].
        This local array format[10] is filled using sprintf() and the
        resulting 12 character string (11 plus null) overruns the
        format[10] array on the stack and on any system will cause
        unexpected behavior (possible working ok) on lines that wrap around,
        and on some systems (like IBM NUMA-Q DYNIX/ptx) this problem
        causes an infinite loop in the code when printing longer lines
        with printHelpLine(), specifically lines that wrap around.

        format[10] is too small, change to
        format[12] because it needs to be large enough to hold format string
        "%.50s\n%29s"  (i.e. 11 chars plus NULL char.)

        See patch below.

STEPS TO REPRODUCE:

        rpm --help

        rpm may have problems when it attempts to print wrapping lines like:

    --verify               - verify a package installation using the same same
                             package specification options as -q



ACTUAL RESULTS:

        For all systems, check the lines printed with --verify
        to look for problems.

        On systems like IBM NUMA-Q DYNIX/ptx it will result in infinite loop:

rpm --help
... [output]
    --verify               - verify a package installation using the same same
                             n using the same same package specification
                             n using the same same package specification
                             n using the same same package specification
                             ...
                             [Infinite loop repeats the above line forever.]

EXPECTED RESULTS:

        Again the correct "rpm --help" output should look like this:

rpm --help
...
    --verify               - verify a package installation using the same same
                             package specification options as -q
      --dbpath <dir>       - use <dir> as the directory for the database
...

BUILD DATE & PLATFORM:

        N/A

ADDITIONAL BUILDS AND PLATFORMS:

        N/A

ADDITIONAL INFORMATION: (crash info)

        N/A

UNIX STACK TRACE:

STACK TRACE of original file with format[10] defect:

debug ./rpm --rcfile /tmp/rpmrc --help
New program rpm (process p1) created
debug> stop rpm.c@294
EVENT [1] assigned
debug> run
STOP EVENT TRIGGERED: rpm.c@294  in p1 [printHelpLine() in rpm.c]
294:            sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help),
indentLength);

...
debug> stack
Stack Trace for p1, Program rpm
[3] printHelpLine(prefix="    --verify              ",help="verify a
package installation using the same same package specification options as
-q")     [rpm.c@289]
[2] printHelp() [rpm.c@381]
[1] main(argc=4,argv=0x8047bdc,0x8047bf0)       [rpm.c@1025]
[0] _start()    [0x804b4c1]
debug> print help
"verify a package installation using the same same package specification
options as -q"
debug> print ch
" package specification options as -q"
debug> print format
""
debug> step -o
STEPPED p1 [printHelpLine() in rpm.c]
295:            fprintf(stdout, format, help, " ");
debug> print help
"verify a package installation using the same same package specification
options as -q"
debug> print ch
"n using the same same package specification options as -q"
debug> print format
"%.49s\n%29s..."
debug>


Above debug output, stepping over sprintf()
294:      sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
shows format[10] has been overrun.

SINCE format[10] has been overrun, it has corrupted stack used by sprintf,
and when sprintf returns, you can see the problems above in the
printHelpLine() local variables of "ch" was corrupted and overwritten with
a smaller value in the pointer,
and "format" out of range format[11] and format[12] were corrupted
and thus the format[12] NULL character was overwritten and the format string
is now unbounded.
NOW IT GENERATES UNDEFINED BEHAVIOR, INFINITE LOOP ON IBM NUMA-Q:


STACK TRACE of corrected file, format[10] changed to format[12]:

debug ./rpm --rcfile /tmp/rpmrc --help
New program rpm (process p1) created
debug> stop rpm.c@295
EVENT [1] assigned
debug> run
...
Stack Trace for p1, Program rpm
[3] printHelpLine(prefix="    --verify              ",help="verify a
package installation using the same same package specification options as
-q")     [rpm.c@295]
[2] printHelp() [rpm.c@381]
[1] main(argc=4,argv=0x8047bdc,0x8047bf0)       [rpm.c@1025]
[0] _start()    [0x804b4c1]
debug> print format
"%.49s\n%29s"
debug> run
...

NOW IT IS HAPPY!


SAMPLE PATCH:

IBM patch sequence number: rpm-3.0.6_IBM_patch_006


List of files patched followed by RCS or SCCS ident lines.
==========================================================

rpm.c



Patch to fix the files
======================
*** 1.4 2000/12/14 11:03:50
--- rpm.c       2001/01/16 01:29:42
***************
*** 280,286 ****
      int lineLength = 79 - indentLength;
      int helpLength = strlen(help);
      char * ch;
!     char format[10];

      fprintf(stdout, "%s - ", prefix);

--- 280,286 ----
      int lineLength = 79 - indentLength;
      int helpLength = strlen(help);
      char * ch;
!     char format[12];  /* Large enough to hold format string "%.50s\n%29s" */

      fprintf(stdout, "%s - ", prefix);

Comment 1 Paul Shearer 2001-01-16 06:08:21 UTC
Created attachment 7669 [details]
rpm-3.0.6_IBM_patch_006 Patch File to fix bugzilla 24093 rpm --help problem

Comment 2 Jeff Johnson 2001-01-16 14:34:21 UTC
Fixed in CVS for all of rpm 4.0.1/4.0.2/3.0.7. Thanks for noticing.