summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorunknown <cmiller@zippy.(none)>2006-05-01 22:10:50 -0400
committerunknown <cmiller@zippy.(none)>2006-05-01 22:10:50 -0400
commit3010890e589de89d2f5bb4c0e2c3a0b06b827b10 (patch)
treee1be3b9af9e1eb4a72abb369924831d5a8129301 /tests
parent8eb2b474b335973dcd2a2aa8c1fa5c097d46cc50 (diff)
downloadmariadb-git-3010890e589de89d2f5bb4c0e2c3a0b06b827b10.tar.gz
SECURITY FIX
Bug#17667: An attacker has the opportunity to bypass query logging. This adds a new, local-only printf format specifier to our *printf functions that allows us to print known-size buffers that must not be interpreted as NUL-terminated "strings." It uses this format-specifier to print to the log, thus fixing this problem. include/my_sys.h: Add prototype for my_memmem() . mysys/Makefile.am: Add reference to new file, my_memmem.c mysys/mf_iocache2.c: Add a "%.1234b" and "%.*b" percent-code. It takes a width, just like "%s", but unlike the string-indicator, it requires the width and doesn't stop printing at NUL characters. Also, simplify the code a bit. TODO: This code should be unified with the strings/my_vnsprintf.c code in the future. sql/sql_parse.cc: The query is not a C-string, but is a sized buffer, containing any character at all, which may include NUL characters. strings/my_vsnprintf.c: Add a "%.1234b" and "%.*b" percent-code. It takes a width, just like "%s", but unlike the string-indicator, it requires the width and doesn't stop printing at NUL characters. tests/Makefile.am: We may need some of our local functions. tests/mysql_client_test.c: Add a "%.1234b" and "%.*b" percent-code. It takes a width, just like "%s", but unlike the string-indicator, it requires the width and doesn't stop printing at NUL characters. mysql-test/t/mysql_client_test.opt: New BitKeeper file ``mysql-test/t/mysql_client_test.opt'' Add '--log' server parameter. mysys/my_memmem.c: New BitKeeper file ``mysys/my_memmem.c'' Implement memmem, a black-box work-alike of the GNU memmem(), which functions like strstr() but for arbitrary blocks of memory.
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/mysql_client_test.c66
2 files changed, 67 insertions, 1 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 131f8b1b625..ec732462ca5 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -42,7 +42,7 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
LIBS = @CLIENT_LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ \
$(top_builddir)/libmysql/libmysqlclient.la
-mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS)
+mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) -lmysys -L../mysys
mysql_client_test_SOURCES= mysql_client_test.c $(yassl_dummy_link_fix)
insert_test_SOURCES= insert_test.c $(yassl_dummy_link_fix)
select_test_SOURCES= select_test.c $(yassl_dummy_link_fix)
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index b1ea5f8ea06..4bd636a7ae3 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -14823,6 +14823,71 @@ static void test_bug15613()
}
/*
+ Bug#17667: An attacker has the opportunity to bypass query logging.
+*/
+static void test_bug17667()
+{
+ int rc;
+ myheader("test_bug17667");
+ struct buffer_and_length {
+ const char *buffer;
+ const uint length;
+ } statements[]= {
+ { "drop table if exists bug17667", 29 },
+ { "create table bug17667 (c varchar(20))", 37 },
+ { "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
+ { "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
+ { "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
+ { "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
+ { "drop table bug17667", 19 },
+ { NULL, 0 } };
+
+ struct buffer_and_length *statement_cursor;
+ FILE *log_file;
+
+ for (statement_cursor= statements; statement_cursor->buffer != NULL;
+ statement_cursor++) {
+ rc= mysql_real_query(mysql, statement_cursor->buffer,
+ statement_cursor->length);
+ myquery(rc);
+ }
+
+ sleep(1); /* The server may need time to flush the data to the log. */
+ log_file= fopen("var/log/master.log", "r");
+ if (log_file != NULL) {
+
+ for (statement_cursor= statements; statement_cursor->buffer != NULL;
+ statement_cursor++) {
+ char line_buffer[MAX_TEST_QUERY_LENGTH*2];
+ /* more than enough room for the query and some marginalia. */
+
+ do {
+ memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
+
+ DIE_UNLESS(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) !=
+ NULL);
+ /* If we reach EOF before finishing the statement list, then we failed. */
+
+ } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
+ statement_cursor->buffer, statement_cursor->length) == NULL);
+ }
+
+ printf("success. All queries found intact in the log.\n");
+
+ } else {
+ fprintf(stderr, "Could not find the log file, var/log/master.log, so "
+ "test_bug17667 is \ninconclusive. Run test from the "
+ "mysql-test/mysql-test-run* program \nto set up the correct "
+ "environment for this test.\n\n");
+ }
+
+ if (log_file != NULL)
+ fclose(log_file);
+
+}
+
+
+/*
Bug#14169: type of group_concat() result changed to blob if tmp_table was used
*/
static void test_bug14169()
@@ -15121,6 +15186,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug16143", test_bug16143 },
{ "test_bug15613", test_bug15613 },
{ "test_bug14169", test_bug14169 },
+ { "test_bug17667", test_bug17667 },
{ 0, 0 }
};