Menu

#2011 sprintf double percent %% heap corruption with long strings

None
closed-fixed
nobody
sprintf (2)
2018-04-28
2018-01-20
No

I was using gnuplot do some system calls, and then discovered this issue.

When I use sprintf to create a "long" string (greater than 260 chars), and it has double percents (%%), gnuplot will crash (I am using Xubuntu 16.04).

If I substitute the %% by the respective formatting string (i.e. by inserting %s in the string, and "%" as argument of sprintf), there will be no issue.

I am providing a simple script which triggers the issue in my system.

1 Attachments

Discussion

  • Rafael C. Barreto

    I will copy and paste the script here to make it easier.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    #!/usr/bin/gnuplot
    
    # Try to run the following script
    # Then uncomment the WARNING part
    
    Ni = 6
    static_string_short = "a[0]=-1.062438e-01; a[1]=9.572160e-02; a[2]=8.094381e-02; a[3]=5.064067e-01; a[4]=-7.579121e-01; "
    static_string = "a[0]=-1.062438e-01; a[1]=9.572160e-02; a[2]=8.094381e-02; a[3]=5.064067e-01; a[4]=-7.579121e-01; a[5]=-2.123451e-02;"
    file1="file1.txt"
    file2="file2.txt"
    
    #########
    # The string itself has no issue
    #########
    print "awk 'BEGIN {  a[0]=-1.062438e-01; a[1]=9.572160e-02; a[2]=8.094381e-02; a[3]=5.064067e-01; a[4]=-7.579121e-01; a[5]=-2.123451e-02; bs=9; printf (\"#offsets\"); } NR%9<2 || NR%9==8 {print} NR%9>1 && NR%9<8 {printf (\"%f %d %f %f\\n\",$1,$2,$3-a[int(NR/9)],$4) }' file1.txt > file2.txt\n"
    
    #########
    # Also, these sprintfs have no issues (changing %% by %s and "%")
    #########
    print sprintf("awk 'BEGIN {%s bs=%d; printf (\"#offsets\"); } NR%s9<2 || NR%s9==8 {print} NR%s9>1 && NR%s9<8 {printf (\"%sf %sd %sf %sf\\n\",$1,$2,$3-a[int(NR/9)],$4) }' %s > %s\n", static_string, Ni+3, "%", "%", "%", "%", "%", "%", "%", "%", file1, file2)
    
    a = sprintf("awk 'BEGIN {%s bs=%d; printf (\"#offsets\"); } NR%s9<2 || NR%s9==8 {print} NR%s9>1 && NR%s9<8 {printf (\"%sf %sd %sf %sf\\n\",$1,$2,$3-a[int(NR/9)],$4) }' %s > %s\n", static_string, Ni+3, "%", "%", "%", "%", "%", "%", "%", "%", file1, file2)
    
    #########
    # A shorter string also has no issues
    #########
    print sprintf("awk 'BEGIN {%s bs=%d; printf (\"#offsets\"); } NR%%9<2 || NR%%9==8 {print} NR%%9>1 && NR%%9<8 {printf (\"%%f %%d %%f %%f\\n\",$1,$2,$3-a[int(NR/9)],$4) }' %s > %s\n", static_string_short, Ni+3, file1, file2)
    
    b = sprintf("awk 'BEGIN {%s bs=%d; printf (\"#offsets\"); } NR%%9<2 || NR%%9==8 {print} NR%%9>1 && NR%%9<8 {printf (\"%%f %%d %%f %%f\\n\",$1,$2,$3-a[int(NR/9)],$4) }' %s > %s\n", static_string_short, Ni+3, file1, file2)
    
    ######### WARNING
    # These sprintfs will crash
    ######### 
    # print sprintf("awk 'BEGIN {%s bs=%d; printf (\"#offsets\"); } NR%%9<2 || NR%%9==8 {print} NR%%9>1 && NR%%9<8 {printf (\"%%f %%d %%f %%f\\n\",$1,$2,$3-a[int(NR/9)],$4) }' %s > %s\n", static_string, Ni+3, file1, file2)
    
    # c = sprintf("awk 'BEGIN {%s bs=%d; printf (\"#offsets\"); } NR%%9<2 || NR%%9==8 {print} NR%%9>1 && NR%%9<8 {printf (\"%%f %%d %%f %%f\\n\",$1,$2,$3-a[int(NR/9)],$4) }' %s > %s\n", static_string, Ni+3, file1, file2)
    
    # print sprintf("awk 'BEGIN {%s bs=%d; printf (\"#offsets\"); } NR%%%%9<2 || NR%%%%9==8 {print} NR%%%%9>1 && NR%%%%9<8 {printf (\"%%%%f %%%%d %%%%f %%%%f\\n\",$1,$2,$3-a[int(NR/9)],$4) }' %s > %s\n", static_string, Ni+3, file1, file2)
    
    #########
    # it procuces the following Error at my computer
    
    # *** Error in `gnuplot': realloc(): invalid next size: 0x0000000000d71360 ***
    # ======= Backtrace: =========
    # /lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f35242757e5]
    # /lib/x86_64-linux-gnu/libc.so.6(+0x834aa)[0x7f35242814aa]
    # /lib/x86_64-linux-gnu/libc.so.6(realloc+0x179)[0x7f3524282839]
    # gnuplot[0x41ae91]
    # gnuplot[0x460afe]
    # gnuplot[0x437a4d]
    # gnuplot[0x437b09]
    # gnuplot[0x4732b2]
    # gnuplot[0x4288b4]
    # gnuplot[0x42a627]
    # gnuplot[0x466a4d]
    # gnuplot[0x419c0c]
    # /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f352421e830]
    # gnuplot[0x41ad79]
    # ======= Memory map: ========
    # 00400000-0058b000 r-xp 00000000 08:01 2511991                            /usr/bin/gnuplot5-qt
    # 0078a000-0078f000 r--p 0018a000 08:01 2511991                            /usr/bin/gnuplot5-qt
    # 0078f000-0079f000 rw-p 0018f000 08:01 2511991                            /usr/bin/gnuplot5-qt
    # 0079f000-007b0000 rw-p 00000000 00:00 0 
    # 00d11000-00d74000 rw-p 00000000 00:00 0                                  [heap]
    # 7f3514000000-7f3514021000 rw-p 00000000 00:00 0 
    # 7f3514021000-7f3518000000 ---p 00000000 00:00 0 
    # 7f35192ac000-7f35192ae000 r-xp 00000000 08:01 2644187                    /usr/lib/x86_64-linux-gnu/gconv/UTF-32.so
    # ** long list of dynamic libraries **
    
    # $ uname -a
    # Linux hel 4.4.0-104-generic #127-Ubuntu SMP Mon Dec 11 12:16:42 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
    
    # $ gnuplot --version
    # gnuplot 5.0 patchlevel 3
    
     

    Last edit: Rafael C. Barreto 2018-01-20
  • Rafael C. Barreto

    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -2,6 +2,6 @@
    
     When I use sprintf to create a "long" string (greater than 260 chars), and it has double percents (%%), gnuplot will crash (I am using Xubuntu 16.04).
    
    -If I substitute the %% by the respective formatting string (i.e. by inserting %s in the string, and "%%" as argument of sprintf), there will be no issue.
    +If I substitute the %% by the respective formatting string (i.e. by inserting %s in the string, and "%" as argument of sprintf), there will be no issue.
    
     I am providing a simple script which triggers the issue in my system.
    
    • Group: -->
    • Priority: -->
     
  • Ethan Merritt

    Ethan Merritt - 2018-01-21

    Thank you for the report and the test case.
    Fixed now for 5.2 and 5.3

    If you really need a fix for 5.0, the patch below prepared for 5.2 may work but I have not tested it.

     
  • Ethan Merritt

    Ethan Merritt - 2018-01-21
    • status: open --> pending-fixed
     
  • Rafael C. Barreto

    Thank you for the fast fix!
    I downloaded the code from the repository, compiled, and it worked fine in my box.

    I did not test with the 5.0 sources.... but I do not think it is really necessary.

    For now, to avoid the issue in the xubuntu 16.04 pre-compiled binaries, I am explicitly printing the percent symbol.

    print sprint(" some text %s foo bar ", "%")

    Best regards and keep up the good work!

     
  • Ethan Merritt

    Ethan Merritt - 2018-04-28
    • Status: pending-fixed --> closed-fixed
     

Log in to post a comment.