[Commits] 7c21ea9: MDEV-7772: SIGSEGV on my_aes_encrypt_cbc when -DWITH_SSL=bundled

Jan Lindström jan.lindstrom at mariadb.com
Fri Mar 13 14:19:40 EET 2015


revision-id: 7c21ea9f502ded155c12a0ee3c5ff0602e9d4c9a
parent(s): 4d0e52189ca945c94146035c2733d85c9c6fd18d
committer: Jan Lindström
branch nick: 10.1-innodb
timestamp: 2015-03-13 14:18:07 +0200
message:

MDEV-7772: SIGSEGV on my_aes_encrypt_cbc when -DWITH_SSL=bundled

Two problems:
- Read/Write outside of buffer at memcpy() because of incorrect parameters
. OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == iv_length); // ECB does not use IV, thus incorrect assertion

Added:
    mysql-test/include/have_file_key_management_plugin.combinations ( to run with aes_cbc and aes_ecb)
    mysql-test/include/have_openssl_ctr.combinations ( to run with aes_cbc, aes_ecb and aes_ctr)

---
 .../have_file_key_management_plugin.combinations   |  6 ++++
 .../include/have_file_key_management_plugin.opt    |  2 +-
 mysql-test/include/have_openssl_ctr.combinations   |  9 ++++++
 mysql-test/include/have_openssl_ctr.opt            |  1 -
 .../t/innodb-page_encryption_log_encryption.opt    |  1 -
 mysql-test/suite/innodb/t/innodb_encryption.opt    |  2 +-
 mysql-test/suite/innodb/t/innodb_scrub.test        |  1 +
 .../suite/innodb/t/innodb_scrub_background.test    |  1 +
 mysys_ssl/my_aes.cc                                | 36 ++++++++++++----------
 storage/innobase/fil/fil0crypt.cc                  |  2 +-
 storage/innobase/fil/fil0fil.cc                    |  2 +-
 storage/innobase/handler/ha_innodb.cc              |  2 +-
 storage/innobase/handler/i_s.cc                    |  2 +-
 storage/xtradb/fil/fil0crypt.cc                    |  2 +-
 storage/xtradb/fil/fil0fil.cc                      |  2 +-
 storage/xtradb/handler/ha_innodb.cc                |  2 +-
 storage/xtradb/handler/i_s.cc                      |  2 +-
 17 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/mysql-test/include/have_file_key_management_plugin.combinations b/mysql-test/include/have_file_key_management_plugin.combinations
new file mode 100644
index 0000000..6a63b5a
--- /dev/null
+++ b/mysql-test/include/have_file_key_management_plugin.combinations
@@ -0,0 +1,6 @@
+[aes_cbc]
+encryption-algorithm=aes_cbc
+
+[aes_ecb]
+encryption-algorithm=aes_ecb
+
diff --git a/mysql-test/include/have_file_key_management_plugin.opt b/mysql-test/include/have_file_key_management_plugin.opt
index 599847b..5aa1ce1 100644
--- a/mysql-test/include/have_file_key_management_plugin.opt
+++ b/mysql-test/include/have_file_key_management_plugin.opt
@@ -1,4 +1,4 @@
 --plugin-load-add=$FILE_KEY_MANAGEMENT_PLUGIN_SO
 --loose-file-key-management-plugin
 --loose-file-key-management-plugin-filename=$MYSQL_TEST_DIR/std_data/keys.txt
---encryption-algorithm=aes_cbc
+
diff --git a/mysql-test/include/have_openssl_ctr.combinations b/mysql-test/include/have_openssl_ctr.combinations
new file mode 100644
index 0000000..2c49c78
--- /dev/null
+++ b/mysql-test/include/have_openssl_ctr.combinations
@@ -0,0 +1,9 @@
+[aes_cbc]
+encryption-algorithm=aes_cbc
+
+[aes_ecb]
+encryption-algorithm=aes_ecb
+
+[aes_ctr]
+encryption-algorithm=aes_ctr
+
diff --git a/mysql-test/include/have_openssl_ctr.opt b/mysql-test/include/have_openssl_ctr.opt
deleted file mode 100644
index a88a422..0000000
--- a/mysql-test/include/have_openssl_ctr.opt
+++ /dev/null
@@ -1 +0,0 @@
---encryption-algorithm=aes_ctr
diff --git a/mysql-test/suite/innodb/t/innodb-page_encryption_log_encryption.opt b/mysql-test/suite/innodb/t/innodb-page_encryption_log_encryption.opt
index fe33453..f14c376 100644
--- a/mysql-test/suite/innodb/t/innodb-page_encryption_log_encryption.opt
+++ b/mysql-test/suite/innodb/t/innodb-page_encryption_log_encryption.opt
@@ -1,2 +1 @@
---encryption-algorithm=aes_cbc
 --innodb-encrypt-log
