Version :
gnuplot-5.2.5
Platform:
Ubuntu 16.04.5
Description:
- There is a format string bug in 'update()' function of src/fit.c If you run gnuplot with the attached PoC file as below, you can observe the following crash raised by a format string bug. (Note that 'touch file' command should be executed first.)
A malicous user may use a crafted input file to perform a memory write operation on arbitrary memory address, and thereby cause a security problem. While this PoC can trigger a format string bug only if 'touch file' is preceded, a more carefully crafted input file may trigger the bug without such a preceding command.
Also, while this PoC file triggers a format string bug by calling 'Eex2()' from src/fit.c:1592, there are some other program points in 'update()' function that seem to have a similar issue.
jason@ubuntu-16:~/gnuplot-5.2.5$ touch file jason@ubuntu-16:~/gnuplot-5.2.5$ gdb -q ./src/gnuplot Reading symbols from ./src/gnuplot...done. (gdb) run ./poc Starting program: /home/jason/gnuplot-5.2.5/src/gnuplot ./poc [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". "./poc", line 1: warning: DEPRECATED command 'update', please use 'save fit' instead "./poc", line 1: Program received signal SIGSEGV, Segmentation fault. 0x00007ffff55a1533 in _IO_vfprintf_internal (s=s@entry=0x7fffffffc920, format=<optimized out>, format@entry=0x7fffffffce60 "new parameter file ,%n%n%%\377\062\377\226\067A7%.S^p\230$\377\214d\341\022C(/ could not be created", ap=ap@entry=0x7fffffffcc80) at vfprintf.c:1631 1631 vfprintf.c: No such file or directory. (gdb) where #0 0x00007ffff55a1533 in _IO_vfprintf_internal (s=s@entry=0x7fffffffc920, format=<optimized out>, format@entry=0x7fffffffce60 "new parameter file ,%n%n%%\377\062\377\226\067A7%.S^p\230$\377\214d\341\022C(/ could not be created", ap=ap@entry=0x7fffffffcc80) at vfprintf.c:1631 #1 0x00007ffff55c8a49 in _IO_vsnprintf (string=0x7fffffffcc00 "new parameter file ,", maxlen=<optimized out>, format=0x7fffffffce60 "new parameter file ,%n%n%%\377\062\377\226\067A7%.S^p\230$\377\214d\341\022C(/ could not be created", args=0x7fffffffcc80) at vsnprintf.c:114 #2 0x0000000000550bc3 in int_error (t_num=-1, str=0x7fffffffce60 "new parameter file ,%n%n%%\377\062\377\226\067A7%.S^p\230$\377\214d\341\022C(/ could not be created") at util.c:1165 #3 0x000000000043418e in error_ex (t_num=-1, str=0x568278 "new parameter file %s could not be created") at fit.c:410 #4 0x00000000004357b6 in update (pfile=0x7f5fd0 "file", npfile=0x7f6020 ",%n%n%%\377\062\377\226\067A7%.S^p\230$\377\214d\341\022C(/") at fit.c:1592 #5 0x000000000041d795 in update_command () at command.c:2490 #6 0x000000000041949d in command () at command.c:629 #7 0x0000000000419249 in do_line () at command.c:419 #8 0x0000000000478732 in load_file (fp=0x7f46e0, name=0x7f2660 "./poc", calltype=4) at misc.c:447 #9 0x0000000000482eb3 in main (argc=1, argv=0x7fffffffe440) at plot.c:654
Analysis:
When 'update()' function calls 'Eex2()' in fit.c:1592, it passes user-controlled string 'ofilename' as an argument.
1591 if (!(nf = fopen(ofilename, "w"))) 1592 Eex2("new parameter file %s could not be created", ofilename);
Then 'Eex2()' internally uses 'ofilename' to construct a format string in 'buf', and passes 'buf' to 'int_error()' as a format string. Therefore, a user-controllable string can be used as a format string in
'int_error()'.
368 void 369 error_ex(int t_num, const char *str, ...) 370 { 371 char buf[128]; 372 va_list args; 373 374 va_start(args, str); 375 vsnprintf(buf, sizeof(buf), str, args); 376 va_end(args); ... 410 int_error(t_num, buf);
Last edit: Jaeseung Choi 2018-11-27
The "update" function no longer exists in tip source