Version:
gnuplot 5.2 patchlevel 5
Description:
Calling tm_min with a high number cause an out-of-bounds read in ggmtime.
Steps to reproduce (payload is attached):
#Build gnuplot with ASAN
LIBS='-ldl -lasan' CFLAGS="-g -fsanitize=address -fno-omit-frame-pointer -DDEBUG -fno-stack-protector" ./configure && make -j8
gnuplot <payload>
ASAN-Report:
-------- STDERR --------
"/tmp/tmpz6ejmz84/6b8b424540630652", line 1: warning: Cannot find or open file "�"
=================================================================
==13000==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55bf5d389ab0 at pc 0x55bf5d1b8a5b bp 0x7ffc79b94840 sp 0x7ffc79b94830
READ of size 4 at 0x55bf5d389ab0 thread T0
#0 0x55bf5d1b8a5a in ggmtime /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/time.c:810
#1 0x55bf5d0f5646 in f_tmmin /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/standard.c:1150
#2 0x55bf5cf39d72 in execute_at /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/eval.c:679
#3 0x55bf5cf39eed in evaluate_at /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/eval.c:707
#4 0x55bf5d04a6f9 in eval_plots /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/plot2d.c:3133
#5 0x55bf5d027048 in plotrequest /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/plot2d.c:301
#6 0x55bf5cf0a106 in plot_command /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/command.c:1849
#7 0x55bf5cf0560d in command /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/command.c:629
#8 0x55bf5cf044fe in do_line /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/command.c:419
#9 0x55bf5cff5f22 in load_file /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/misc.c:447
#10 0x55bf5d024de7 in main /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/plot.c:654
#11 0x7f6405f65222 in __libc_start_main (/usr/lib/libc.so.6+0x24222)
#12 0x55bf5ced90ed in _start (/home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/gnuplot+0xf20ed)
0x55bf5d389ab0 is located 0 bytes to the right of global variable 'mndday' defined in 'time.c:75:12' (0x55bf5d389a80) of size 48
SUMMARY: AddressSanitizer: global-buffer-overflow /home/nils/git/gnuplot-crash-triage/gnuplot-5.2.5/src/time.c:810 in ggmtime
Shadow bytes around the buggy address:
0x0ab86ba69300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ab86ba69310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ab86ba69320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ab86ba69330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ab86ba69340: 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9
=>0x0ab86ba69350: 00 00 00 00 00 00[f9]f9 f9 f9 f9 f9 00 00 00 00
0x0ab86ba69360: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0ab86ba69370: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0ab86ba69380: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0ab86ba69390: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0ab86ba693a0: f9 f9 f9 f9 f9 f9 f9 f9 f9 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
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
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
==13000==ABORTING
-------- STDOUT --------
Credits:
Tim Blazytko
Cornelius Aschermann
Sergej Schumilo
Nils Bars
Diff:
Insufficient context to reproduce.
The command line provided as a reproducer refers to a variable "x" whose value is not known. Assigning trivial values to x (e.g. x=0 x=1 x=1.e4) produces at worst a warning "time value out of range".
You need to compile gnuplot with ASAN enabled. I updated the reproduction steps.
I dont know why this is working without defining x, but it does.
Just execute gnuplot (with ASAN enabled) with the provided payload.
Diff:
Got it. Wow, this is an interesting one. The test case triggers a flaw in the time algorithm where round-off error causes a date to be assigned to the wrong year (think 2 nanoseconds before midnight on 31 Dec). Then when it drills down to assign month/day/hour/etc the rounding goes the other way and it is assigned to the first second of the 13th month of last year rather than the 1st month of this year. ASAN per se didn't help much, but your build instructions turned on verbose DEBUG output and inspecting the dump of intermediate date calculations showed what was happening.
Fixes coming.
Thanks.