diff --git a/mysql-test/suite/innodb/t/innodb_encryption.opt b/mysql-test/suite/innodb/t/innodb_encryption.opt
index 306e3f9..f7f583d 100644
--- a/mysql-test/suite/innodb/t/innodb_encryption.opt
+++ b/mysql-test/suite/innodb/t/innodb_encryption.opt
@@ -4,4 +4,4 @@
 --innodb-encryption-rotate-key-age=15
 --innodb-encryption-threads=4
 --innodb-tablespaces-encryption
---encryption-algorithm=aes_ctr
+
diff --git a/mysql-test/suite/innodb/t/innodb_scrub.test b/mysql-test/suite/innodb/t/innodb_scrub.test
index 4b370b3..09ece97 100644
--- a/mysql-test/suite/innodb/t/innodb_scrub.test
+++ b/mysql-test/suite/innodb/t/innodb_scrub.test
@@ -1,6 +1,7 @@
 -- source include/have_innodb.inc
 -- source include/not_embedded.inc
 -- source include/have_example_key_management_plugin.inc
+-- source include/have_openssl_ctr.inc
 
 let $MYSQLD_DATADIR=`select @@datadir`;
 let ib1_IBD = $MYSQLD_DATADIR/ibdata1;
diff --git a/mysql-test/suite/innodb/t/innodb_scrub_background.test b/mysql-test/suite/innodb/t/innodb_scrub_background.test
index 44cb16b..881c124 100644
--- a/mysql-test/suite/innodb/t/innodb_scrub_background.test
+++ b/mysql-test/suite/innodb/t/innodb_scrub_background.test
@@ -1,6 +1,7 @@
 -- source include/have_innodb.inc
 -- source include/not_embedded.inc
 -- source include/have_example_key_management_plugin.inc
+-- source include/have_openssl_ctr.inc
 
 let $MYSQLD_DATADIR=`select @@datadir`;
 let ib1_IBD = $MYSQLD_DATADIR/ibdata1;
diff --git a/mysys_ssl/my_aes.cc b/mysys_ssl/my_aes.cc
index 20bd035..6486f74 100644
--- a/mysys_ssl/my_aes.cc
+++ b/mysys_ssl/my_aes.cc
@@ -255,12 +255,12 @@ static int my_aes_encrypt_cbc(const uchar* source, uint32 source_length,
   }
 
   if (noPadding) {
-	if (remaining_bytes!=0) {
-	   memcpy(dest + source_length, source + source_length, remaining_bytes);
-	}
+    if (remaining_bytes!=0) {
+      /* Note that we moved the original pointers above */
+      memcpy(dest, source, remaining_bytes);
+    }
     *dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes;
     return AES_OK;
-
   }
 
   /* Encode the rest. We always have incomplete block */
@@ -383,12 +383,12 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length,
   }
 
   if (noPadding) {
-	if (remaining_bytes!=0) {
-	   memcpy(dest + source_length, source + source_length, remaining_bytes);
-	}
-	*dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes;
+    if (remaining_bytes!=0) {
+      /* Note that we moved the original pointers above */
+      memcpy(dest, source, remaining_bytes);
+    }
+    *dest_length = MY_AES_BLOCK_SIZE * (num_blocks) + remaining_bytes;
     return AES_OK;
-
   }
 
   /* Encode the rest. We always have incomplete block */
@@ -430,7 +430,8 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length,
   }
   EVP_CIPHER_CTX_key_length(&ctx.ctx);
   OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx.ctx) == key_length);
-  OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == iv_length);
+  // ECB does not use IV
+  OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == 0);
   OPENSSL_assert(EVP_CIPHER_CTX_block_size(&ctx.ctx) == 16);
   if (! EVP_EncryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len,
                           (unsigned const char *) source, source_length))
