Menu

#1999 global-buffer-overflow bug in do_enh_writec

None
closed-works-for-me
nobody
None
2018-01-10
2017-12-08
No

Hello.

I found a global-buffer-overflow bug in gnuplot.

Please confirm.

Thanks.

OS: CentOS 7
version: gnuplot 5.3 patchlevel 0

=================================================================
==1239==ERROR: AddressSanitizer: global-buffer-overflow on address 0x08b6ebe1 at pc 0x0847225b bp 0xbfca8898 sp 0xbfca888c
WRITE of size 1 at 0x08b6ebe1 thread T0
    #0 0x847225a in do_enh_writec /home/karas/gnuplot-gnuplot-main/src/term.c:2202:26
    #1 0x8473014 in enhanced_recursion /home/karas/gnuplot-gnuplot-main/src/term.c:2275:3
    #2 0x8524d6f in ENHCANVAS_put_text /home/karas/gnuplot-gnuplot-main/src/../term/canvas.trm:1536:20
    #3 0x84656e3 in write_multiline /home/karas/gnuplot-gnuplot-main/src/term.c:792:3
    #4 0x8170a34 in do_key_sample /home/karas/gnuplot-gnuplot-main/src/boundary.c:1170:3
    #5 0x8262c95 in do_plot /home/karas/gnuplot-gnuplot-main/src/graphics.c:704:7
    #6 0x8344322 in eval_plots /home/karas/gnuplot-gnuplot-main/src/plot2d.c:3401:2
    #7 0x818ae75 in plot_command /home/karas/gnuplot-gnuplot-main/src/command.c:1821:5
    #8 0x8180f3a in command /home/karas/gnuplot-gnuplot-main/src/command.c:630:2
    #9 0x8180f3a in do_line /home/karas/gnuplot-gnuplot-main/src/command.c:420
    #10 0x82f5364 in load_file /home/karas/gnuplot-gnuplot-main/src/misc.c:405:10
    #11 0x831bcb2 in main /home/karas/gnuplot-gnuplot-main/src/plot.c:650:3
    #12 0xb7394636 in __libc_start_main /build/glibc-KM3i_a/glibc-2.23/csu/../csu/libc-start.c:291
    #13 0x806a347 in _start (/home/karas/gnuplot-gnuplot-main/src/gnuplot+0x806a347)

0x08b6ebe1 is located 0 bytes to the right of global variable 'enhanced_text' defined in 'term.c:188:7' (0x8b6e7e0) of size 1025
SUMMARY: AddressSanitizer: global-buffer-overflow /home/karas/gnuplot-gnuplot-main/src/term.c:2202:26 in do_enh_writec
Shadow bytes around the buggy address:
  0x2116dd20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x2116dd30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x2116dd40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x2116dd50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x2116dd60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x2116dd70: 00 00 00 00 00 00 00 00 00 00 00 00[01]f9 f9 f9
  0x2116dd80: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x2116dd90: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x2116dda0: 04 f9 f9 f9 f9 f9 f9 f9 00 00 f9 f9 f9 f9 f9 f9
  0x2116ddb0: 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9
  0x2116ddc0: 01 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==1239==ABORTING
1 Attachments

