Bug #58497 | mysql client crashes due to unitialized string buffer in term.c | ||
---|---|---|---|
Submitted: | 25 Nov 2010 15:38 | Modified: | 21 Mar 2012 19:06 |
Reporter: | Werner Ott | Email Updates: | |
Status: | Can't repeat | Impact on me: | |
Category: | MySQL Server: Compiling | Severity: | S1 (Critical) |
Version: | 5.1.53 | OS: | Linux |
Assigned to: | CPU Architecture: | Any | |
Tags: | segfault |
[25 Nov 2010 15:38]
Werner Ott
[27 Nov 2010 13:23]
Sveta Smirnova
Thank you for the report. I can not repeat described behavior. Please try with current version 5.1.53 and if problem still exists try with newer version of gcc and inform us about results.
[7 Dec 2010 9:31]
Werner Ott
Retried on openSUSE 11.0 and 11.1 x86_64 using (*) gcc 4.4.5 (*) mysql 5.1.53 still showed the same result. mysql client program crashes (segfault) as soon as it connects to any MySQL 5.0 or 5.1 server.
[7 Dec 2010 10:19]
Werner Ott
Introduction: ------------- Already filed for 5.1.35, this bug still is in 5.1.53! This error, as opposed to what I've written earlier, has NOTHING to do with the compiler version used. It is an How to reproduce: ----------------- This segfault is caused by the use of an unitialized buffer in ./cmd-line-utils/libedit/term.c The content of this buffer is arbitrary (as it isn't initialized) and may thus be non-reproducable in other environments. "Stack trace" in term.c: ------------------------ 904: buf = array[2048]; 914: area = pointer to buf; // buf still uninitalized! 959: term_alloc(..., area); 400: clen = strlen(cap); // unpredictable! 407: strcpy unitialized buffer to other buffer // segfaults! How to fix: ----------- (Credits go to Bart Kedryna, see Bug 45562) Since function term_set() allocates a char buffer which it doesn't do anything with, it contains possibly junk. This potentially junk containing buffer is passed to function term_alloc(). Function term_alloc() then tries to read the contents of this pointer and is segfaulting. Since this buffer is not even initialized, it doesn't contain anything useful, and since it's passed to term_alloc() as const, it can't be written to by term_alloc(). The fix is to completely comment it out (line 904) and set the area pointer to NULL instead of buf (in line 914): 904:// char buf[TC_BUFSIZE]; 914: area = NULL;
[14 Dec 2010 19:15]
Sveta Smirnova
Thank you for the feedback. Please send output of command \s of mysql command line client.
[15 Jan 2011 0:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".
[19 Mar 2012 2:13]
Eric Batchelor
Just wanted to comment I ran across this in version 5.1.61, and a fix that worked for me. As best I can tell it's the same problem. I'm using Ubuntu 10.04.4 LTS, 64 bit version. GCC 4.4.3 I ran ./configure, it balked about a terminal library. I installed the package libncursesw5-dev, thinking I might want wide-char support, and compilation succeeded, but the resultant mysql bin segfaulted. I think it's simply a package problem where the proper curses header files were not being included and this was not detected by the configure script. The following compile warnings hint at the cause of the segfault: terminal.c: In function ‘terminal_set’: terminal.c:925: warning: passing argument 3 of ‘terminal_alloc’ makes pointer from integer without a cast terminal.c:327: note: expected ‘const char *’ but argument is of type ‘int’ The relevant code: terminal_alloc(el, t, tgetstr(strchr(t->name, *t->name), &area) ); (This code is valid, btw, notice that &area is being passed to tgetstr, not terminal_alloc. It's fine if area=buf points to an unitinalized area.) tgetstr is supposed to return a char*, NOT an int, so clearly something is wrong, like a missing header file. Using a 32 bit int as a 64 bit address of course is completely bogus and generates an invalid address which causes a segfault. The generated assembler code is movslq %eax,%rdx which sign extends the top bit of 32 bit eax register to 64 bit rdx, which is not at all what we want. What fixed it for me: I uninstalled libncursesw5-dev and installed libncurses5-dev (non-wide char), ./configure, make, and the resultant mysql binary executes fine. No warnings were generated for the same section of code, and stepping through with a debugger confirmed that the return value of tgetstr was being interpreted as a 64 bit address, not a 32 bit int.
[19 Mar 2012 21:47]
Sveta Smirnova
Eric, thank you for the feedback. I can not repeat described behavior with libncursesw as well. Please send full configuration line you use. Do you link with static or dynamic curses library?
[21 Mar 2012 5:51]
Eric Batchelor
My configure line was simply ./configure with no additional arguments. I believe it is dynamically linked. ldd shows for curses: libncursesw.so.5 => /lib/libncursesw.so.5 (0x00007fa824e82000)
[21 Mar 2012 19:06]
Sveta Smirnova
Thank you for the feedback. I still can not repeat described behavior. So closing report as "Can't repeat". As problem seems to be ncurses library workaround can be use different version of the library.
[27 Aug 2012 21:55]
Xun Tang
I have experienced the same crash. When I run the cmake command like below, The HAVE_CURSES_H is not defined and curses.h is not included in terminal.c. Then the built bin/mysql will crash. I have to explicitly define HAVE_CURSES_H. I can't find where the configure is broken. cmake . -DCURSES_LIBRARY=/usr/lib64/libcurses.so.1 -DCURSES_INCLUDE_PATH=/usr/include/curses/
[3 Sep 2012 17:35]
Sveta Smirnova
Xun Tang, thank you for the feedback. I still can not repeat this issue with ncurses 5.7 Looks like version matters.