Re: buffer overflows in MySQL error messages (e.g. in 4.0.10-gamma)
Sergei Golubchik wrote: Though your changes looked innocent - that is they most probably could do no harm - I failed to understand when they'll do any good. You replaced a set of checks for buffer overflow by some other set of checks, which looked equivalent to the old one. Hi, it turns out that my original problem was completely due to the bug in MyODBC 3.51.05: MySQL immediately truncated my very long key name, thereby avoiding any buffer overflows in MySQL code. However, as I already indicated in my previous message, I _did_ find potential issues with those MySQL files for which I provided patches. The issues may be improbable, but now that we know them, we should rather fix them once and for all. Here you have some clarifications about the patches I provided: mysys/my_error.c - my_error() can overflow buffer when the error format message length exceeds ERRMSGSIZE+20; my_printf_error() must not use the unsafe vsprintf(), but the safe my_vsnprintf(). mysys/my_vsnprintf.c - my_vsnprintf() must reserve 20 bytes of temp. space instead of 16, to format a decimal integer up to 2^64; if it uses a temporary array for that, instead of the error message buffer itself, a narrow number can still fit just before the end of the error buffer (now the code requires enough space to fit a wide number). sql/handler.cc- print_error() would fail if strlen(ER(ER_DUP_ENTRY)) is larger than MYSQL_ERRMSG_SIZE. sql/net_pkg.cc- send_ok() assumes that the message will fit in the error buffer. sql/sql_table.cc - mysql_admin_table() should use safe my_snprintf() instead of unsafe sprintf(). Thanks, Maarten - Before posting, please check: http://www.mysql.com/manual.php (the manual) http://lists.mysql.com/ (the list archive) To request this thread, e-mail [EMAIL PROTECTED] To unsubscribe, e-mail [EMAIL PROTECTED] Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php
Re: buffer overflows in MySQL error messages (e.g. in 4.0.10-gamma)
Sergei Golubchik wrote: Ok, I took a look at this. (btw, this was not a diff at all, but rather tarball of new and old files. Having a real unified diff would make your changes MUCH easier to understand). Hi, I did not want to force a particular diff format on the reader; having the original and the new sources, one can run diff with any options desired... Though your changes looked innocent - that is they most probably could do no harm - I failed to understand when they'll do any good. You replaced a set of checks for buffer overflow by some other set of checks, which looked equivalent to the old one. Please, show at least one single test case where old code gets buffer overflow. First of all I must _apologize_ that in my bug report I _mixed_ remarks about the behavior of MySQL with those for MyODBC: it is in fact MyODBC which evidently does not do any overflow checks for error messages! MyODBC version 3.51.06 uses a buffer twice the original size, which in practice probably is enough to avoid the problem, though it _still_ does not do explicit checks (I have reported that). MySQL _does_ check for overflows, but _not_ 100% correctly... I will try to reproduce the problem that I observed a few weeks ago, but I will show you one problem right now. Look in mysys/my_error.c: - char ebuff[ERRMSGSIZE+20]; /* ... */ olen=(uint) strlen(tpos=my_errmsg[nr / ERRMOD][nr % ERRMOD]); endpos=ebuff; while (*tpos) { if (tpos[0] != '%') { *endpos++= *tpos++; /* Copy ordinary char */ olen++; continue; } - Now what if olen = ERRMSGSIZE+20 i.e. olen = 276? Then the above code could overflow the buffer. It would be ridiculous if an error message were that long, right? Well, the longest message in sql/share/romanian/errmsg.txt is _318_ characters long... Regards, Maarten - Before posting, please check: http://www.mysql.com/manual.php (the manual) http://lists.mysql.com/ (the list archive) To request this thread, e-mail [EMAIL PROTECTED] To unsubscribe, e-mail [EMAIL PROTECTED] Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php
Re: buffer overflows in MySQL error messages (e.g. in 4.0.10-gamma)
Hi! On Mar 14, Maarten LITMAATH wrote: Sergei Golubchik wrote: On Mar 12, Maarten LITMAATH wrote: Description: MySQL (e.g. version 4.0.10-gamma) does not check for buffer overflows when formatting error messages: the code just assumes that no message will ever be larger than SC_MAXWIDTH (256), ERRMSGSIZE (SC_MAXWIDTH) or MYSQL_ERRMSG_SIZE (200). This has been observed to lead to memory corruption when the client e.g. tries to redefine a key with a name whose length is of order 200 (yes, that _is_ a realistic use case for computer-handled keys). Nope. Fails for me. Error message gets truncated, no overflow. OK, let me give a bit more information. I am using MySQL through a server (the Globus RLS, if you care about that), which does all the SQL statements. I did some stress testing of that server, trying to break it, e.g. by supplying ridiculously long names for keys, which caused it to corrupt its own memory and/or crash. Debugging that, I ultimately came to the MySQL client code that it uses, and found that it _evidently_ does not check for overflows in error messages. In the debugger I clearly saw the code scribbling beyond the end of an error message buffer, overwriting adjacent fields in some struct. I then patched various routines dealing with error messages (also in MyODBC) and my problem went away. I got truncated error messages too, but _after_ they had overflowed... Furthermore, whenever such overflow happens, the damage depends on the layout of the data segment or stack, so your program may survive, or _seem_ to survive, having corrupted its own memory. Please download the diffs and have a look at them: http://litmaath.home.cern.ch/litmaath/MyODBC-MySQL-patches/mysql-4.0.10-gamma-ml-diffs.tgz Ok, I took a look at this. (btw, this was not a diff at all, but rather tarball of new and old files. Having a real unified diff would make your changes MUCH easier to understand). Though your changes looked innocent - that is they most probably could do no harm - I failed to understand when they'll do any good. You replaced a set of checks for buffer overflow by some other set of checks, which looked equivalent to the old one. Please, show at least one single test case where old code gets buffer overflow. Regards, Sergei -- MySQL Development Team __ ___ ___ __ / |/ /_ __/ __/ __ \/ / Sergei Golubchik [EMAIL PROTECTED] / /|_/ / // /\ \/ /_/ / /__ MySQL AB, http://www.mysql.com/ /_/ /_/\_, /___/\___\_\___/ Osnabrueck, Germany ___/ - Before posting, please check: http://www.mysql.com/manual.php (the manual) http://lists.mysql.com/ (the list archive) To request this thread, e-mail [EMAIL PROTECTED] To unsubscribe, e-mail [EMAIL PROTECTED] Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php
Re: buffer overflows in MySQL error messages (e.g. in 4.0.10-gamma)
Hi! On Mar 12, Maarten LITMAATH wrote: Description: MySQL (e.g. version 4.0.10-gamma) does not check for buffer overflows when formatting error messages: the code just assumes that no message will ever be larger than SC_MAXWIDTH (256), ERRMSGSIZE (SC_MAXWIDTH) or MYSQL_ERRMSG_SIZE (200). This has been observed to lead to memory corruption when the client e.g. tries to redefine a key with a name whose length is of order 200 (yes, that _is_ a realistic use case for computer-handled keys). How-To-Repeat: Define a key with a length of ~200 or more (the longer, the better) and then try to redefine it; observe the client getting an error message that is truncated and/or has trailing garbage. The client and/or the server may then have corrupted their own memories to such an extent that they become unusable and/or crash (both have been observed at least in a client application). Nope. Fails for me. mysql create table aa (bb int, key ccc(bb)); ERROR 1059: Identifier name 'ccc' is too long mysql create table aa (bb int, key c(bb)); ERROR 1059: Identifier name 'cc Error message gets truncated, no overflow. Sergei -- MySQL Development Team __ ___ ___ __ / |/ /_ __/ __/ __ \/ / Sergei Golubchik [EMAIL PROTECTED] / /|_/ / // /\ \/ /_/ / /__ MySQL AB, http://www.mysql.com/ /_/ /_/\_, /___/\___\_\___/ Osnabrueck, Germany ___/ - Before posting, please check: http://www.mysql.com/manual.php (the manual) http://lists.mysql.com/ (the list archive) To request this thread, e-mail [EMAIL PROTECTED] To unsubscribe, e-mail [EMAIL PROTECTED] Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php
Re: buffer overflows in MySQL error messages (e.g. in 4.0.10-gamma)
Sergei Golubchik wrote: On Mar 12, Maarten LITMAATH wrote: Description: MySQL (e.g. version 4.0.10-gamma) does not check for buffer overflows when formatting error messages: the code just assumes that no message will ever be larger than SC_MAXWIDTH (256), ERRMSGSIZE (SC_MAXWIDTH) or MYSQL_ERRMSG_SIZE (200). This has been observed to lead to memory corruption when the client e.g. tries to redefine a key with a name whose length is of order 200 (yes, that _is_ a realistic use case for computer-handled keys). How-To-Repeat: Define a key with a length of ~200 or more (the longer, the better) and then try to redefine it; observe the client getting an error message that is truncated and/or has trailing garbage. The client and/or the server may then have corrupted their own memories to such an extent that they become unusable and/or crash (both have been observed at least in a client application). Nope. Fails for me. mysql create table aa (bb int, key ccc(bb)); ERROR 1059: Identifier name 'ccc ' is too long mysql create table aa (bb int, key c(bb)); ERROR 1059: Identifier name 'ccc ccc Error message gets truncated, no overflow. OK, let me give a bit more information. I am using MySQL through a server (the Globus RLS, if you care about that), which does all the SQL statements. I did some stress testing of that server, trying to break it, e.g. by supplying ridiculously long names for keys, which caused it to corrupt its own memory and/or crash. Debugging that, I ultimately came to the MySQL client code that it uses, and found that it _evidently_ does not check for overflows in error messages. In the debugger I clearly saw the code scribbling beyond the end of an error message buffer, overwriting adjacent fields in some struct. I then patched various routines dealing with error messages (also in MyODBC) and my problem went away. I got truncated error messages too, but _after_ they had overflowed... Furthermore, whenever such overflow happens, the damage depends on the layout of the data segment or stack, so your program may survive, or _seem_ to survive, having corrupted its own memory. Please download the diffs and have a look at them: http://litmaath.home.cern.ch/litmaath/MyODBC-MySQL-patches/ mysql-4.0.10-gamma-ml-diffs.tgz You will see that the problems can easily be fixed once and for all, by using functions like my_snprintf() instead of plain sprintf(). Best regards, Maarten - Before posting, please check: http://www.mysql.com/manual.php (the manual) http://lists.mysql.com/ (the list archive) To request this thread, e-mail [EMAIL PROTECTED] To unsubscribe, e-mail [EMAIL PROTECTED] Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php
buffer overflows in MySQL error messages (e.g. in 4.0.10-gamma)
Description: MySQL (e.g. version 4.0.10-gamma) does not check for buffer overflows when formatting error messages: the code just assumes that no message will ever be larger than SC_MAXWIDTH (256), ERRMSGSIZE (SC_MAXWIDTH) or MYSQL_ERRMSG_SIZE (200). This has been observed to lead to memory corruption when the client e.g. tries to redefine a key with a name whose length is of order 200 (yes, that _is_ a realistic use case for computer-handled keys). How-To-Repeat: Define a key with a length of ~200 or more (the longer, the better) and then try to redefine it; observe the client getting an error message that is truncated and/or has trailing garbage. The client and/or the server may then have corrupted their own memories to such an extent that they become unusable and/or crash (both have been observed at least in a client application). Fix: In general, functions like my_vsnprintf() and my_snprintf() should be used instead of their counterparts vsprintf() and sprintf(). Please find suggested changes for various source files here: http://litmaath.home.cern.ch/litmaath/MyODBC-MySQL-patches.html In particular the file mysql-4.0.10-gamma-ml-diffs.tgz contains the differences between the original and the patched versions. These fixes appeared to be sufficient to prevent memory corruption in my use cases. Submitter-Id: unknown Originator: Maarten LITMAATH Organization: CERN - European Laboratory for Particle Physics MySQL support: none Synopsis: error message formatting may cause buffer overflows Severity: serious Priority: high Category: mysql Class: sw-bug Release:mysql-4.0.10-gamma (Source distribution) Server: lt-mysqladmin Ver 8.40 Distrib 4.0.10-gamma, for intel-linux on i686 Copyright (C) 2000 MySQL AB MySQL Finland AB TCX DataKonsult AB This software comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to modify and redistribute it under the GPL license Server version 4.0.10-gamma Protocol version10 Connection Localhost via UNIX socket UNIX socket /tmp/mysql.sock Uptime: 16 days 11 hours 50 min 3 sec Threads: 1 Questions: 5523 Slow queries: 0 Opens: 13 Flush tables: 1 Open tables: 7 Queries per second avg: 0.004 C compiler:2.95.2 C++ compiler: 2.95.2 Environment: System: Linux lxshare0270 2.4.18-18.7.x.cernsmp #1 SMP Mon Nov 18 15:44:49 CET 2002 i686 unknown Architecture: i686 Some paths: /usr/bin/perl /usr/bin/make /usr/bin/gmake /usr/bin/gcc /usr/bin/cc GCC: Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs gcc version 2.96 2731 (Red Hat Linux 7.3 2.96-113) (not used) Compilation info: CC='gcc' CFLAGS='' CXX='g++' CXXFLAGS='' LDFLAGS='' ASFLAGS='' LIBC: lrwxrwxrwx1 root root 13 Feb 20 13:27 /lib/libc.so.6 - libc-2.2.5.so -rwxr-xr-x1 root root 1260480 Oct 10 17:16 /lib/libc-2.2.5.so -rw-r--r--1 root root 2312442 Oct 10 16:51 /usr/lib/libc.a -rw-r--r--1 root root 178 Oct 10 16:46 /usr/lib/libc.so Configure command: ./configure '--prefix=/var/lib/mysql' '--with-thread-safe-client' '--enable-thread-safe-client' - Before posting, please check: http://www.mysql.com/manual.php (the manual) http://lists.mysql.com/ (the list archive) To request this thread, e-mail [EMAIL PROTECTED] To unsubscribe, e-mail [EMAIL PROTECTED] Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php