MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:msvensson Date:August 29 2006 9:08am
Subject:bk commit into 5.0 tree (msvensson:1.2249) BUG#14346
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of msvensson. When msvensson does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-08-29 11:08:47+02:00, msvensson@neptunus.(none) +2 -0
  Bug#21813 An attacker has the opportunity to bypass query logging, part2
   - Use the "%.*b" format when printing prepared and exeuted prepared statements to the log.
   - Add test case to check that also prepared statements end up in the query log
  Bug#14346 Prepared statements corrupting general log/server memory
   - Use "stmt->query" when logging the newly prepared query instead of "packet"

  sql/sql_prepare.cc@stripped, 2006-08-29 11:08:44+02:00, msvensson@neptunus.(none) +4 -2
    mysql_stmt_prepare
     - Use "%.*b" format when printing to log
     - Print the query from stmt instead of "packet", packet points at the net in/out buffer and has most likely been overwritten
       when  result for prepare was written to client.
    mysql_stmt_execute 
     - Use "%.*b" format when printing to log
     - Print the query from thd as the expanded query has been specifially set to be valid also after restore from backup statement  

  tests/mysql_client_test.c@stripped, 2006-08-29 11:08:45+02:00, msvensson@neptunus.(none) +62 -27
    Add tests for bug#21813 to already existing test for bug#17667. Add functionality for also executing prepared statements and making sure they end up in the log as well. 

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	msvensson
# Host:	neptunus.(none)
# Root:	/home/msvensson/mysql/bug21813/my50-bug21813

--- 1.181/sql/sql_prepare.cc	2006-08-29 11:08:52 +02:00
+++ 1.182/sql/sql_prepare.cc	2006-08-29 11:08:52 +02:00
@@ -1877,7 +1877,8 @@ void mysql_stmt_prepare(THD *thd, const 
     thd->stmt_map.erase(stmt);
   }
   else
-    mysql_log.write(thd, COM_STMT_PREPARE, "[%lu] %s", stmt->id, packet);
+    mysql_log.write(thd, COM_STMT_PREPARE, "[%lu] %.*b", stmt->id,
+                    stmt->query_length, stmt->query);
 
   /* check_prepared_statemnt sends the metadata packet in case of success */
   DBUG_VOID_RETURN;
@@ -2252,7 +2253,8 @@ void mysql_stmt_execute(THD *thd, char *
   if (!(specialflag & SPECIAL_NO_PRIOR))
     my_pthread_setprio(pthread_self(), WAIT_PRIOR);
   if (error == 0)
-    mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %s", stmt->id, thd->query);
+    mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %.*b", stmt->id,
+                    thd->query_length, thd->query);
 
   DBUG_VOID_RETURN;
 

--- 1.204/tests/mysql_client_test.c	2006-08-29 11:08:52 +02:00
+++ 1.205/tests/mysql_client_test.c	2006-08-29 11:08:52 +02:00
@@ -14912,22 +14912,31 @@ static void test_bug15613()
 
 /*
   Bug#17667: An attacker has the opportunity to bypass query logging.
+
+  Note! Also tests Bug#21813, where prepared statements are used to
+  run queries
 */
 static void test_bug17667()
 {
   int rc;
+  MYSQL_STMT *stmt;
+  enum query_type { QT_NORMAL, QT_PREPARED};
   struct buffer_and_length {
+    enum query_type qt;
     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 } };
+    { QT_NORMAL, "drop table if exists bug17667", 29 },
+    { QT_NORMAL, "create table bug17667 (c varchar(20))", 37 },
+    { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
+    { QT_PREPARED,
+      "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */", 69, },
+    { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
+    { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
+    { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')", 50 },
+    { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
+    { QT_NORMAL, "drop table bug17667", 19 },
+    { QT_NORMAL, NULL, 0 } };
 
   struct buffer_and_length *statement_cursor;
   FILE *log_file;
@@ -14937,9 +14946,36 @@ static void test_bug17667()
 
   for (statement_cursor= statements; statement_cursor->buffer != NULL;
       statement_cursor++) {
-    rc= mysql_real_query(mysql, statement_cursor->buffer,
-        statement_cursor->length);
-    myquery(rc);
+    if (statement_cursor->qt == QT_NORMAL)
+    {
+      /* Run statement as normal query */
+      rc= mysql_real_query(mysql, statement_cursor->buffer,
+                           statement_cursor->length);
+      myquery(rc);
+    }
+    else if (statement_cursor->qt == QT_PREPARED)
+    {
+      /*
+         Run as prepared statement
+
+         NOTE! All these queries should be in the log twice,
+         one time for prepare and one time for execute
+      */
+      stmt= mysql_stmt_init(mysql);
+
+      rc= mysql_stmt_prepare(stmt, statement_cursor->buffer,
+                             statement_cursor->length);
+      check_execute(stmt, rc);
+
+      rc= mysql_stmt_execute(stmt);
+      check_execute(stmt, rc);
+
+      mysql_stmt_close(stmt);
+    }
+    else
+    {
+      assert(0==1);
+    }
   }
 
   /* Make sure the server has written the logs to disk before reading it */
@@ -14957,29 +14993,28 @@ static void test_bug17667()
 
     for (statement_cursor= statements; statement_cursor->buffer != NULL;
         statement_cursor++) {
+      int expected_hits= 1, hits= 0;
       char line_buffer[MAX_TEST_QUERY_LENGTH*2];
       /* more than enough room for the query and some marginalia. */
 
+      /* Prepared statments always occurs twice in log */
+      if (statement_cursor->qt == QT_PREPARED)
+        expected_hits++;
+
+      /* Loop until we found expected number of log entries */
       do {
-        memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
+        /* Loop until statement is found in log */
+        do {
+          memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
 
-        if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
-        {
-          /* If fgets returned NULL, it indicates either error or EOF */
-          if (feof(log_file))
+          if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
             DIE("Found EOF before all statements where found");
-          else
-          {
-            fprintf(stderr, "Got error %d while reading from file\n",
-                    ferror(log_file));
-            DIE("Read error");
-          }
-        }
-        /* Print the line */
-        printf("%s", line_buffer);
 
-      } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
-            statement_cursor->buffer, statement_cursor->length) == NULL);
+        } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
+                           statement_cursor->buffer,
+                           statement_cursor->length) == NULL);
+        hits++;
+      } while (hits < expected_hits);
 
       printf("Found statement starting with \"%s\"\n",
              statement_cursor->buffer);
Thread
bk commit into 5.0 tree (msvensson:1.2249) BUG#14346msvensson29 Aug