Discussion

  • Ethan Merritt

    Ethan Merritt - 2017-12-08

    Nope.
    I can't reproduce that one, either in gdb or in valgrind.

     
    • Gwan Yeong Kim

      Gwan Yeong Kim - 2017-12-08

      I'm sorry I took your time.

      No error occurs in a clean environment.

      Thanks.

       
  • Ethan Merritt

    Ethan Merritt - 2017-12-20
    • status: open --> closed-works-for-me
    • Group: -->
    • Priority: -->
     
    • Gwan Yeong Kim

      Gwan Yeong Kim - 2018-01-10

      Hello,

      I will reproduce this problem.

      Can you check again?

      I uploaded the docker file.

      Thanks.

      ==18165== Invalid write of size 1
      ==18165==    at 0x48324B6: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
      ==18165==    by 0x1DD925: CANVAS_put_text (canvas.trm:1070)
      ==18165==    by 0x1DED8C: ENHCANVAS_put_text (canvas.trm:1516)
      ==18165==    by 0x1DEF93: ENHCANVAS_put_text (canvas.trm:1557)
      ==18165==    by 0x1D881B: write_multiline (term.c:793)
      ==18165==    by 0x11C077: do_key_sample (boundary.c:1164)
      ==18165==    by 0x153F2C: do_plot (graphics.c:715)
      ==18165==    by 0x193575: eval_plots (plot2d.c:3401)
      ==18165==    by 0x184FB4: plotrequest (plot2d.c:290)
      ==18165==    by 0x122A78: plot_command (command.c:1822)
      ==18165==    by 0x120577: command (command.c:631)
      ==18165==    by 0x11FD46: do_line (command.c:420)
      ==18165==  Address 0x290000 is not stack'd, malloc'd or (recently) free'd
      ==18165== 
      ==18165== 
      ==18165== Process terminating with default action of signal 11 (SIGSEGV): dumping core
      ==18165==  Access not within mapped region at address 0x290000
      ==18165==    at 0x48324B6: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
      ==18165==    by 0x1DD925: CANVAS_put_text (canvas.trm:1070)
      ==18165==    by 0x1DED8C: ENHCANVAS_put_text (canvas.trm:1516)
      ==18165==    by 0x1DEF93: ENHCANVAS_put_text (canvas.trm:1557)
      ==18165==    by 0x1D881B: write_multiline (term.c:793)
      ==18165==    by 0x11C077: do_key_sample (boundary.c:1164)
      ==18165==    by 0x153F2C: do_plot (graphics.c:715)
      ==18165==    by 0x193575: eval_plots (plot2d.c:3401)
      ==18165==    by 0x184FB4: plotrequest (plot2d.c:290)
      ==18165==    by 0x122A78: plot_command (command.c:1822)
      ==18165==    by 0x120577: command (command.c:631)
      ==18165==    by 0x11FD46: do_line (command.c:420)
      
      (gdb) by full
      Undefined command: "by".  Try "help".
      (gdb) bt full
      #0  __strlen_ia32 () at ../sysdeps/i386/i686/multiarch/../../i586/strlen.S:51
      No locals.
      #1  0xb7d1df60 in _IO_vfprintf_internal (s=0xb7ea5d80 <_IO_2_1_stdout_>, 
          format=0x80145d66 "} // End %s_plot_%d \n", 
          ap=0xbffff1fc "\216\216\216\216 \317\030\200\220=\027\200\370\362\377\277\216\216\216\216 \317\030\200\220=\027\200\370\362\377\277\300\310\004\200\t")
          at vfprintf.c:1643
              len = <optimized out>
              string_malloced = 0
              string = 0x8e8e8e8e <error: Cannot access memory at address 0x8e8e8e8e>
              width = 0
              is_short = 0
              spec = 115 's'
              step0_jumps = {0, -1821, 509, 593, -884, 865, 684, -1667, 344, -1440, 
                -1328, 267, -3730, -3814, -2668, -2616, -1767, 970, -800, -785, 
                -2984, -496, -967, 37, 131, -3643, -1244, -3814, -3730, 781}
              base = <optimized out>
              pad = 32 ' '
              step1_jumps = {0, 0, 0, 0, 0, 0, 0, 0, 0, -1440, -1328, 267, -3730, 
                -3814, -2668, -2616, -1767, 970, -800, -785, -2984, -496, -967, 37, 
                131, -3643, -1244, -3814, -3730, 0}
              is_negative = <optimized out>
              use_outdigits = 0
      ---Type <return> to continue, or q <return> to quit---
              step2_jumps = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1328, 267, -3730, -3814, 
                -2668, -2616, -1767, 970, -800, -785, -2984, -496, -967, 37, 131, 
                -3643, -1244, -3814, -3730, 0}
              alt = 0
              left = 0
              showsign = 0
              group = 0
              is_char = <optimized out>
              step3a_jumps = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 0, 0, 0, -2668, 
                -2616, -1767, 970, -800, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0}
              the_arg = {pa_wchar = -1209377408 L'\xb7ea5d80', pa_int = -1209377408, 
                pa_long_int = -1209377408, pa_long_long_int = 3085589888, 
                pa_u_int = 3085589888, pa_u_long_int = 3085589888, 
                pa_u_long_long_int = 3085589888, 
                pa_double = 1.5244839608159396e-314, 
                pa_long_double = 1.1247590815318897237978468581535281e-4941, 
                pa_string = 0xb7ea5d80 <_IO_2_1_stdout_> "\204*\255\373\300\326\030\200\300\326\030\200\300\326\030\200\300\326\030\200\311\326\030\200\300\326\030\200\300\326\030\200\300\332\030\200", 
                pa_wstring = 0xb7ea5d80 <_IO_2_1_stdout_> L"\xfbad2a84\x8018d6c0\x8018d6c0\x8018d6c0\x8018d6c0\x8018d6c9\x8018d6c0\x8018d6c0\x8018dac0", 
                pa_pointer = 0xb7ea5d80 <_IO_2_1_stdout_>, 
                pa_user = 0xb7ea5d80 <_IO_2_1_stdout_>}
      ---Type <return> to continue, or q <return> to quit---
              space = 0
              is_long_double = 0
              is_long = <optimized out>
              step3b_jumps = {0 <repeats 11 times>, -3730, 0, 0, -2668, -2616, 
                -1767, 970, -800, -785, -2984, -496, -967, 37, 131, -3643, -1244, 0, 
                0, 0}
              step4_jumps = {0 <repeats 14 times>, -2668, -2616, -1767, 970, -800, 
                -785, -2984, -496, -967, 37, 131, -3643, -1244, 0, 0, 0}
              prec = -1
              _buffer = {__routine = 0xb7d36e40 <__funlockfile>, 
                __arg = 0xb7ea5d80 <_IO_2_1_stdout_>, __canceltype = -2145960560, 
                __prev = 0x0}
              _avail = <optimized out>
              thousands_sep = 0x0
              grouping = 0xffffffff <error: Cannot access memory at address 0xffffffff>
              done = 9
              f = 0x80145d70 "s_plot_%d \n"
              lead_str_end = 0x80145d6f "%s_plot_%d \n"
              end_of_spec = <optimized out>
              work_buffer = "\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\220=\027\200h\356\377\277\222\276\021\200\000\000\000\000\000\000\000\000\177\003\000\000\000\000\360?", '\000' <repeats 14 times>, "$@\001\000\000\000V---Type <return> to continue, or q <return> to quit---
      9\024\200\000\000\000\000\321\373\031\200\340\f\030\200\001\000\000\000\000\000\000\000\376g\r\200\000\000\000\000\000\000\000\000\022\000\000\000\000HP`\220=\027\200\000\000\000\000\230\356\377\277\351l\r\200\000\000\000\000\000\000\000\000x\340\234\021\372i\r\200\220=\027\200#g\r\200\000\357\377\277\000HP`\220=\027\200\000\000\000\000(\357\377\277P\272\021\200\262\373\031\200\000\000\000\000V9\024\200\000\000\000\000\000\000$@\000\000\000\000\000\000\000\000"...
              workstart = 0x0
              workend = 0xbffff1ac ""
              ap_save = 0xbffff1f8 "\216\216\216\216\216\216\216\216 \317\030\200\220=\027\200\370\362\377\277\216\216\216\216 \317\030\200\220=\027\200\370\362\377\277\300\310\004\200\t"
              nspecs_done = <optimized out>
              save_errno = 0
              readonly_format = 0
              __PRETTY_FUNCTION__ = "_IO_vfprintf_internal"
      #2  0xb7d241b8 in __fprintf (stream=0xb7ea5d80 <_IO_2_1_stdout_>, 
          format=0x80145d66 "} // End %s_plot_%d \n") at fprintf.c:32
              arg = 0xbffff1f8 "\216\216\216\216\216\216\216\216 \317\030\200\220=\027\200\370\362\377\277\216\216\216\216 \317\030\200\220=\027\200\370\362\377\277\300\310\004\200\t"
              done = -1903260018
      #3  0x800d64d8 in CANVAS_layer (layer=TERM_LAYER_AFTER_PLOT)
          at ../term/canvas.trm:1302
      ---Type <return> to continue, or q <return> to quit---
              basename = 0x8e8e8e8e <error: Cannot access memory at address 0x8e8e8e8e>
      #4  0x8004c8c0 in do_plot (plots=0x80188290, pcount=1) at graphics.c:920
              localkey = true
              t = 0x8017b384 <term_tbl+900>
              curve = 0
              this_plot = 0x80188290
              xl = 1609599
              yl = 3736
              key_count = 0
              key_pass = false
              key = 0x80174d20 <keyT>
              previous_plot_style = 0
      #5  0x8008b576 in eval_plots () at plot2d.c:3401
              i = 100
              this_plot = 0x0
              tp_ptr = 0x80188290
              uses_axis = {(USES_AXIS_FOR_DATA | unknown: 3221222808), 
                USES_AXIS_FOR_FUNC, USES_AXIS_FOR_FUNC, (unknown: 2149006736), 
                (unknown: 2149089904), (unknown: 0), (unknown: 0), 
                (USES_AXIS_FOR_DATA | unknown: 3221222808), (unknown: 16), 
                (unknown: 3085586432), (unknown: 2148677300)}
              some_functions = true
      ---Type <return> to continue, or q <return> to quit---
              some_tables = false
              plot_num = 1
              line_num = 1
              was_definition = false
              pattern_num = 0
              xtitle = 0x0
              begin_token = 1
              start_token = 1
              end_token = 3
              key = 0x80174d20 <keyT>
              orig_dummy_var = "x\000ot\000\n\200\000\000\000\000\220=\027\200\330\365\377\277c\331\000\200\001\000\000\000D\375\022\200\225\214\317\267*\331\000\200\037,\022\200tZ\030\200\000\000\000"
              nbins = 0
              binlow = 0
              binhigh = 0
              binwidth = 0
              newhist_start = 0
              histogram_sequence = -1
              newhist_color = 1
              newhist_pattern = -5
      #6  0x8007cfb5 in plotrequest () at plot2d.c:290
              dummy_token = 0
      ---Type <return> to continue, or q <return> to quit---
              axis = PARALLEL_AXES
      #7  0x8001aa79 in plot_command () at command.c:1822
      No locals.
      #8  0x80018578 in command () at command.c:631
              i = 12
      #9  0x80017d47 in do_line () at command.c:420
              inlptr = 0x8018f4d0 "plot 9-3t\"egMJt\206t \257\357 r\257\257\257\257u\351\351\351\351\351\324\351\351|ermin&&aa&&\257\257\257\264a&min&&aa&&\257\257\235\235\235\235\235\235\235\235\235\235n\235\235&\257\257\257\244\232a", 'D' <repeats 116 times>...
      #10 0x80072514 in load_file (fp=0x8018cdc0, name=0x8018cf20 "do_enh_writec", 
          calltype=4) at misc.c:405
              len = 25946
              start = 25947
              left = 2725
              more = 0
              stop = 1
              gpval_lineno = 0x8018c870
      #11 0x8007bf90 in main (argc=1, argv=0xbffff7b8) at plot.c:652
              i = 1
      
       
  • Ethan Merritt

    Ethan Merritt - 2018-01-10

    The script file "do_enh_writec" tries to feed a 36 kbyte quoted string of binary garbage via the command line. In other words, this is not a failure mode that you could reasonably trigger interactively or from a script that was working half-way reasonably. Notice that the failure showing in the dump you provide is inside a system-specific library support routine that implements the C language library call strlen()
    __strlen_ia32 () at ../sysdeps/i386/i686/multiarch/../../i586/strlen.S:51

    I think gnuplot is an innocent victim here.
    If you are generating these failure cases using a fuzzer, I suggest that you only allow it to generate valid ascii (or utf8) input, not random binary junk. That's where the interesting failure modes lie.

     
    • Gwan Yeong Kim

      Gwan Yeong Kim - 2018-01-10

      Thank you for your reply.

      fuzzing is difficult to create valid inputs by entering random data.

      Happy New Year. :)

       

Log in to post a comment.

MongoDB Logo MongoDB