[Commits] 36c01167200: MDEV-12632: Source and destination overlap in memcpy, encryption.innodb-discard-import-change fails in buildbot with valgrind

jan jan.lindstrom at mariadb.com
Thu Apr 12 11:19:31 EEST 2018


revision-id: 36c01167200cf29ac92f3bd3263d7757c55cbb89 (mariadb-10.2.14-39-g36c01167200)
parent(s): 2f1f160979377cb3959f7030989bddcbd61c3afd
author: Jan Lindström
committer: Jan Lindström
timestamp: 2018-04-12 11:19:27 +0300
message:

MDEV-12632: Source and destination overlap in memcpy, encryption.innodb-discard-import-change fails in buildbot with valgrind

Problem was that if tablespace was encrypted we try to copy
also page 0 from read buffer to write buffer that are in
that case the same memory area.

fil_iterate
	When tablespace is encrypted or compressed its
        first page (i.e. page 0) is not encrypted or
	compressed and there is no need to copy buffer.

---
 storage/innobase/row/row0import.cc | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 4f7813929f2..dad16c1f54e 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -3349,12 +3349,12 @@ fil_iterate(
 		bool		updated = false;
 		os_offset_t	page_off = offset;
 		ulint		n_pages_read = n_bytes / size;
-		bool		decrypted = false;
 		block->page.id.set_page_no(ulint(page_off / size));
 
 		for (ulint i = 0; i < n_pages_read;
 		     block->page.id.set_page_no(block->page.id.page_no() + 1),
 		     ++i, page_off += size, block->frame += size) {
+			bool decrypted = false;
 			err = DB_SUCCESS;
 			byte*	src = readptr + i * size;
 			byte*	dst = io_buffer + i * size;
@@ -3401,6 +3401,7 @@ fil_iterate(
 						block->frame = src;
 						frame_changed = true;
 					} else {
+						ut_ad(dst != src);
 						memcpy(dst, src, size);
 					}
 				}
@@ -3460,9 +3461,13 @@ fil_iterate(
 			ut_ad(encrypted ?
 			      src != dst && dst != writeptr + (i * size):1);
 
-			if (encrypted) {
-				memcpy(writeptr + (i * size),
-				       callback.get_frame(block), size);
+			/* When tablespace is encrypted or compressed its
+			first page (i.e. page 0) is not encrypted or
+			compressed and there is no need to copy frame. */
+			if (encrypted && i != 0) {
+				byte *local_frame = callback.get_frame(block);
+				ut_ad((writeptr + (i * size)) != local_frame);
+				memcpy((writeptr + (i * size)), local_frame, size);
 			}
 
 			if (frame_changed) {
@@ -3500,6 +3505,7 @@ fil_iterate(
 
 				if (tmp == src) {
 					/* TODO: remove unnecessary memcpy's */
+					ut_ad(dest != src);
 					memcpy(dest, src, size);
 				}
 


More information about the commits mailing list