@@ -438,9 +439,9 @@ static int my_aes_encrypt_ecb(const uchar* source, uint32 source_length,
   if (! EVP_EncryptFinal_ex(&ctx.ctx, (unsigned char *) dest + u_len, &f_len))
     return AES_BAD_DATA;                        /* Error */
 
-  if (remaining_bytes!=0) {
-   	  memcpy(dest + source_length, source + source_length, remaining_bytes);
-     }
+  if (remaining_bytes!=0)
+    memcpy(dest + source_length, source + source_length, remaining_bytes);
+
   *dest_length = (unsigned long int) (u_len + f_len + remaining_bytes);
 
   return AES_OK;
@@ -524,7 +525,8 @@ static int my_aes_decrypt_cbc(const uchar* source, uint32 source_length,
   if (noPadding) {
     memcpy(dest, block, MY_AES_BLOCK_SIZE);
     if (remaining_bytes!=0) {
-            	  memcpy(dest + source_length, source + source_length, remaining_bytes);
+      /* Note that we have moved dest and source */
+      memcpy(dest + MY_AES_BLOCK_SIZE, source + MY_AES_BLOCK_SIZE, remaining_bytes);
     }
     *dest_length = MY_AES_BLOCK_SIZE * num_blocks + remaining_bytes;
     return AES_OK;
@@ -656,7 +658,8 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length,
   if (noPadding) {
     memcpy(dest, block, MY_AES_BLOCK_SIZE);
     if (remaining_bytes!=0) {
-      memcpy(dest + source_length, source + source_length, remaining_bytes);
+      /* Note that we have moved dest and source */
+      memcpy(dest + MY_AES_BLOCK_SIZE, source + MY_AES_BLOCK_SIZE, remaining_bytes);
     }
     *dest_length = MY_AES_BLOCK_SIZE * num_blocks + remaining_bytes;
     return AES_OK;
@@ -699,7 +702,8 @@ static int my_aes_decrypt_ecb(const uchar* source, uint32 source_length,
     EVP_CIPHER_CTX_set_padding(&ctx.ctx, 0);
   }
   OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx.ctx) == key_length);
-  OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == iv_length);
+  // ECB does not use IV
+  OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx.ctx) == 0);
   OPENSSL_assert(EVP_CIPHER_CTX_block_size(&ctx.ctx) == 16);
   if (! EVP_DecryptUpdate(&ctx.ctx, (unsigned char *) dest, &u_len,
                           (unsigned char *)source, source_length))
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 823c74a..10d49bb 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -734,7 +734,7 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn,
 	uint32 dstlen;
 
 	if (page_compressed) {
-		srclen = page_size -  FIL_PAGE_DATA;;
+		srclen = page_size -  FIL_PAGE_DATA;
 	}
 
 	int rc = (* my_aes_encrypt_dynamic)(src, srclen,
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 750cb50..adc8f0b 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -5985,7 +5985,7 @@ fil_flush(
 	     node != NULL;
 	     node = UT_LIST_GET_NEXT(chain, node)) {
 
-		ib_int64_t old_mod_counter = node->modification_counter;;
+		ib_int64_t old_mod_counter = node->modification_counter;
 
 		if (old_mod_counter <= node->flush_counter) {
 			continue;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index df443f9..3a5f961 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -11287,7 +11287,7 @@ ha_innobase::check_table_options(
 	const bool	use_tablespace, /*!< in: use file par table */
 	const ulint     file_format)
 {
-	enum row_type	row_format = table->s->row_type;;
+	enum row_type	row_format = table->s->row_type;
 	ha_table_option_struct *options= table->s->option_struct;
 	atomic_writes_t awrites = (atomic_writes_t)options->atomic_writes;
 
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 3664c05..65fcb70 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -7683,7 +7683,7 @@ i_s_dict_fill_sys_tablespaces(
 {
 	Field**	fields;
 	ulint	atomic_blobs	= FSP_FLAGS_HAS_ATOMIC_BLOBS(flags);
-	ulint	page_size	= fsp_flags_get_page_size(flags);;
+	ulint	page_size	= fsp_flags_get_page_size(flags);
 	ulint	zip_size	= fsp_flags_get_zip_size(flags);
 	const char* file_format;
 	const char* row_format;
diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc
index 823c74a..10d49bb 100644
--- a/storage/xtradb/fil/fil0crypt.cc
+++ b/storage/xtradb/fil/fil0crypt.cc
@@ -734,7 +734,7 @@ fil_space_encrypt(ulint space, ulint offset, lsn_t lsn,
 	uint32 dstlen;
 
 	if (page_compressed) {
-		srclen = page_size -  FIL_PAGE_DATA;;
+		srclen = page_size -  FIL_PAGE_DATA;
 	}
 
 	int rc = (* my_aes_encrypt_dynamic)(src, srclen,
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index d960950..b80685d 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -6052,7 +6052,7 @@ fil_flush(
 	     node != NULL;
 	     node = UT_LIST_GET_NEXT(chain, node)) {
 
-		ib_int64_t old_mod_counter = node->modification_counter;;
+		ib_int64_t old_mod_counter = node->modification_counter;
 
 		if (old_mod_counter <= node->flush_counter) {
 			continue;
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 0ad6af8..5cc232a 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -11793,7 +11793,7 @@ ha_innobase::check_table_options(
 	const bool	use_tablespace, /*!< in: use file par table */
 	const ulint     file_format)
 {
-	enum row_type	row_format = table->s->row_type;;
+	enum row_type	row_format = table->s->row_type;
 	ha_table_option_struct *options= table->s->option_struct;
 	atomic_writes_t awrites = (atomic_writes_t)options->atomic_writes;
 
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 6157156..20bc433 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -7651,7 +7651,7 @@ i_s_dict_fill_sys_tablespaces(
 {
 	Field**	fields;
 	ulint	atomic_blobs	= FSP_FLAGS_HAS_ATOMIC_BLOBS(flags);
-	ulint	page_size	= fsp_flags_get_page_size(flags);;
+	ulint	page_size	= fsp_flags_get_page_size(flags);
 	ulint	zip_size	= fsp_flags_get_zip_size(flags);
 	const char* file_format;
 	const char* row_format;


More information about the commits mailing list