From 447e23392451f1c91c78a7465fb1680e8f21384b Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Mon, 27 Jun 2016 12:48:57 +0530 Subject: [PATCH 01/33] Raise version number after cloning 5.5.51 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index db9d497c141a9..acabf9b42d0ca 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=51 +MYSQL_VERSION_PATCH=52 MYSQL_VERSION_EXTRA= From 6986645c7924ef3292e233d9365520b29eb8fa0d Mon Sep 17 00:00:00 2001 From: Christopher Powers Date: Thu, 30 Jun 2016 20:42:29 +0200 Subject: [PATCH 02/33] Bug#14111584 PB2: PERFSCHEMA.AGGREGATE FAILS ON PB2 SPORADICALLY Permanently removed test case perfschema.aggregate. The Performance Schema is generally lock-free, allowing for race conditions that might arise from multi-threaded operation which occasionally results in temporary and/or minor variances when aggregating statistics. This test needs to be redesigned to accommodate such variances. --- .../suite/perfschema/r/aggregate.result | 102 ---------- mysql-test/suite/perfschema/t/aggregate.test | 174 ------------------ 2 files changed, 276 deletions(-) delete mode 100644 mysql-test/suite/perfschema/r/aggregate.result delete mode 100644 mysql-test/suite/perfschema/t/aggregate.test diff --git a/mysql-test/suite/perfschema/r/aggregate.result b/mysql-test/suite/perfschema/r/aggregate.result deleted file mode 100644 index edc7ce0bcca19..0000000000000 --- a/mysql-test/suite/perfschema/r/aggregate.result +++ /dev/null @@ -1,102 +0,0 @@ -"General cleanup" -drop table if exists t1; -update performance_schema.setup_instruments set enabled = 'NO'; -update performance_schema.setup_consumers set enabled = 'NO'; -truncate table performance_schema.file_summary_by_event_name; -truncate table performance_schema.file_summary_by_instance; -truncate table performance_schema.events_waits_summary_global_by_event_name; -truncate table performance_schema.events_waits_summary_by_instance; -truncate table performance_schema.events_waits_summary_by_thread_by_event_name; -update performance_schema.setup_consumers set enabled = 'YES'; -update performance_schema.setup_instruments -set enabled = 'YES', timed = 'YES'; -create table t1 ( -id INT PRIMARY KEY, -b CHAR(100) DEFAULT 'initial value') -ENGINE=MyISAM; -insert into t1 (id) values (1), (2), (3), (4), (5), (6), (7), (8); -update performance_schema.setup_instruments SET enabled = 'NO'; -update performance_schema.setup_consumers set enabled = 'NO'; -set @dump_all=FALSE; -"Verifying file aggregate consistency" -SELECT EVENT_NAME, e.COUNT_READ, SUM(i.COUNT_READ) -FROM performance_schema.file_summary_by_event_name AS e -JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.COUNT_READ <> SUM(i.COUNT_READ)) -OR @dump_all; -EVENT_NAME COUNT_READ SUM(i.COUNT_READ) -SELECT EVENT_NAME, e.COUNT_WRITE, SUM(i.COUNT_WRITE) -FROM performance_schema.file_summary_by_event_name AS e -JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.COUNT_WRITE <> SUM(i.COUNT_WRITE)) -OR @dump_all; -EVENT_NAME COUNT_WRITE SUM(i.COUNT_WRITE) -SELECT EVENT_NAME, e.SUM_NUMBER_OF_BYTES_READ, SUM(i.SUM_NUMBER_OF_BYTES_READ) -FROM performance_schema.file_summary_by_event_name AS e -JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.SUM_NUMBER_OF_BYTES_READ <> SUM(i.SUM_NUMBER_OF_BYTES_READ)) -OR @dump_all; -EVENT_NAME SUM_NUMBER_OF_BYTES_READ SUM(i.SUM_NUMBER_OF_BYTES_READ) -SELECT EVENT_NAME, e.SUM_NUMBER_OF_BYTES_WRITE, SUM(i.SUM_NUMBER_OF_BYTES_WRITE) -FROM performance_schema.file_summary_by_event_name AS e -JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.SUM_NUMBER_OF_BYTES_WRITE <> SUM(i.SUM_NUMBER_OF_BYTES_WRITE)) -OR @dump_all; -EVENT_NAME SUM_NUMBER_OF_BYTES_WRITE SUM(i.SUM_NUMBER_OF_BYTES_WRITE) -"Verifying waits aggregate consistency (instance)" -SELECT EVENT_NAME, e.SUM_TIMER_WAIT, SUM(i.SUM_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.SUM_TIMER_WAIT < SUM(i.SUM_TIMER_WAIT)) -OR @dump_all; -EVENT_NAME SUM_TIMER_WAIT SUM(i.SUM_TIMER_WAIT) -SELECT EVENT_NAME, e.MIN_TIMER_WAIT, MIN(i.MIN_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.MIN_TIMER_WAIT > MIN(i.MIN_TIMER_WAIT)) -AND (MIN(i.MIN_TIMER_WAIT) != 0) -OR @dump_all; -EVENT_NAME MIN_TIMER_WAIT MIN(i.MIN_TIMER_WAIT) -SELECT EVENT_NAME, e.MAX_TIMER_WAIT, MAX(i.MAX_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.MAX_TIMER_WAIT < MAX(i.MAX_TIMER_WAIT)) -OR @dump_all; -EVENT_NAME MAX_TIMER_WAIT MAX(i.MAX_TIMER_WAIT) -"Verifying waits aggregate consistency (thread)" -SELECT EVENT_NAME, e.SUM_TIMER_WAIT, SUM(t.SUM_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t -USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.SUM_TIMER_WAIT < SUM(t.SUM_TIMER_WAIT)) -OR @dump_all; -EVENT_NAME SUM_TIMER_WAIT SUM(t.SUM_TIMER_WAIT) -SELECT EVENT_NAME, e.MIN_TIMER_WAIT, MIN(t.MIN_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t -USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.MIN_TIMER_WAIT > MIN(t.MIN_TIMER_WAIT)) -AND (MIN(t.MIN_TIMER_WAIT) != 0) -OR @dump_all; -EVENT_NAME MIN_TIMER_WAIT MIN(t.MIN_TIMER_WAIT) -SELECT EVENT_NAME, e.MAX_TIMER_WAIT, MAX(t.MAX_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t -USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.MAX_TIMER_WAIT < MAX(t.MAX_TIMER_WAIT)) -OR @dump_all; -EVENT_NAME MAX_TIMER_WAIT MAX(t.MAX_TIMER_WAIT) -update performance_schema.setup_consumers set enabled = 'YES'; -update performance_schema.setup_instruments -set enabled = 'YES', timed = 'YES'; -drop table test.t1; diff --git a/mysql-test/suite/perfschema/t/aggregate.test b/mysql-test/suite/perfschema/t/aggregate.test deleted file mode 100644 index 91794f0434607..0000000000000 --- a/mysql-test/suite/perfschema/t/aggregate.test +++ /dev/null @@ -1,174 +0,0 @@ -# Tests for PERFORMANCE_SCHEMA -# Verify that statistics aggregated by different criteria are consistent. - ---source include/not_embedded.inc ---source include/have_perfschema.inc - ---echo "General cleanup" - ---disable_warnings -drop table if exists t1; ---enable_warnings - -update performance_schema.setup_instruments set enabled = 'NO'; -update performance_schema.setup_consumers set enabled = 'NO'; - -# Cleanup statistics -truncate table performance_schema.file_summary_by_event_name; -truncate table performance_schema.file_summary_by_instance; -truncate table performance_schema.events_waits_summary_global_by_event_name; -truncate table performance_schema.events_waits_summary_by_instance; -truncate table performance_schema.events_waits_summary_by_thread_by_event_name; - -# Start recording data -update performance_schema.setup_consumers set enabled = 'YES'; -update performance_schema.setup_instruments - set enabled = 'YES', timed = 'YES'; - - -create table t1 ( - id INT PRIMARY KEY, - b CHAR(100) DEFAULT 'initial value') - ENGINE=MyISAM; - -insert into t1 (id) values (1), (2), (3), (4), (5), (6), (7), (8); - -# Stop recording data, so the select below don't add noise. -update performance_schema.setup_instruments SET enabled = 'NO'; -# Disable all consumers, for long standing waits -update performance_schema.setup_consumers set enabled = 'NO'; - -# Helper to debug -set @dump_all=FALSE; - -# Note that in general: -# - COUNT/SUM/MAX(file_summary_by_event_name) >= -# COUNT/SUM/MAX(file_summary_by_instance). -# - MIN(file_summary_by_event_name) <= -# MIN(file_summary_by_instance). -# There will be equality only when file instances are not removed, -# aka when a file is not deleted from the file system, -# because doing so removes a row in file_summary_by_instance. - -# Likewise: -# - COUNT/SUM/MAX(events_waits_summary_global_by_event_name) >= -# COUNT/SUM/MAX(events_waits_summary_by_instance) -# - MIN(events_waits_summary_global_by_event_name) <= -# MIN(events_waits_summary_by_instance) -# There will be equality only when an instrument instance -# is not removed, which is next to impossible to predictably guarantee -# in the server. -# For example, a MyISAM table removed from the table cache -# will cause a mysql_mutex_destroy on myisam/MYISAM_SHARE::intern_lock. -# Another example, a thread terminating will cause a mysql_mutex_destroy -# on sql/LOCK_delete -# Both cause a row to be deleted from events_waits_summary_by_instance. - -# Likewise: -# - COUNT/SUM/MAX(events_waits_summary_global_by_event_name) >= -# COUNT/SUM/MAX(events_waits_summary_by_thread_by_event_name) -# - MIN(events_waits_summary_global_by_event_name) <= -# MIN(events_waits_summary_by_thread_by_event_name) -# There will be equality only when no thread is removed, -# that is if no thread disconnects, or no sub thread (for example insert -# delayed) ever completes. -# A thread completing will cause rows in -# events_waits_summary_by_thread_by_event_name to be removed. - ---echo "Verifying file aggregate consistency" - -# Since the code generating the load in this test does: -# - create table -# - insert -# - does not cause temporary tables to be used -# we can test for equality here for file aggregates. - -# If any of these queries returns data, the test failed. - -SELECT EVENT_NAME, e.COUNT_READ, SUM(i.COUNT_READ) -FROM performance_schema.file_summary_by_event_name AS e -JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.COUNT_READ <> SUM(i.COUNT_READ)) -OR @dump_all; - -SELECT EVENT_NAME, e.COUNT_WRITE, SUM(i.COUNT_WRITE) -FROM performance_schema.file_summary_by_event_name AS e -JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.COUNT_WRITE <> SUM(i.COUNT_WRITE)) -OR @dump_all; - -SELECT EVENT_NAME, e.SUM_NUMBER_OF_BYTES_READ, SUM(i.SUM_NUMBER_OF_BYTES_READ) -FROM performance_schema.file_summary_by_event_name AS e -JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.SUM_NUMBER_OF_BYTES_READ <> SUM(i.SUM_NUMBER_OF_BYTES_READ)) -OR @dump_all; - -SELECT EVENT_NAME, e.SUM_NUMBER_OF_BYTES_WRITE, SUM(i.SUM_NUMBER_OF_BYTES_WRITE) -FROM performance_schema.file_summary_by_event_name AS e -JOIN performance_schema.file_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.SUM_NUMBER_OF_BYTES_WRITE <> SUM(i.SUM_NUMBER_OF_BYTES_WRITE)) -OR @dump_all; - ---echo "Verifying waits aggregate consistency (instance)" - -SELECT EVENT_NAME, e.SUM_TIMER_WAIT, SUM(i.SUM_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.SUM_TIMER_WAIT < SUM(i.SUM_TIMER_WAIT)) -OR @dump_all; - -SELECT EVENT_NAME, e.MIN_TIMER_WAIT, MIN(i.MIN_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.MIN_TIMER_WAIT > MIN(i.MIN_TIMER_WAIT)) -AND (MIN(i.MIN_TIMER_WAIT) != 0) -OR @dump_all; - -SELECT EVENT_NAME, e.MAX_TIMER_WAIT, MAX(i.MAX_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_instance AS i USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.MAX_TIMER_WAIT < MAX(i.MAX_TIMER_WAIT)) -OR @dump_all; - ---echo "Verifying waits aggregate consistency (thread)" - -SELECT EVENT_NAME, e.SUM_TIMER_WAIT, SUM(t.SUM_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t -USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.SUM_TIMER_WAIT < SUM(t.SUM_TIMER_WAIT)) -OR @dump_all; - -SELECT EVENT_NAME, e.MIN_TIMER_WAIT, MIN(t.MIN_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t -USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.MIN_TIMER_WAIT > MIN(t.MIN_TIMER_WAIT)) -AND (MIN(t.MIN_TIMER_WAIT) != 0) -OR @dump_all; - -SELECT EVENT_NAME, e.MAX_TIMER_WAIT, MAX(t.MAX_TIMER_WAIT) -FROM performance_schema.events_waits_summary_global_by_event_name AS e -JOIN performance_schema.events_waits_summary_by_thread_by_event_name AS t -USING (EVENT_NAME) -GROUP BY EVENT_NAME -HAVING (e.MAX_TIMER_WAIT < MAX(t.MAX_TIMER_WAIT)) -OR @dump_all; - - -# Cleanup - -update performance_schema.setup_consumers set enabled = 'YES'; -update performance_schema.setup_instruments - set enabled = 'YES', timed = 'YES'; - -drop table test.t1; From 07a33cdcef16b21c5d9bb5f0c538066e24eb8dc0 Mon Sep 17 00:00:00 2001 From: Kailasnath Nagarkar Date: Fri, 1 Jul 2016 12:01:27 +0530 Subject: [PATCH 03/33] Bug #23296299 : HANDLE_FATAL_SIGNAL (SIG=11) IN MY_TOSORT_UTF32 This patch is specific for mysql-5.5 ISSUE: When a charater that is larger than possible to handle is passed to function my_tosort_utf32(), it results in segmentation fault. In the scenario mentioned in the bug AES_ENCRYPT function is used which returns large value. This value is further passed to my_tosort_utf32 function. This causes to cross array bound for array uni_plane, resulting in segment violation. SOLUTION: This issue has got addressed in 5.6 onward releases through worklog 2673. The fix is similar backport of that. Check for maximum character before accessing the array uni_plane. In addition to function my_tosort_utf32, the same potential problem is also present in functions my_tolower_utf16, my_toupper_utf16, my_tosort_utf16, my_tolower_utf32, my_toupper_utf32, my_tosort_unicode, my_tolower_utf8mb4 and my_toupper_utf8mb4. Fixed these functions as well. --- include/m_ctype.h | 4 ++-- strings/ctype-ucs2.c | 14 +++++++------- strings/ctype-utf8.c | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index 81096f60c78a8..87b1e529f657b 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,11 +33,11 @@ extern "C" { #define MY_CS_TO_UPPER_TABLE_SIZE 256 #define MY_CS_SORT_ORDER_TABLE_SIZE 256 #define MY_CS_TO_UNI_TABLE_SIZE 256 - #define CHARSET_DIR "charsets/" #define my_wc_t ulong +#define MY_CS_MAX_CHAR 0xFFFF #define MY_CS_REPLACEMENT_CHARACTER 0xFFFD /* diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 37fd1b5349ff8..f1beff82a409a 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -1099,7 +1099,7 @@ static inline void my_tolower_utf16(MY_UNICASE_INFO **uni_plane, my_wc_t *wc) { int page= *wc >> 8; - if (page < 256 && uni_plane[page]) + if (page < 256 && *wc <= MY_CS_MAX_CHAR && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].tolower; } @@ -1108,7 +1108,7 @@ static inline void my_toupper_utf16(MY_UNICASE_INFO **uni_plane, my_wc_t *wc) { int page= *wc >> 8; - if (page < 256 && uni_plane[page]) + if (page < 256 && *wc <= MY_CS_MAX_CHAR && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].toupper; } @@ -1117,7 +1117,7 @@ static inline void my_tosort_utf16(MY_UNICASE_INFO **uni_plane, my_wc_t *wc) { int page= *wc >> 8; - if (page < 256) + if (page < 256 && *wc <= MY_CS_MAX_CHAR) { if (uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].sort; @@ -1728,7 +1728,7 @@ static inline void my_tolower_utf32(MY_UNICASE_INFO **uni_plane, my_wc_t *wc) { int page= *wc >> 8; - if (page < 256 && uni_plane[page]) + if (page < 256 && *wc <= MY_CS_MAX_CHAR && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].tolower; } @@ -1737,7 +1737,7 @@ static inline void my_toupper_utf32(MY_UNICASE_INFO **uni_plane, my_wc_t *wc) { int page= *wc >> 8; - if (page < 256 && uni_plane[page]) + if (page < 256 && *wc <= MY_CS_MAX_CHAR && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].toupper; } @@ -1746,7 +1746,7 @@ static inline void my_tosort_utf32(MY_UNICASE_INFO **uni_plane, my_wc_t *wc) { int page= *wc >> 8; - if (page < 256) + if (page < 256 && *wc <= MY_CS_MAX_CHAR) { if (uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].sort; diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 52e05f17d61db..33e5703ffd9d4 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -1941,7 +1941,7 @@ static inline void my_tosort_unicode(MY_UNICASE_INFO **uni_plane, my_wc_t *wc) { int page= *wc >> 8; - if (page < 256) + if (page < 256 && *wc <= MY_CS_MAX_CHAR) { if (uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].sort; @@ -5023,7 +5023,7 @@ static inline void my_tolower_utf8mb4(MY_UNICASE_INFO **uni_plane, my_wc_t *wc) { int page= *wc >> 8; - if (page < 256 && uni_plane[page]) + if (page < 256 && *wc <= MY_CS_MAX_CHAR && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].tolower; } @@ -5032,7 +5032,7 @@ static inline void my_toupper_utf8mb4(MY_UNICASE_INFO **uni_plane, my_wc_t *wc) { int page= *wc >> 8; - if (page < 256 && uni_plane[page]) + if (page < 256 && *wc <= MY_CS_MAX_CHAR && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].toupper; } From 09784e244bfbb16d3a1b54d1018995984ac8c121 Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Tue, 5 Jul 2016 17:08:37 +0530 Subject: [PATCH 04/33] Bug#23736787 - YUM UPDATE FAIL FROM 5.5.51(COMUNITY/COMMERCIAL) TO 5.6.32(COMUNITY/COMMERCIAL) Remove mysql_config from client sub-package --- packaging/rpm-oel/mysql.spec.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packaging/rpm-oel/mysql.spec.in b/packaging/rpm-oel/mysql.spec.in index 29957d98ed0ed..409c325b6759f 100644 --- a/packaging/rpm-oel/mysql.spec.in +++ b/packaging/rpm-oel/mysql.spec.in @@ -835,8 +835,6 @@ fi %attr(755, root, root) %{_bindir}/mysqlimport %attr(755, root, root) %{_bindir}/mysqlshow %attr(755, root, root) %{_bindir}/mysqlslap -%attr(755, root, root) %{_bindir}/mysql_config -%attr(755, root, root) %{_bindir}/mysql_config-%{__isa_bits} %attr(644, root, root) %{_mandir}/man1/msql2mysql.1* %attr(644, root, root) %{_mandir}/man1/mysql.1* @@ -918,6 +916,9 @@ fi %endif %changelog +* Tue Jul 05 2016 Balasubramanian Kandasamy - 5.5.51-1 +- Remove mysql_config from client subpackage + * Tue Sep 29 2015 Balasubramanian Kandasamy - 5.5.47-1 - Added conflicts to mysql-connector-c-shared dependencies From 54e887b2fe24056b633957e8f9aff9d7f50b5089 Mon Sep 17 00:00:00 2001 From: Chaithra Gopalareddy Date: Tue, 19 Jul 2016 08:03:09 +0530 Subject: [PATCH 05/33] Bug#23280059: ITEM_ROW::ILLEGAL_METHOD_CALL(CONST CHAR*): ASSERTION `0' FAILED ON SELECT AREA Problem: Optimizer tries to get the points to calculate area without checking the return value of uint4korr for 0 "points". As a result server exits. Solution: Check the return value from uint4korr(). --- sql/spatial.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/spatial.cc b/sql/spatial.cc index 7aab91b5a5bc1..7643b3a649dd0 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -849,6 +849,8 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const if (no_data(data, 4)) return 1; n_points= uint4korr(data); + if (n_points == 0) + return 1; if (not_enough_points(data, n_points)) return 1; get_point(&prev_x, &prev_y, data+4); From ac460e584d9706e02ce3dcb86bd994276672b267 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Fri, 22 Jul 2016 07:33:43 +0530 Subject: [PATCH 06/33] Bug #23280699: MYSQLD GOT SIGNAL 11 IN IS_NULL ON SELECT FROM I_S Issue: ------ There is a difference in the field type created when the following DDLs are used: 1) CREATE TABLE t0 AS SELECT NULL; 2) CREATE TABLE t0 AS SELECT GREATEST(NULL,NULL); The first statement creates field of type Field_string and the second one creates a field of type Field_null. This creates a problem when the query mentioned in this bug is used. Since the null_ptr is calculated differently for Field_null. Solution: --------- When there is a function returning null in the select list as mentioned above, the field should be of type Field_string. This was fixed in 5.6+ as part of Bug#14021323. This is a backport to mysql-5.5. An incorrect comment in innodb_bug54044.test has been corrected in all versions. --- mysql-test/suite/innodb/r/innodb_bug54044.result | 14 ++++++++++---- mysql-test/suite/innodb/t/innodb_bug54044.test | 11 +++++------ sql/item.cc | 5 +---- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb_bug54044.result b/mysql-test/suite/innodb/r/innodb_bug54044.result index 350c500cb9b74..29b0127f20b92 100644 --- a/mysql-test/suite/innodb/r/innodb_bug54044.result +++ b/mysql-test/suite/innodb/r/innodb_bug54044.result @@ -6,7 +6,13 @@ table_54044 CREATE TEMPORARY TABLE `table_54044` ( `IF(NULL IS NOT NULL, NULL, NULL)` binary(0) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE table_54044; -CREATE TABLE tmp ENGINE = INNODB AS SELECT COALESCE(NULL, NULL, NULL); -ERROR HY000: Can't create table 'test.tmp' (errno: -1) -CREATE TABLE tmp ENGINE = INNODB AS SELECT GREATEST(NULL, NULL); -ERROR HY000: Can't create table 'test.tmp' (errno: -1) +CREATE TABLE tmp ENGINE = INNODB +AS SELECT COALESCE(NULL, NULL, NULL), GREATEST(NULL, NULL), NULL; +SHOW CREATE TABLE tmp; +Table Create Table +tmp CREATE TABLE `tmp` ( + `COALESCE(NULL, NULL, NULL)` binary(0) DEFAULT NULL, + `GREATEST(NULL, NULL)` binary(0) DEFAULT NULL, + `NULL` binary(0) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE tmp; diff --git a/mysql-test/suite/innodb/t/innodb_bug54044.test b/mysql-test/suite/innodb/t/innodb_bug54044.test index 0bbd7da00658b..cfc6f3c3f0a9b 100644 --- a/mysql-test/suite/innodb/t/innodb_bug54044.test +++ b/mysql-test/suite/innodb/t/innodb_bug54044.test @@ -10,10 +10,9 @@ CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB SHOW CREATE TABLE table_54044; DROP TABLE table_54044; -# These 'create table' operations should fail because of -# using NULL datatype +# This 'create table' should pass since it uses a Field_string of size 0. ---error ER_CANT_CREATE_TABLE -CREATE TABLE tmp ENGINE = INNODB AS SELECT COALESCE(NULL, NULL, NULL); ---error ER_CANT_CREATE_TABLE -CREATE TABLE tmp ENGINE = INNODB AS SELECT GREATEST(NULL, NULL); +CREATE TABLE tmp ENGINE = INNODB + AS SELECT COALESCE(NULL, NULL, NULL), GREATEST(NULL, NULL), NULL; +SHOW CREATE TABLE tmp; +DROP TABLE tmp; diff --git a/sql/item.cc b/sql/item.cc index 1541314ec97ce..34157c33cf425 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5360,10 +5360,6 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length) field= new Field_double((uchar*) 0, max_length, null_ptr, 0, Field::NONE, name, decimals, 0, unsigned_flag); break; - case MYSQL_TYPE_NULL: - field= new Field_null((uchar*) 0, max_length, Field::NONE, - name, &my_charset_bin); - break; case MYSQL_TYPE_INT24: field= new Field_medium((uchar*) 0, max_length, null_ptr, 0, Field::NONE, name, 0, unsigned_flag); @@ -5394,6 +5390,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length) DBUG_ASSERT(0); /* If something goes awfully wrong, it's better to get a string than die */ case MYSQL_TYPE_STRING: + case MYSQL_TYPE_NULL: if (fixed_length && max_length < CONVERT_IF_BIGGER_TO_BLOB) { field= new Field_string(max_length, maybe_null, name, From fd31eea949e5cbfccb97715bec62f6c63ece6010 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Fri, 22 Jul 2016 13:15:32 +0530 Subject: [PATCH 07/33] Bug #23295288: HANDLE_FATAL_SIGNAL (SIG=11) IN GET_SERVER_FROM_TABLE_TO_CACHE Description:- Server received SIG11 in the function, "get_server_from_table_to_cache()". Analysis:- Defining a server with a blank name is not handled properly. Fix:- Modified "get_server_from_table_to_cache()" to take care of blank server name. --- sql/sql_yacc.yy | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 16ed61334c65d..b8ddc8bd49fc5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2148,6 +2148,11 @@ server_def: ident_or_text OPTIONS_SYM '(' server_options_list ')' { + if ($2.length == 0) + { + my_error(ER_WRONG_VALUE, MYF(0), "server name", ""); + MYSQL_YYABORT; + } Lex->server_options.server_name= $2.str; Lex->server_options.server_name_length= $2.length; Lex->server_options.scheme= $6.str; From 2674cf91c5dad871f59704685e77e76ba8f462cd Mon Sep 17 00:00:00 2001 From: Thayumanavar S Date: Mon, 25 Jul 2016 06:43:16 +0100 Subject: [PATCH 08/33] BUG#23703568 - IS CLIENT LIBRARY SUPPOSED TO RETRY EINTR INDEFINITELY OR NOT Commit#ebd24626ca38e7fa1e3da2acdcf88540be70fabe obsoleted the THREAD and THREAD_SAFE_CLIENT preprocessor symbols. This is not removed in the sql/net_serv.cc thereby the code that retries on EINTR became dead code. Remove the THREAD_SAFE_CLIENT preprocessor directive form sql/net_serv.cc. Also check errno for EINTR only if there is an error in preceding read call. --- sql/net_serv.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 8b44c7d443f1a..9c0c84bb2924b 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -676,13 +676,13 @@ net_real_write(NET *net,const uchar *packet, size_t len) my_progname); #endif /* EXTRA_DEBUG */ } -#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) +#ifndef MYSQL_SERVER if (vio_errno(net->vio) == SOCKET_EINTR) { DBUG_PRINT("warning",("Interrupted write. Retrying...")); continue; } -#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */ +#endif /* !defined(MYSQL_SERVER) */ net->error= 2; /* Close socket */ net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE); @@ -887,8 +887,9 @@ my_real_read(NET *net, size_t *complen) my_progname,vio_errno(net->vio)); #endif /* EXTRA_DEBUG */ } -#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) - if (vio_errno(net->vio) == SOCKET_EINTR) +#ifndef MYSQL_SERVER + if (static_cast(length) < 0 && + vio_errno(net->vio) == SOCKET_EINTR) { DBUG_PRINT("warning",("Interrupted read. Retrying...")); continue; From a63a250d40be0254c6a5633329a6b0577eaee74c Mon Sep 17 00:00:00 2001 From: Neha Kumari Date: Mon, 25 Jul 2016 20:34:20 +0530 Subject: [PATCH 09/33] BUG#23509275 :DBUG_PRINT in THD::decide_logging_format prints incorrectly, access out-of-bound Problem: In debug builds, there is a chance that an out-of-bounds read is performed when tables are locked in LTM_PRELOCKED_UNDER_LOCK_TABLES mode. It can happen because the debug code uses enum values as index for an array of mode descriptions, but it only takes into consideration 3 out of 4 of the enum values. Fix: This patch fixes it by implementing a getter for the enum which returns a string representation of the enum, effectively removing the out-of-bounds read. Moreover, it also fixes the lock mode descriptions that would be print out in debug builds. --- sql/sql_class.cc | 32 ++++++++++++++++++++++---------- sql/sql_class.h | 11 +++++++++++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 4711009d7cd83..0696021cfc09b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -4246,6 +4246,25 @@ has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables) return 0; } +#ifndef DBUG_OFF +const char * get_locked_tables_mode_name(enum_locked_tables_mode locked_tables_mode) +{ + switch (locked_tables_mode) + { + case LTM_NONE: + return "LTM_NONE"; + case LTM_LOCK_TABLES: + return "LTM_LOCK_TABLES"; + case LTM_PRELOCKED: + return "LTM_PRELOCKED"; + case LTM_PRELOCKED_UNDER_LOCK_TABLES: + return "LTM_PRELOCKED_UNDER_LOCK_TABLES"; + default: + return "Unknown table lock mode"; + } +} +#endif + /** Decide on logging format to use for the statement and issue errors or warnings as needed. The decision depends on the following @@ -4397,15 +4416,8 @@ int THD::decide_logging_format(TABLE_LIST *tables) TABLE* prev_access_table= NULL; #ifndef DBUG_OFF - { - static const char *prelocked_mode_name[] = { - "NON_PRELOCKED", - "PRELOCKED", - "PRELOCKED_UNDER_LOCK_TABLES", - }; - DBUG_PRINT("debug", ("prelocked_mode: %s", - prelocked_mode_name[locked_tables_mode])); - } + DBUG_PRINT("debug", ("prelocked_mode: %s", + get_locked_tables_mode_name(locked_tables_mode))); #endif if (variables.binlog_format != BINLOG_FORMAT_ROW && tables) diff --git a/sql/sql_class.h b/sql/sql_class.h index 0df8c70e18443..dcc7458ee5043 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -963,6 +963,8 @@ typedef I_List Item_change_list; /** Type of locked tables mode. See comment for THD::locked_tables_mode for complete description. + While adding new enum values add them to the getter method for this enum + declared below and defined in sql_class.cc as well. */ enum enum_locked_tables_mode @@ -973,6 +975,15 @@ enum enum_locked_tables_mode LTM_PRELOCKED_UNDER_LOCK_TABLES }; +#ifndef DBUG_OFF +/** + Getter for the enum enum_locked_tables_mode + @param locked_tables_mode enum for types of locked tables mode + + @return The string represantation of that enum value +*/ +const char * get_locked_tables_mode_name(enum_locked_tables_mode locked_tables_mode); +#endif /** Class that holds information about tables which were opened and locked From 8bb95e9a974b5eee44764698fafc56279f8b7691 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Wed, 3 Aug 2016 09:58:36 +0530 Subject: [PATCH 10/33] Bug #24380263: INCORRECT BEHAVIOR WITH PARAMETER AND DERIVED TABLE IN JOIN ISSUE: ------ This problem occurs under the following conditions: 1) A parameter is used in the select-list of a derived table. 2) The derived table is part of a JOIN. SOLUTION: --------- When a derived table is materialized, a temporary table is created. This temporary table creates a field each for the items in the select-list of the derived table. This set of fields is later used to setup the join. Currently no field is created in the temporary table if a parameter is used in the select-list. Create a field for the parameter. By default Item_param's result type in a prepared statement is set to STRING_RESULT. This can change during the execute phase depending on the user variable. But since the execute phase creates its own temporary table, it will be handled separately. This is a backport of the fix for BUG#22392374. --- sql/sql_select.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b5ecebdadc861..fb705e9ba6ad2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10240,6 +10240,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::REF_ITEM: case Item::NULL_ITEM: case Item::VARBIN_ITEM: + case Item::PARAM_ITEM: if (make_copy_field) { DBUG_ASSERT(((Item_result_field*)item)->result_field); From 322afb2c0a6bc7c8ffb365c61b90392bfe4b4f31 Mon Sep 17 00:00:00 2001 From: Kailasnath Nagarkar Date: Wed, 3 Aug 2016 12:54:58 +0530 Subject: [PATCH 11/33] Bug #19984392 : MEDIUMINT: STACK BUFFER OVERFLOW IN PROTOCOL_TEXT::STORE_LONG ISSUE: Queries with mediumint as column when operated with long long type of data results in buffer overflow in store_long function. The merging rule specified for (MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24) is MYSQL_TYPE_LONG. Due to this store_long function was getting called which resulted in buffer overflow. SOLUTION: The correct merging rule for (MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24) should be MYSQL_TYPE_LONGLONG. So, instead of function store_long, function store_longlong is called which correctly handles the type MYSQL_TYPE_LONGLONG. External Bug #23645238 is a duplicate of this issue. --- sql/field.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index abe856a8292c6..d9889f0fb489b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -347,7 +347,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP MYSQL_TYPE_LONGLONG, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 - MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONG, + MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG, //MYSQL_TYPE_DATE MYSQL_TYPE_TIME MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR From 194776ce00f6fea37551ea25584798f78b0ad24b Mon Sep 17 00:00:00 2001 From: Kailasnath Nagarkar Date: Thu, 4 Aug 2016 12:49:50 +0530 Subject: [PATCH 12/33] Bug #19984392 : MEDIUMINT: STACK BUFFER OVERFLOW IN PROTOCOL_TEXT::STORE_LONG Reverting the patch due to some issues. --- sql/field.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/field.cc b/sql/field.cc index d9889f0fb489b..3ca072e777164 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -347,7 +347,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP MYSQL_TYPE_LONGLONG, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 - MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG, + MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONG, //MYSQL_TYPE_DATE MYSQL_TYPE_TIME MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR From 22eec68941f3acbd9033e7fb33d10c63e6b388da Mon Sep 17 00:00:00 2001 From: Neha Kumari Date: Fri, 5 Aug 2016 12:17:11 +0530 Subject: [PATCH 13/33] Bug#23540182:MYSQLBINLOG DOES NOT FREE THE EXISTING CONNECTION BEFORE OPENING NEW REMOTE ONE It happens when you are trying to read two or more log files from a remote server using mysqlbinlog utility. The reason for this is no matching mysql_close() that concludes the life time of 'mysql' struct describing connection to the server. This happens when mysqlbinlog is invoked with connecting to the server and requesting more than one binlog file. In such case dump_remote_log_entries() keeps calling safe_connect() per eachfile, never caring to invoke mysql_close(). Only the final safe_connect()'s allocation effect are cleaned by the base code. That is with 2 files there's one 'mysql' connection descriptor struct uncleaned/deallocated. We are backporting the bug 21255763 (pushed in mysql-trunk) in the earlier version of MySQL starting from 5.5 to 5.7. which was pushed in mysql-trunk. Fix: Invoke mysql_close() just before mysql_init() in safe_connect() defined in mysqlbinlog.cc. That makes possibly previously used 'mysql' be reclaimed prior a new one is allocated. --- client/mysqlbinlog.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 73a801c4b21e0..955d9e3fb3c1e 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1444,6 +1444,12 @@ static int parse_args(int *argc, char*** argv) */ static Exit_status safe_connect() { + /* + A possible old connection's resources are reclaimed now + at new connect attempt. The final safe_connect resources + are mysql_closed at the end of program, explicitly. + */ + mysql_close(mysql); mysql= mysql_init(NULL); if (!mysql) From 737964dcd12e61ae7fb4b47505158e2fecce9f2b Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Wed, 10 Aug 2016 11:24:18 -0400 Subject: [PATCH 14/33] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index db9d497c141a9..acabf9b42d0ca 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=51 +MYSQL_VERSION_PATCH=52 MYSQL_VERSION_EXTRA= From 09cb64682bda8648b0cdad606b169b4d592f839d Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 11 Aug 2016 19:35:53 +0000 Subject: [PATCH 15/33] Windows : fix search for WiX root directory when using 64bit cmake "C:\Program Files (x86)" directory needs to be checked as well in this case. --- win/packaging/CMakeLists.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/win/packaging/CMakeLists.txt b/win/packaging/CMakeLists.txt index 0535a486d57ba..1682bae6986cb 100644 --- a/win/packaging/CMakeLists.txt +++ b/win/packaging/CMakeLists.txt @@ -24,10 +24,13 @@ ENDIF() SET(MANUFACTURER "MariaDB Corporation Ab") -FIND_PATH(WIX_DIR heat.exe - "$ENV{ProgramFiles}/WiX Toolset v3.9/bin" - "$ENV{ProgramFiles}/WiX Toolset v3.10/bin" -) +SET(WIX_BIN_PATHS) +FOREACH(WIX_VER 3.9 3.10 3.11) + LIST(APPEND WIX_BIN_PATHS "$ENV{ProgramFiles}/WiX Toolset v${WIX_VER}/bin") + LIST(APPEND WIX_BIN_PATHS "$ENV{ProgramFiles} (x86)/WiX Toolset v${WIX_VER}/bin") +ENDFOREACH() + +FIND_PATH(WIX_DIR heat.exe ${WIX_BIN_PATHS}) SET(CPACK_WIX_PACKAGE_BASE_NAME "MariaDB") IF(CMAKE_SIZEOF_VOID_P EQUAL 4) SET(CPACK_WIX_UPGRADE_CODE "49EB7A6A-1CEF-4A1E-9E89-B9A4993963E3") From 723488bba162109f241bc764b6e33c6f3d8b39d6 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 4 Aug 2016 15:43:52 +0400 Subject: [PATCH 16/33] MDEV-10424 - Assertion `ticket == __null' failed in MDL_request::set_type Reexecution of prepared "ANALYZE TABLE merge_table, table" may miss to reinitialize "table" for subsequent execution and trigger assertion failure. This happens because MERGE engine may adjust table->next_global chain, which gets cleared by close_thread_tables()/ha_myisammrg::detach_children() later. Since reinitilization iterates next_global chain, it won't see tables following merge table. Fixed by appending saved next_global chain after merge children. --- mysql-test/r/merge.result | 17 +++++++++++++++++ mysql-test/t/merge.test | 13 +++++++++++++ sql/sql_admin.cc | 14 +++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 41ee148cee326..66ba6cea70e3c 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -3832,4 +3832,21 @@ test.m1 repair error Corrupt # Clean-up. drop tables m1, t1, t4; drop view t3; +# +# MDEV-10424 - Assertion `ticket == __null' failed in +# MDL_request::set_type +# +CREATE TABLE t1 (f1 INT) ENGINE=MyISAM; +CREATE TABLE tmerge (f1 INT) ENGINE=MERGE UNION=(t1); +PREPARE stmt FROM "ANALYZE TABLE tmerge, t1"; +EXECUTE stmt; +Table Op Msg_type Msg_text +test.tmerge analyze note The storage engine for the table doesn't support analyze +test.t1 analyze status Table is already up to date +EXECUTE stmt; +Table Op Msg_type Msg_text +test.tmerge analyze note The storage engine for the table doesn't support analyze +test.t1 analyze status Table is already up to date +DEALLOCATE PREPARE stmt; +DROP TABLE t1, tmerge; End of 5.5 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 6573c2b09c009..9d0ddd01752ce 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -2880,6 +2880,19 @@ drop tables m1, t1, t4; drop view t3; +--echo # +--echo # MDEV-10424 - Assertion `ticket == __null' failed in +--echo # MDL_request::set_type +--echo # +CREATE TABLE t1 (f1 INT) ENGINE=MyISAM; +CREATE TABLE tmerge (f1 INT) ENGINE=MERGE UNION=(t1); +PREPARE stmt FROM "ANALYZE TABLE tmerge, t1"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +DROP TABLE t1, tmerge; + + --echo End of 5.5 tests --disable_result_log diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 12a59fa6ee80c..55effcd70027d 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -441,7 +441,19 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, } thd->prepare_derived_at_open= FALSE; - table->next_global= save_next_global; + /* + MERGE engine may adjust table->next_global chain, thus we have to + append save_next_global after merge children. + */ + if (save_next_global) + { + TABLE_LIST *table_list_iterator= table; + while (table_list_iterator->next_global) + table_list_iterator= table_list_iterator->next_global; + table_list_iterator->next_global= save_next_global; + save_next_global->prev_global= &table_list_iterator->next_global; + } + table->next_local= save_next_local; thd->open_options&= ~extra_open_options; From a92a8cc817649df80fd84b6a466da345772660fb Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 19 Aug 2016 17:11:20 +0000 Subject: [PATCH 17/33] Windows packaging : use /d switch to sign MSI, to prevent installer showing randomly generated name in UAC prompt --- win/packaging/create_msi.cmake.in | 1 + 1 file changed, 1 insertion(+) diff --git a/win/packaging/create_msi.cmake.in b/win/packaging/create_msi.cmake.in index a8ca35906e8da..fceea04167646 100644 --- a/win/packaging/create_msi.cmake.in +++ b/win/packaging/create_msi.cmake.in @@ -430,6 +430,7 @@ EXECUTE_PROCESS( IF(SIGNCODE) EXECUTE_PROCESS( COMMAND ${SIGNTOOL_EXECUTABLE} sign ${SIGNTOOL_PARAMETERS} + /d ${CPACK_PACKAGE_FILE_NAME}.msi ${CPACK_PACKAGE_FILE_NAME}.msi ) ENDIF() From ee97274ca7d9ea8d8f00e40476a039c35399ee15 Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 25 Aug 2016 09:50:04 +0300 Subject: [PATCH 18/33] DEV-10595 MariaDB daemon leaks memory with specific query The issue was that in some extreme cases when doing GROUP BY, buffers for temporary blobs where not properly cleared. --- mysql-test/r/group_min_max_innodb.result | 16 +++++++++++++ mysql-test/t/group_min_max_innodb.test | 13 +++++++++++ sql/sql_class.h | 5 ++++ sql/sql_select.cc | 29 +++++++++++++++++++----- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/group_min_max_innodb.result b/mysql-test/r/group_min_max_innodb.result index c4d2fb88784dc..1e3ee793a7f97 100644 --- a/mysql-test/r/group_min_max_innodb.result +++ b/mysql-test/r/group_min_max_innodb.result @@ -286,3 +286,19 @@ F 28 28 F 29 29 F 30 30 DROP TABLE t0,t1,t2; +# +# MDEV-MariaDB daemon leaks memory with specific query +# +CREATE TABLE t1 (`voter_id` int(11) unsigned NOT NULL, +`language_id` int(11) unsigned NOT NULL DEFAULT '1' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t2 (`voter_id` int(10) unsigned NOT NULL DEFAULT '0', +`serialized_c` mediumblob) ENGINE=InnoDB DEFAULT CHARSET=utf8; +insert into t2 values (1,repeat("a",1000)),(2,repeat("a",1000)),(3,repeat("b",1000)),(4,repeat("c",1000)),(4,repeat("b",1000)); +SELECT GROUP_CONCAT(t1.language_id SEPARATOR ',') AS `translation_resources`, `d`.`serialized_c` FROM t2 AS `d` LEFT JOIN t1 ON `d`.`voter_id` = t1.`voter_id` GROUP BY `d`.`voter_id` ORDER BY 10-d.voter_id+RAND()*0; +translation_resources serialized_c +NULL cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +NULL bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +NULL aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +NULL aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drop table t1,t2; diff --git a/mysql-test/t/group_min_max_innodb.test b/mysql-test/t/group_min_max_innodb.test index 6967f84714729..91e0bd3279fb4 100644 --- a/mysql-test/t/group_min_max_innodb.test +++ b/mysql-test/t/group_min_max_innodb.test @@ -230,3 +230,16 @@ eval EXPLAIN $query; eval $query; DROP TABLE t0,t1,t2; + +--echo # +--echo # MDEV-MariaDB daemon leaks memory with specific query +--echo # + +CREATE TABLE t1 (`voter_id` int(11) unsigned NOT NULL, + `language_id` int(11) unsigned NOT NULL DEFAULT '1' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t2 (`voter_id` int(10) unsigned NOT NULL DEFAULT '0', + `serialized_c` mediumblob) ENGINE=InnoDB DEFAULT CHARSET=utf8; +insert into t2 values (1,repeat("a",1000)),(2,repeat("a",1000)),(3,repeat("b",1000)),(4,repeat("c",1000)),(4,repeat("b",1000)); +SELECT GROUP_CONCAT(t1.language_id SEPARATOR ',') AS `translation_resources`, `d`.`serialized_c` FROM t2 AS `d` LEFT JOIN t1 ON `d`.`voter_id` = t1.`voter_id` GROUP BY `d`.`voter_id` ORDER BY 10-d.voter_id+RAND()*0; +drop table t1,t2; diff --git a/sql/sql_class.h b/sql/sql_class.h index d24dad7c2ca7b..da83382d5e93b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3607,6 +3607,11 @@ class TMP_TABLE_PARAM :public Sql_alloc save_copy_field_end= copy_field_end= NULL; } } + void free_copy_field_data() + { + for (Copy_field *ptr= copy_field ; ptr != copy_field_end ; ptr++) + ptr->tmp.free(); + } }; class select_union :public select_result_interceptor diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 613cbb2e08699..121805dd0e2ea 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8275,9 +8275,26 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table) We need to destruct the copy_field (allocated in create_tmp_table()) before setting it to 0 if the join is not "reusable". */ - if (!tmp_join || tmp_join != this) - tmp_table_param.cleanup(); - tmp_table_param.copy_field= tmp_table_param.copy_field_end=0; + if (!tmp_join || tmp_join != this) + tmp_table_param.cleanup(); + else + { + /* + Free data buffered in copy_fields, but keep data pointed by copy_field + around for next iteration (possibly stored in save_copy_fields). + + It would be logically simpler to not clear copy_field + below, but as we have loops that runs over copy_field to + copy_field_end that should not be done anymore, it's simpler to + just clear the pointers. + + Another option would be to just clear copy_field_end and not run + the loops if this is not set or to have tmp_table_param.cleanup() + to run cleanup on save_copy_field if copy_field is not set. + */ + tmp_table_param.free_copy_field_data(); + tmp_table_param.copy_field= tmp_table_param.copy_field_end=0; + } first_record= sort_and_group=0; send_records= (ha_rows) 0; @@ -10866,7 +10883,7 @@ void JOIN::join_free() /** Free resources of given join. - @param fill true if we should free all resources, call with full==1 + @param full true if we should free all resources, call with full==1 should be last, before it this function can be called with full==0 @@ -10982,7 +10999,7 @@ void JOIN::cleanup(bool full) /* If we have tmp_join and 'this' JOIN is not tmp_join and tmp_table_param.copy_field's of them are equal then we have to remove - pointer to tmp_table_param.copy_field from tmp_join, because it qill + pointer to tmp_table_param.copy_field from tmp_join, because it will be removed in tmp_table_param.cleanup(). */ if (tmp_join && @@ -21397,7 +21414,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, err: if (copy) delete [] param->copy_field; // This is never 0 - param->copy_field=0; + param->copy_field= 0; err2: DBUG_RETURN(TRUE); } From 684a165f28b3718160a3e4c5ebd18a465d85e97c Mon Sep 17 00:00:00 2001 From: Terje Rosten Date: Fri, 12 Aug 2016 12:38:20 +0200 Subject: [PATCH 19/33] Bug#24464380 PRIVILEGE ESCALATION USING MYSQLD_SAFE Argument to malloc-lib must be included in restricted list of directories, symlink guards added, and mysqld and mysqld-version options restricted to command line only. Don't redirect errors to stderr. --- packaging/rpm-oel/mysql.init | 2 +- packaging/rpm-sles/mysql.init | 2 +- scripts/mysqld_safe.sh | 79 +++++++++++++++++++++-------------- support-files/mysql.server.sh | 2 +- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/packaging/rpm-oel/mysql.init b/packaging/rpm-oel/mysql.init index 262d0582f68b4..aaea498d15339 100644 --- a/packaging/rpm-oel/mysql.init +++ b/packaging/rpm-oel/mysql.init @@ -102,7 +102,7 @@ start(){ # alarms, per bug #547485 $exec --datadir="$datadir" --socket="$socketfile" \ --pid-file="$mypidfile" \ - --basedir=/usr --user=mysql >/dev/null 2>&1 & + --basedir=/usr --user=mysql >/dev/null & safe_pid=$! # Spin for a maximum of N seconds waiting for the server to come up; # exit the loop immediately if mysqld_safe process disappears. diff --git a/packaging/rpm-sles/mysql.init b/packaging/rpm-sles/mysql.init index 50ca4c9033c75..dda0bebba5658 100644 --- a/packaging/rpm-sles/mysql.init +++ b/packaging/rpm-sles/mysql.init @@ -137,7 +137,7 @@ start () { rc_failed 6 ; rc_status -v ; rc_exit fi - $PROG --basedir=/usr --datadir="$datadir" --pid-file="$pidfile" >/dev/null 2>&1 & + $PROG --basedir=/usr --datadir="$datadir" --pid-file="$pidfile" >/dev/null & if pinger $! ; then echo -n "Starting service MySQL:" touch $lockfile diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index f705953059e0b..11b692ec92874 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -208,8 +208,17 @@ parse_arguments() { --core-file-size=*) core_file_size="$val" ;; --ledir=*) ledir="$val" ;; --malloc-lib=*) set_malloc_lib "$val" ;; - --mysqld=*) MYSQLD="$val" ;; + --mysqld=*) + if [ -z "$pick_args" ]; then + log_error "--mysqld option can only be used as command line option, found in config file" + exit 1 + fi + MYSQLD="$val" ;; --mysqld-version=*) + if [ -z "$pick_args" ]; then + log_error "--mysqld-version option can only be used as command line option, found in config file" + exit 1 + fi if test -n "$val" then MYSQLD="mysqld-$val" @@ -297,38 +306,22 @@ mysqld_ld_preload_text() { echo "$text" } - -mysql_config= -get_mysql_config() { - if [ -z "$mysql_config" ]; then - mysql_config=`echo "$0" | sed 's,/[^/][^/]*$,/mysql_config,'` - if [ ! -x "$mysql_config" ]; then - log_error "Can not run mysql_config $@ from '$mysql_config'" - exit 1 - fi - fi - - "$mysql_config" "$@" -} - - # set_malloc_lib LIB # - If LIB is empty, do nothing and return -# - If LIB is 'tcmalloc', look for tcmalloc shared library in /usr/lib -# then pkglibdir. tcmalloc is part of the Google perftools project. +# - If LIB is 'tcmalloc', look for tcmalloc shared library in $malloc_dirs. +# tcmalloc is part of the Google perftools project. # - If LIB is an absolute path, assume it is a malloc shared library # # Put LIB in mysqld_ld_preload, which will be added to LD_PRELOAD when # running mysqld. See ld.so for details. set_malloc_lib() { + # This list is kept intentionally simple. + malloc_dirs="/usr/lib /usr/lib64 /usr/lib/i386-linux-gnu /usr/lib/x86_64-linux-gnu" malloc_lib="$1" if [ "$malloc_lib" = tcmalloc ]; then - pkglibdir=`get_mysql_config --variable=pkglibdir` malloc_lib= - # This list is kept intentionally simple. Simply set --malloc-lib - # to a full path if another location is desired. - for libdir in /usr/lib "$pkglibdir" "$pkglibdir/mysql"; do + for libdir in $(echo $malloc_dirs); do for flavor in _minimal '' _and_profiler _debug; do tmp="$libdir/libtcmalloc$flavor.so" #log_notice "DEBUG: Checking for malloc lib '$tmp'" @@ -339,7 +332,7 @@ set_malloc_lib() { done if [ -z "$malloc_lib" ]; then - log_error "no shared library for --malloc-lib=tcmalloc found in /usr/lib or $pkglibdir" + log_error "no shared library for --malloc-lib=tcmalloc found in $malloc_dirs" exit 1 fi fi @@ -350,9 +343,21 @@ set_malloc_lib() { case "$malloc_lib" in /*) if [ ! -r "$malloc_lib" ]; then - log_error "--malloc-lib '$malloc_lib' can not be read and will not be used" + log_error "--malloc-lib can not be read and will not be used" exit 1 fi + + # Restrict to a the list in $malloc_dirs above + case "$(dirname "$malloc_lib")" in + /usr/lib) ;; + /usr/lib64) ;; + /usr/lib/i386-linux-gnu) ;; + /usr/lib/x86_64-linux-gnu) ;; + *) + log_error "--malloc-lib must be located in one of the directories: $malloc_dirs" + exit 1 + ;; + esac ;; *) log_error "--malloc-lib must be an absolute path or 'tcmalloc'; " \ @@ -569,7 +574,7 @@ then log_notice "Logging to '$err_log'." logging=file - if [ ! -f "$err_log" ]; then # if error log already exists, + if [ ! -f "$err_log" -a ! -h "$err_log" ]; then # if error log already exists, touch "$err_log" # we just append. otherwise, chmod "$fmode" "$err_log" # fix the permissions here! fi @@ -594,7 +599,7 @@ then USER_OPTION="--user=$user" fi # Change the err log to the right user, if it is in use - if [ $want_syslog -eq 0 ]; then + if [ $want_syslog -eq 0 -a ! -h "$err_log" ]; then touch "$err_log" chown $user "$err_log" fi @@ -614,9 +619,11 @@ safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}} mysql_unix_port_dir=`dirname $safe_mysql_unix_port` if [ ! -d $mysql_unix_port_dir ] then - mkdir $mysql_unix_port_dir - chown $user $mysql_unix_port_dir - chmod 755 $mysql_unix_port_dir + if [ ! -h $mysql_unix_port_dir ]; then + mkdir $mysql_unix_port_dir + chown $user $mysql_unix_port_dir + chmod 755 $mysql_unix_port_dir + fi fi # If the user doesn't specify a binary, we assume name "mysqld" @@ -728,7 +735,9 @@ then exit 1 fi fi - rm -f "$pid_file" + if [ ! -h "$pid_file" ]; then + rm -f "$pid_file" + fi if test -f "$pid_file" then log_error "Fatal error: Can't remove the pid file: @@ -779,13 +788,19 @@ have_sleep=1 while true do - rm -f $safe_mysql_unix_port "$pid_file" # Some extra safety + # Some extra safety + if [ ! -h "$safe_mysql_unix_port" ]; then + rm -f "$safe_mysql_unix_port" + fi + if [ ! -h "$pid_file" ]; then + rm -f "$pid_file" + fi start_time=`date +%M%S` eval_log_error "$cmd" - if [ $want_syslog -eq 0 -a ! -f "$err_log" ]; then + if [ $want_syslog -eq 0 -a ! -f "$err_log" -a ! -h "$err_log" ]; then touch "$err_log" # hypothetical: log was renamed but not chown $user "$err_log" # flushed yet. we'd recreate it with chmod "$fmode" "$err_log" # wrong owner next time we log, so set diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index 7487d5acc0f9d..909d33f877085 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -280,7 +280,7 @@ case "$mode" in then # Give extra arguments to mysqld with the my.cnf file. This script # may be overwritten at next upgrade. - $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 & + $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null & wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$? # Make lock for RedHat / SuSE From 4e5473862e6852b0f3802b0cd0c6fa10b5253291 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Tue, 16 Aug 2016 15:35:19 +0200 Subject: [PATCH 20/33] Bug#24388746: PRIVILEGE ESCALATION AND RACE CONDITION USING CREATE TABLE During REPAIR TABLE of a MyISAM table, a temporary data file (.TMD) is created. When repair finishes, this file is renamed to the original .MYD file. The problem was that during this rename, we copied the stats from the old file to the new file with chmod/chown. If a user managed to replace the temporary file before chmod/chown was executed, it was possible to get an arbitrary file with the privileges of the mysql user. This patch fixes the problem by not copying stats from the old file to the new file. This is not needed as the new file was created with the correct stats. This fix only changes server behavior - external utilities such as myisamchk still does chmod/chown. No test case provided since the problem involves synchronization with file system operations. --- include/my_sys.h | 3 ++- include/myisam.h | 11 +++++----- mysys/my_redel.c | 12 ++++++++--- storage/myisam/ha_myisam.cc | 26 ++++++++++++++++++----- storage/myisam/mi_check.c | 41 ++++++++++++++++++++++++++----------- storage/myisam/myisamchk.c | 16 +++++++++------ 6 files changed, 77 insertions(+), 32 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index b1b8bf15be328..472c2ba5ca069 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -83,6 +83,7 @@ typedef struct my_aio_result { #define MY_RESOLVE_LINK 128 /* my_realpath(); Only resolve links */ #define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */ #define MY_REDEL_MAKE_BACKUP 256 +#define MY_REDEL_NO_COPY_STAT 512 /* my_redel() doesn't call my_copystat() */ #define MY_SEEK_NOT_DONE 32 /* my_lock may have to do a seek */ #define MY_DONT_WAIT 64 /* my_lock() don't wait if can't lock */ #define MY_ZEROFILL 32 /* my_malloc(), fill array with zero */ diff --git a/include/myisam.h b/include/myisam.h index 85d37a81bc699..a9fcd7e436975 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -426,12 +426,13 @@ int chk_size(MI_CHECK *param, MI_INFO *info); int chk_key(MI_CHECK *param, MI_INFO *info); int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend); int mi_repair(MI_CHECK *param, register MI_INFO *info, - char * name, int rep_quick); -int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name); + char * name, int rep_quick, my_bool no_copy_stat); +int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name, + my_bool no_copy_stat); int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, - const char * name, int rep_quick); + const char * name, int rep_quick, my_bool no_copy_stat); int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, - const char * name, int rep_quick); + const char * name, int rep_quick, my_bool no_copy_stat); int change_to_newfile(const char * filename, const char * old_ext, const char * new_ext, myf myflags); int lock_file(MI_CHECK *param, File file, my_off_t start, int lock_type, diff --git a/mysys/my_redel.c b/mysys/my_redel.c index a47df8265c808..25391cd4e8fa0 100644 --- a/mysys/my_redel.c +++ b/mysys/my_redel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,6 +35,9 @@ struct utimbuf { if MY_REDEL_MAKE_COPY is given, then the orginal file is renamed to org_name-'current_time'.BAK + + if MY_REDEL_NO_COPY_STAT is given, stats are not copied + from org_name to tmp_name. */ #define REDEL_EXT ".BAK" @@ -46,8 +49,11 @@ int my_redel(const char *org_name, const char *tmp_name, myf MyFlags) DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %d", org_name,tmp_name,MyFlags)); - if (my_copystat(org_name,tmp_name,MyFlags) < 0) - goto end; + if (!(MyFlags & MY_REDEL_NO_COPY_STAT)) + { + if (my_copystat(org_name,tmp_name,MyFlags) < 0) + goto end; + } if (MyFlags & MY_REDEL_MAKE_BACKUP) { char name_buff[FN_REFLEN+20]; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 602a0ae6cc11f..21cbef32188ef 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1091,24 +1091,36 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) /* TODO: respect myisam_repair_threads variable */ my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map)); thd_proc_info(thd, buf); + /* + The new file is created with the right stats, so we can skip + copying file stats from old to new. + */ error = mi_repair_parallel(¶m, file, fixed_name, - param.testflag & T_QUICK); + param.testflag & T_QUICK, TRUE); thd_proc_info(thd, "Repair done"); // to reset proc_info, as // it was pointing to local buffer } else { thd_proc_info(thd, "Repair by sorting"); + /* + The new file is created with the right stats, so we can skip + copying file stats from old to new. + */ error = mi_repair_by_sort(¶m, file, fixed_name, - param.testflag & T_QUICK); + param.testflag & T_QUICK, TRUE); } } else { thd_proc_info(thd, "Repair with keycache"); param.testflag &= ~T_REP_BY_SORT; + /* + The new file is created with the right stats, so we can skip + copying file stats from old to new. + */ error= mi_repair(¶m, file, fixed_name, - param.testflag & T_QUICK); + param.testflag & T_QUICK, TRUE); } #ifdef HAVE_MMAP if (remap) @@ -1124,7 +1136,11 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) { optimize_done=1; thd_proc_info(thd, "Sorting index"); - error=mi_sort_index(¶m,file,fixed_name); + /* + The new file is created with the right stats, so we can skip + copying file stats from old to new. + */ + error=mi_sort_index(¶m,file,fixed_name, TRUE); } if (!statistics_done && (local_testflag & T_STATISTICS)) { diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index ba1f975549a1c..fe0d4c9c30b47 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1512,7 +1512,7 @@ static int mi_drop_all_indexes(MI_CHECK *param, MI_INFO *info, my_bool force) /* Save new datafile-name in temp_filename */ int mi_repair(MI_CHECK *param, register MI_INFO *info, - char * name, int rep_quick) + char * name, int rep_quick, my_bool no_copy_stat) { int error,got_error; ha_rows start_records,new_header_length; @@ -1726,6 +1726,11 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, /* Replace the actual file with the temporary file */ if (new_file >= 0) { + myf flags= 0; + if (param->testflag & T_BACKUP_DATA) + flags |= MY_REDEL_MAKE_BACKUP; + if (no_copy_stat) + flags |= MY_REDEL_NO_COPY_STAT; mysql_file_close(new_file, MYF(0)); info->dfile=new_file= -1; /* @@ -1744,8 +1749,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, info->s->file_map= NULL; } if (change_to_newfile(share->data_file_name, MI_NAME_DEXT, DATA_TMP_EXT, - (param->testflag & T_BACKUP_DATA ? - MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || + flags) || mi_open_datafile(info,share,name,-1)) got_error=1; @@ -1933,7 +1937,8 @@ int flush_blocks(MI_CHECK *param, KEY_CACHE *key_cache, File file) /* Sort index for more efficent reads */ -int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name) +int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name, + my_bool no_copy_stat) { reg2 uint key; reg1 MI_KEYDEF *keyinfo; @@ -2004,7 +2009,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name) share->kfile = -1; (void) mysql_file_close(new_file, MYF(MY_WME)); if (change_to_newfile(share->index_file_name, MI_NAME_IEXT, INDEX_TMP_EXT, - MYF(0)) || + no_copy_stat ? MYF(MY_REDEL_NO_COPY_STAT) : MYF(0)) || mi_open_keyfile(share)) goto err2; info->lock_type= F_UNLCK; /* Force mi_readinfo to lock */ @@ -2209,6 +2214,8 @@ int filecopy(MI_CHECK *param, File to,File from,my_off_t start, info MyISAM handler to repair name Name of table (for warnings) rep_quick set to <> 0 if we should not change data file + no_copy_stat Don't copy file stats from old to new file, + assume that new file was created with correct stats RESULT 0 ok @@ -2216,7 +2223,7 @@ int filecopy(MI_CHECK *param, File to,File from,my_off_t start, */ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, - const char * name, int rep_quick) + const char * name, int rep_quick, my_bool no_copy_stat) { int got_error; uint i; @@ -2543,11 +2550,15 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, /* Replace the actual file with the temporary file */ if (new_file >= 0) { + myf flags= 0; + if (param->testflag & T_BACKUP_DATA) + flags |= MY_REDEL_MAKE_BACKUP; + if (no_copy_stat) + flags |= MY_REDEL_NO_COPY_STAT; mysql_file_close(new_file, MYF(0)); info->dfile=new_file= -1; if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, DATA_TMP_EXT, - (param->testflag & T_BACKUP_DATA ? - MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || + flags) || mi_open_datafile(info,share,name,-1)) got_error=1; } @@ -2595,6 +2606,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, info MyISAM handler to repair name Name of table (for warnings) rep_quick set to <> 0 if we should not change data file + no_copy_stat Don't copy file stats from old to new file, + assume that new file was created with correct stats DESCRIPTION Same as mi_repair_by_sort but do it multithreaded @@ -2629,7 +2642,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, */ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, - const char * name, int rep_quick) + const char * name, int rep_quick, my_bool no_copy_stat) { int got_error; uint i,key, total_key_length, istep; @@ -3076,11 +3089,15 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, /* Replace the actual file with the temporary file */ if (new_file >= 0) { + myf flags= 0; + if (param->testflag & T_BACKUP_DATA) + flags |= MY_REDEL_MAKE_BACKUP; + if (no_copy_stat) + flags |= MY_REDEL_NO_COPY_STAT; mysql_file_close(new_file, MYF(0)); info->dfile=new_file= -1; if (change_to_newfile(share->data_file_name, MI_NAME_DEXT, DATA_TMP_EXT, - (param->testflag & T_BACKUP_DATA ? - MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || + flags) || mi_open_datafile(info,share,name,-1)) got_error=1; } diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 8606bd7c74868..9360a0548726a 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -993,14 +993,18 @@ static int myisamchk(MI_CHECK *param, char * filename) info->s->state.key_map, param->force_sort)) { + /* + The new file might not be created with the right stats depending + on how myisamchk is run, so we must copy file stats from old to new. + */ if (param->testflag & T_REP_BY_SORT) - error=mi_repair_by_sort(param,info,filename,rep_quick); + error= mi_repair_by_sort(param, info, filename, rep_quick, FALSE); else - error=mi_repair_parallel(param,info,filename,rep_quick); + error= mi_repair_parallel(param, info, filename, rep_quick, FALSE); state_updated=1; } else if (param->testflag & T_REP_ANY) - error=mi_repair(param, info,filename,rep_quick); + error= mi_repair(param, info, filename, rep_quick, FALSE); } if (!error && param->testflag & T_SORT_RECORDS) { @@ -1040,12 +1044,12 @@ static int myisamchk(MI_CHECK *param, char * filename) { if (param->verbose) puts("Table had a compressed index; We must now recreate the index"); - error=mi_repair_by_sort(param,info,filename,1); + error= mi_repair_by_sort(param, info, filename, 1, FALSE); } } } if (!error && param->testflag & T_SORT_INDEX) - error=mi_sort_index(param,info,filename); + error= mi_sort_index(param, info, filename, FALSE); if (!error) share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED | STATE_CRASHED_ON_REPAIR); From 48bd8b16fe382be302c6f0b45931be5aa6f29a0e Mon Sep 17 00:00:00 2001 From: Sivert Sorumgard Date: Mon, 22 Aug 2016 14:30:02 +0200 Subject: [PATCH 21/33] Bug#24388753: PRIVILEGE ESCALATION USING MYSQLD_SAFE [This is the 5.5/5.6 version of the bugfix]. The problem was that it was possible to write log files ending in .ini/.cnf that later could be parsed as an options file. This made it possible for users to specify startup options without the permissions to do so. This patch fixes the problem by disallowing general query log and slow query log to be written to files ending in .ini and .cnf. --- sql/log.cc | 89 +++++++++++++++++++++++++++++++++++++++++++++++-- sql/log.h | 10 ++++++ sql/mysqld.cc | 18 +++++++++- sql/sys_vars.cc | 25 +++++++++----- 4 files changed, 131 insertions(+), 11 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 50d7762af6d7a..493aae8f2ff17 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2293,6 +2293,77 @@ bool MYSQL_LOG::init_and_set_log_file_name(const char *log_name, } +bool is_valid_log_name(const char *name, size_t len) +{ + if (len > 3) + { + const char *tail= name + len - 4; + if (my_strcasecmp(system_charset_info, tail, ".ini") == 0 || + my_strcasecmp(system_charset_info, tail, ".cnf") == 0) + { + return false; + } + } + return true; +} + + +/** + Get the real log file name, and possibly reopen file. + + Use realpath() to get the path with symbolic links + expanded. Then, close the file, and reopen the real path using the + O_NOFOLLOW flag. This will reject following symbolic links. + + @param file File descriptor. + @param log_file_key Key for P_S instrumentation. + @param open_flags Flags to use for opening the file. + @param opened_file_name Name of the open fd. + + @retval file descriptor to open file with 'real_file_name', or '-1' + in case of errors. +*/ + +#ifndef _WIN32 +static File mysql_file_real_name_reopen(File file, +#ifdef HAVE_PSI_INTERFACE + PSI_file_key log_file_key, +#endif + int open_flags, + const char *opened_file_name) +{ + DBUG_ASSERT(file); + DBUG_ASSERT(opened_file_name); + + /* Buffer for realpath must have capacity for PATH_MAX. */ + char real_file_name[PATH_MAX]; + + /* Get realpath, validate, open realpath with O_NOFOLLOW. */ + if (realpath(opened_file_name, real_file_name) == NULL) + { + (void) mysql_file_close(file, MYF(0)); + return -1; + } + + if (mysql_file_close(file, MYF(0))) + return -1; + + if (strlen(real_file_name) > FN_REFLEN) + return -1; + + if (!is_valid_log_name(real_file_name, strlen(real_file_name))) + { + sql_print_error("Invalid log file name after expanding symlinks: '%s'", + real_file_name); + return -1; + } + + return mysql_file_open(log_file_key, real_file_name, + open_flags | O_NOFOLLOW, + MYF(MY_WME | ME_WAITTANG)); +} +#endif // _WIN32 + /* Open a (new) log file. @@ -2358,8 +2429,22 @@ bool MYSQL_LOG::open( if ((file= mysql_file_open(log_file_key, log_file_name, open_flags, - MYF(MY_WME | ME_WAITTANG))) < 0 || - init_io_cache(&log_file, file, IO_SIZE, io_cache_type, + MYF(MY_WME | ME_WAITTANG))) < 0) + goto err; + +#ifndef _WIN32 + /* Reopen and validate path. */ + if ((log_type_arg == LOG_UNKNOWN || log_type_arg == LOG_NORMAL) && + (file= mysql_file_real_name_reopen(file, +#ifdef HAVE_PSI_INTERFACE + log_file_key, +#endif + open_flags, + log_file_name)) < 0) + goto err; +#endif // _WIN32 + + if (init_io_cache(&log_file, file, IO_SIZE, io_cache_type, mysql_file_tell(file, MYF(MY_WME)), 0, MYF(MY_WME | MY_NABP | ((log_type == LOG_BIN) ? MY_WAIT_IF_FULL : 0)))) diff --git a/sql/log.h b/sql/log.h index b5e751386a60d..d3ecba419645f 100644 --- a/sql/log.h +++ b/sql/log.h @@ -717,6 +717,16 @@ File open_binlog(IO_CACHE *log, const char *log_file_name, char *make_log_name(char *buff, const char *name, const char* log_ext); +/** + Check given log name against certain blacklisted names/extensions. + + @param name Log name to check + @param len Length of log name + + @returns true if name is valid, false otherwise. +*/ +bool is_valid_log_name(const char *name, size_t len); + extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG mysql_bin_log; extern LOGGER logger; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a2532ceddd396..e979ea1b731a9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify @@ -3512,6 +3512,22 @@ static int init_common_variables() "--log-slow-queries option, log tables are used. " "To enable logging to files use the --log-output=file option."); + if (opt_logname && + !is_valid_log_name(opt_logname, strlen(opt_logname))) + { + sql_print_error("Invalid value for --general_log_file: %s", + opt_logname); + return 1; + } + + if (opt_slow_logname && + !is_valid_log_name(opt_slow_logname, strlen(opt_slow_logname))) + { + sql_print_error("Invalid value for --slow_query_log_file: %s", + opt_slow_logname); + return 1; + } + #define FIX_LOG_VAR(VAR, ALT) \ if (!VAR || !*VAR) \ { \ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index b0fa7f9a341fb..d08cb4f8ca838 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2810,6 +2810,14 @@ static bool check_log_path(sys_var *self, THD *thd, set_var *var) if (!var->save_result.string_value.str) return true; + if (!is_valid_log_name(var->save_result.string_value.str, + var->save_result.string_value.length)) + { + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), + self->name.str, var->save_result.string_value.str); + return true; + } + if (var->save_result.string_value.length > FN_REFLEN) { // path is too long my_error(ER_PATH_LENGTH, MYF(0), self->name.str); @@ -2856,7 +2864,7 @@ static bool check_log_path(sys_var *self, THD *thd, set_var *var) return false; } static bool fix_log(char** logname, const char* default_logname, - const char*ext, bool enabled, void (*reopen)(char*)) + const char*ext, bool enabled, bool (*reopen)(char*)) { if (!*logname) // SET ... = DEFAULT { @@ -2868,16 +2876,17 @@ static bool fix_log(char** logname, const char* default_logname, } logger.lock_exclusive(); mysql_mutex_unlock(&LOCK_global_system_variables); + bool error= false; if (enabled) - reopen(*logname); + error= reopen(*logname); logger.unlock(); mysql_mutex_lock(&LOCK_global_system_variables); - return false; + return error; } -static void reopen_general_log(char* name) +static bool reopen_general_log(char* name) { logger.get_log_file_handler()->close(0); - logger.get_log_file_handler()->open_query_log(name); + return logger.get_log_file_handler()->open_query_log(name); } static bool fix_general_log_file(sys_var *self, THD *thd, enum_var_type type) { @@ -2890,10 +2899,10 @@ static Sys_var_charptr Sys_general_log_path( IN_FS_CHARSET, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_log_path), ON_UPDATE(fix_general_log_file)); -static void reopen_slow_log(char* name) +static bool reopen_slow_log(char* name) { logger.get_slow_log_file_handler()->close(0); - logger.get_slow_log_file_handler()->open_slow_log(name); + return logger.get_slow_log_file_handler()->open_slow_log(name); } static bool fix_slow_log_file(sys_var *self, THD *thd, enum_var_type type) { From 754e7eff2872995e2b6e62f9da7448587a411c7b Mon Sep 17 00:00:00 2001 From: Terje Rosten Date: Fri, 26 Aug 2016 11:25:40 +0200 Subject: [PATCH 22/33] Bug#24464380 PRIVILEGE ESCALATION USING MYSQLD_SAFE Post push fix: Solaris 10 /bin/sh don't understand $(). --- scripts/mysqld_safe.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 11b692ec92874..1b30a3bb15ba2 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -321,7 +321,7 @@ set_malloc_lib() { if [ "$malloc_lib" = tcmalloc ]; then malloc_lib= - for libdir in $(echo $malloc_dirs); do + for libdir in `echo $malloc_dirs`; do for flavor in _minimal '' _and_profiler _debug; do tmp="$libdir/libtcmalloc$flavor.so" #log_notice "DEBUG: Checking for malloc lib '$tmp'" @@ -348,7 +348,7 @@ set_malloc_lib() { fi # Restrict to a the list in $malloc_dirs above - case "$(dirname "$malloc_lib")" in + case "`dirname "$malloc_lib"`" in /usr/lib) ;; /usr/lib64) ;; /usr/lib/i386-linux-gnu) ;; From b9631e310b7cadf8711eef643e432d7e816680b4 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Tue, 10 Nov 2015 12:41:26 +0100 Subject: [PATCH 23/33] MDEV-8833 Crash of server on prepared statement with conversion to semi-join Correct context chain made to allow outer fields pullout. --- mysql-test/r/ps.result | 33 ++++++++++++++++++++++++++++++++- mysql-test/t/ps.test | 29 ++++++++++++++++++++++++++++- sql/item.cc | 23 +++++++++++++++++++++-- 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 04a19d3840f16..bb8b76faa49b4 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -4072,4 +4072,35 @@ id value deallocate prepare stmt; SET SESSION sql_mode = @save_sql_mode; DROP TABLE t1,t2; -# End of 10.0 tests +# +# MDEV-8833: Crash of server on prepared statement with +# conversion to semi-join +# +CREATE TABLE t1 (column1 INT); +INSERT INTO t1 VALUES (3),(9); +CREATE TABLE t2 (column2 INT); +INSERT INTO t2 VALUES (1),(4); +CREATE TABLE t3 (column3 INT); +INSERT INTO t3 VALUES (6),(8); +CREATE TABLE t4 (column4 INT); +INSERT INTO t4 VALUES (2),(5); +PREPARE stmt FROM "SELECT ( SELECT MAX( table1.column1 ) AS field1 +FROM t1 AS table1 +WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS table2 ) +) AS sq +FROM t3 AS table3, t4 AS table4"; +EXECUTE stmt; +sq +NULL +NULL +NULL +NULL +EXECUTE stmt; +sq +NULL +NULL +NULL +NULL +deallocate prepare stmt; +drop table t1,t2,t3,t4; +# End of 5.5 tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 2ed5bb11bacbd..1516acca01efd 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3653,5 +3653,32 @@ deallocate prepare stmt; SET SESSION sql_mode = @save_sql_mode; DROP TABLE t1,t2; +--echo # +--echo # MDEV-8833: Crash of server on prepared statement with +--echo # conversion to semi-join +--echo # + +CREATE TABLE t1 (column1 INT); +INSERT INTO t1 VALUES (3),(9); + +CREATE TABLE t2 (column2 INT); +INSERT INTO t2 VALUES (1),(4); + +CREATE TABLE t3 (column3 INT); +INSERT INTO t3 VALUES (6),(8); + +CREATE TABLE t4 (column4 INT); +INSERT INTO t4 VALUES (2),(5); + +PREPARE stmt FROM "SELECT ( SELECT MAX( table1.column1 ) AS field1 +FROM t1 AS table1 +WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS table2 ) +) AS sq +FROM t3 AS table3, t4 AS table4"; +EXECUTE stmt; +EXECUTE stmt; +deallocate prepare stmt; +drop table t1,t2,t3,t4; + ---echo # End of 10.0 tests +--echo # End of 5.5 tests diff --git a/sql/item.cc b/sql/item.cc index 5861766371cfd..abcf48fc270a0 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2778,9 +2778,28 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref) if (context) { Name_resolution_context *ctx= new Name_resolution_context(); - ctx->outer_context= NULL; // We don't build a complete name resolver - ctx->table_list= NULL; // We rely on first_name_resolution_table instead + if (context->select_lex == new_parent) + { + /* + This field was pushed in then pulled out + (for example left part of IN) + */ + ctx->outer_context= context->outer_context; + } + else if (context->outer_context) + { + /* just pull to the upper context */ + ctx->outer_context= context->outer_context->outer_context; + } + else + { + /* No upper context (merging Derived/VIEW where context chain ends) */ + ctx->outer_context= NULL; + } + ctx->table_list= context->first_name_resolution_table; ctx->select_lex= new_parent; + if (context->select_lex == NULL) + ctx->select_lex= NULL; ctx->first_name_resolution_table= context->first_name_resolution_table; ctx->last_name_resolution_table= context->last_name_resolution_table; ctx->error_processor= context->error_processor; From a2290919533df16afdfdbd0679f80734b5a36109 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 11 Sep 2016 20:52:00 +0200 Subject: [PATCH 24/33] potential signedness issue different fix for 07a33cdcef: Bug #23296299 : HANDLE_FATAL_SIGNAL (SIG=11) IN MY_TOSORT_UTF32 --- mysql-test/r/ctype_utf32.result | 3 +++ mysql-test/t/ctype_utf32.test | 5 +++++ strings/ctype-ucs2.c | 14 +++++++------- strings/ctype-utf8.c | 8 ++++---- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/ctype_utf32.result b/mysql-test/r/ctype_utf32.result index 1f316b7b68fe8..ae55f2c101ed9 100644 --- a/mysql-test/r/ctype_utf32.result +++ b/mysql-test/r/ctype_utf32.result @@ -1269,6 +1269,9 @@ CHAR_LENGTH(TRIM(BOTH 0x61 FROM _utf32 0x00000061)) SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _utf32 0x00000061)); CHAR_LENGTH(TRIM(BOTH 0x00 FROM _utf32 0x00000061)) 1 +select hex(lower(cast(0xffff0000 as char character set utf32))) as c; +c +FFFF0000 # # End of 5.5 tests # diff --git a/mysql-test/t/ctype_utf32.test b/mysql-test/t/ctype_utf32.test index 1be8925873c41..8cbb8e2e55e19 100644 --- a/mysql-test/t/ctype_utf32.test +++ b/mysql-test/t/ctype_utf32.test @@ -876,6 +876,11 @@ SELECT CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _utf32 0x00000061)); SELECT CHAR_LENGTH(TRIM(BOTH 0x61 FROM _utf32 0x00000061)); SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _utf32 0x00000061)); +# +# potential signedness issue +# +select hex(lower(cast(0xffff0000 as char character set utf32))) as c; + --echo # --echo # End of 5.5 tests --echo # diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index a79f5899ec542..ca6f53f3f8d7c 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1,5 +1,5 @@ /* Copyright (c) 2003, 2013, Oracle and/or its affiliates - Copyright (c) 2009, 2014, SkySQL Ab. + Copyright (c) 2009, 2016, MariaDB This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -1098,7 +1098,7 @@ my_uni_utf16(CHARSET_INFO *cs __attribute__((unused)), static inline void my_tolower_utf16(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) { - int page= *wc >> 8; + uint page= *wc >> 8; if (page < 256 && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].tolower; } @@ -1107,7 +1107,7 @@ my_tolower_utf16(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) static inline void my_toupper_utf16(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) { - int page= *wc >> 8; + uint page= *wc >> 8; if (page < 256 && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].toupper; } @@ -1116,7 +1116,7 @@ my_toupper_utf16(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) static inline void my_tosort_utf16(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) { - int page= *wc >> 8; + uint page= *wc >> 8; if (page < 256) { if (uni_plane[page]) @@ -1727,7 +1727,7 @@ my_uni_utf32(CHARSET_INFO *cs __attribute__((unused)), static inline void my_tolower_utf32(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) { - int page= *wc >> 8; + uint page= *wc >> 8; if (page < 256 && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].tolower; } @@ -1736,7 +1736,7 @@ my_tolower_utf32(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) static inline void my_toupper_utf32(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) { - int page= *wc >> 8; + uint page= *wc >> 8; if (page < 256 && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].toupper; } @@ -1745,7 +1745,7 @@ my_toupper_utf32(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) static inline void my_tosort_utf32(MY_UNICASE_INFO *const* uni_plane, my_wc_t *wc) { - int page= *wc >> 8; + uint page= *wc >> 8; if (page < 256) { if (uni_plane[page]) diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 2dd7f5e6b921e..f2782657bea70 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2013, Monty Program Ab + Copyright (c) 2009, 2016, MariaDB This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -1939,7 +1939,7 @@ MY_UNICASE_INFO *const my_unicase_turkish[256]= static inline void my_tosort_unicode(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) { - int page= *wc >> 8; + uint page= *wc >> 8; if (page < 256) { if (uni_plane[page]) @@ -5024,7 +5024,7 @@ my_wc_mb_utf8mb4_no_range(CHARSET_INFO *cs __attribute__((unused)), static inline void my_tolower_utf8mb4(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) { - int page= *wc >> 8; + uint page= *wc >> 8; if (page < 256 && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].tolower; } @@ -5033,7 +5033,7 @@ my_tolower_utf8mb4(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) static inline void my_toupper_utf8mb4(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc) { - int page= *wc >> 8; + uint page= *wc >> 8; if (page < 256 && uni_plane[page]) *wc= uni_plane[page][*wc & 0xFF].toupper; } From 611dc0dcf4b39c670daf229f10e43b8b33f6e8c3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 11 Sep 2016 20:53:16 +0200 Subject: [PATCH 25/33] missing element in prelocked_mode_name[] array different fix for a63a250d40: BUG#23509275 :DBUG_PRINT in THD::decide_logging_format prints incorrectly, access out-of-bound --- sql/sql_class.cc | 2 ++ sql/sql_class.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 05a8ee8091c47..62339b2690a62 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4736,9 +4736,11 @@ int THD::decide_logging_format(TABLE_LIST *tables) { static const char *prelocked_mode_name[] = { "NON_PRELOCKED", + "LOCK_TABLES", "PRELOCKED", "PRELOCKED_UNDER_LOCK_TABLES", }; + compile_time_assert(array_elements(prelocked_mode_name) == LTM_always_last); DBUG_PRINT("debug", ("prelocked_mode: %s", prelocked_mode_name[locked_tables_mode])); } diff --git a/sql/sql_class.h b/sql/sql_class.h index da83382d5e93b..27bc40e3761ec 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1075,7 +1075,8 @@ enum enum_locked_tables_mode LTM_NONE= 0, LTM_LOCK_TABLES, LTM_PRELOCKED, - LTM_PRELOCKED_UNDER_LOCK_TABLES + LTM_PRELOCKED_UNDER_LOCK_TABLES, + LTM_always_last }; From 347eeefbfc658c8531878218487d729f4e020805 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 11 Sep 2016 20:55:11 +0200 Subject: [PATCH 26/33] don't use my_copystat in the server it was supposed to be used in command-line tools only. Different fix for 4e5473862e: Bug#24388746: PRIVILEGE ESCALATION AND RACE CONDITION USING CREATE TABLE --- include/my_sys.h | 4 ++-- mysys/my_redel.c | 7 ++++--- mysys/my_static.c | 1 + sql/mysqld.cc | 1 + 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 7e37fe598bd3e..001769a0b76fc 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2013, Monty Program Ab. + Copyright (c) 2010, 2016, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -246,7 +246,7 @@ extern my_bool my_use_symdir; extern ulong my_default_record_cache_size; extern my_bool my_disable_locking, my_disable_async_io, my_disable_flush_key_blocks, my_disable_symlinks; -extern my_bool my_disable_sync; +extern my_bool my_disable_sync, my_disable_copystat_in_redel; extern char wild_many,wild_one,wild_prefix; extern const char *charsets_dir; /* from default.c */ diff --git a/mysys/my_redel.c b/mysys/my_redel.c index b285bb25e2e88..e5e4f48d9d5ec 100644 --- a/mysys/my_redel.c +++ b/mysys/my_redel.c @@ -1,5 +1,5 @@ -/* - Copyright (c) 2000, 2010, Oracle and/or its affiliates +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates + Copyright (c) 2009, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -49,7 +49,8 @@ int my_redel(const char *org_name, const char *tmp_name, DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %d", org_name,tmp_name,MyFlags)); - if (my_copystat(org_name,tmp_name,MyFlags) < 0) + if (!my_disable_copystat_in_redel && + my_copystat(org_name,tmp_name,MyFlags) < 0) goto end; if (MyFlags & MY_REDEL_MAKE_BACKUP) { diff --git a/mysys/my_static.c b/mysys/my_static.c index fdc01b1248b22..48b1e5b8dd9a5 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -99,6 +99,7 @@ my_bool my_disable_sync=0; my_bool my_disable_async_io=0; my_bool my_disable_flush_key_blocks=0; my_bool my_disable_symlinks=0; +my_bool my_disable_copystat_in_redel=0; /* Note that PSI_hook and PSI_server are unconditionally diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9b8f964629d59..be9e21d6746d8 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3455,6 +3455,7 @@ static int init_common_variables() max_system_variables.pseudo_thread_id= (ulong)~0; server_start_time= flush_status_time= my_time(0); + my_disable_copystat_in_redel= 1; rpl_filter= new Rpl_filter; binlog_filter= new Rpl_filter; From 0da39caceea7733a94d898427d63ba2670160af4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 12 Sep 2016 16:18:07 +0200 Subject: [PATCH 27/33] fix BIGINT+MEDIUMINT type aggregation --- mysql-test/r/type_uint.result | 19 +++++++++++++++++++ mysql-test/t/type_uint.test | 8 ++++++++ sql/field.cc | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/type_uint.result b/mysql-test/r/type_uint.result index e08605fb237e0..d67c735f067a8 100644 --- a/mysql-test/r/type_uint.result +++ b/mysql-test/r/type_uint.result @@ -14,3 +14,22 @@ this 0 4294967295 drop table t1; +create table t1 (a bigint unsigned, b mediumint unsigned); +insert t1 values (1,2),(0xffffffffffffffff,0xffffff); +select coalesce(a,b), coalesce(b,a) from t1; +coalesce(a,b) coalesce(b,a) +1 2 +18446744073709551615 16777215 +create table t2 as select a from t1 union select b from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` bigint(20) unsigned DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from t2; +a +1 +18446744073709551615 +2 +16777215 +drop table t1, t2; diff --git a/mysql-test/t/type_uint.test b/mysql-test/t/type_uint.test index a9212183cb61c..14e5e3bd6213c 100644 --- a/mysql-test/t/type_uint.test +++ b/mysql-test/t/type_uint.test @@ -15,3 +15,11 @@ select * from t1; drop table t1; # End of 4.1 tests + +create table t1 (a bigint unsigned, b mediumint unsigned); +insert t1 values (1,2),(0xffffffffffffffff,0xffffff); +select coalesce(a,b), coalesce(b,a) from t1; +create table t2 as select a from t1 union select b from t1; +show create table t2; +select * from t2; +drop table t1, t2; diff --git a/sql/field.cc b/sql/field.cc index a0686fb2f1974..878e3d305af9f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -359,7 +359,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP MYSQL_TYPE_LONGLONG, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 - MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONG, + MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG, //MYSQL_TYPE_DATE MYSQL_TYPE_TIME MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR From b3f7a8019dae01ed03353856f62543248e6f9cd9 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Tue, 13 Sep 2016 11:12:54 -0400 Subject: [PATCH 28/33] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index acabf9b42d0ca..d44c8b2800612 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=52 +MYSQL_VERSION_PATCH=53 MYSQL_VERSION_EXTRA= From 943443137460cab6499c032f0e5a03256daa9571 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Sat, 24 Sep 2016 13:50:42 +0200 Subject: [PATCH 29/33] Fix free() after my_malloc() (should be my_free()). Signed-off-by: Kristian Nielsen --- tests/async_queries.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/async_queries.c b/tests/async_queries.c index 75229eec4b43c..c91edf5bb3b24 100644 --- a/tests/async_queries.c +++ b/tests/async_queries.c @@ -425,7 +425,7 @@ main(int argc, char *argv[]) event_dispatch(); - free(sds); + my_free(sds); mysql_library_end(); From f620da194befe4506679ad7f1d0725796fad7de0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 24 Sep 2016 01:17:35 +0200 Subject: [PATCH 30/33] MDEV-10725 Server 10.1.17 fails to build using clang with c++11 my_offsetof() returns a difference of two pointers, it must use the appropriate return type (my_ptrdiff_t, not size_t) --- include/my_global.h | 3 +-- sql/parse_file.h | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index dce38a124c125..0c15478439f38 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -857,8 +857,7 @@ typedef long long my_ptrdiff_t; and related routines are refactored. */ -#define my_offsetof(TYPE, MEMBER) \ - ((size_t)((char *)&(((TYPE *)0x10)->MEMBER) - (char*)0x10)) +#define my_offsetof(TYPE, MEMBER) PTR_BYTE_DIFF(&((TYPE *)0x10)->MEMBER, 0x10) #define NullS (char *) 0 diff --git a/sql/parse_file.h b/sql/parse_file.h index 2a0266e98b7eb..83a8eabcf5f72 100644 --- a/sql/parse_file.h +++ b/sql/parse_file.h @@ -42,9 +42,9 @@ enum file_opt_type { struct File_option { - LEX_STRING name; /**< Name of the option */ - int offset; /**< offset to base address of value */ - file_opt_type type; /**< Option type */ + LEX_STRING name; /**< Name of the option */ + my_ptrdiff_t offset; /**< offset to base address of value */ + file_opt_type type; /**< Option type */ }; From 8483659f4f017285a878ce563c1c756ee3e4d3dc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 24 Sep 2016 10:06:58 +0200 Subject: [PATCH 31/33] report correct write error on log writes --- sql/log.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/log.cc b/sql/log.cc index da45a844bb3f1..bb8f06c80f7fe 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2863,7 +2863,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, if (! write_error) { write_error= 1; - sql_print_error(ER(ER_ERROR_ON_WRITE), name, error); + sql_print_error(ER(ER_ERROR_ON_WRITE), name, tmp_errno); } } } From c91fdb66dbd26d832073e7b99075bfd0b5b9da11 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 26 Sep 2016 13:03:02 +0200 Subject: [PATCH 32/33] Windows , mtr : allow cdb to print core dumps also if --parallel > 1 --- mysql-test/lib/My/CoreDump.pm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mysql-test/lib/My/CoreDump.pm b/mysql-test/lib/My/CoreDump.pm index 0e90967ef9545..f9f7b3d8d4b23 100644 --- a/mysql-test/lib/My/CoreDump.pm +++ b/mysql-test/lib/My/CoreDump.pm @@ -261,11 +261,7 @@ sub show { # On Windows, rely on cdb to be there... if (IS_WINDOWS) { - # Starting cdb is unsafe when used with --parallel > 1 option - if ( $parallel < 2 ) - { - _cdb($core_name); - } + _cdb($core_name); return; } From d61e5260fb9983ea8dff539b23a6d0a150c2065c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 26 Sep 2016 17:48:08 +0200 Subject: [PATCH 33/33] MDEV-10441 Document the server_audit_loc_info variable fix PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT plugin thdvars to work. use that for server_audit_loc_info --- .../suite/plugins/r/server_audit.result | 3 - .../plugins/r/thread_pool_server_audit.result | 3 - plugin/server_audit/server_audit.c | 5 +- sql/sql_plugin.cc | 151 ++++++++---------- 4 files changed, 69 insertions(+), 93 deletions(-) diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index 2dcfa107103a3..c807107534dba 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -8,7 +8,6 @@ server_audit_file_rotate_now OFF server_audit_file_rotate_size 1000000 server_audit_file_rotations 9 server_audit_incl_users -server_audit_loc_info server_audit_logging OFF server_audit_mode 0 server_audit_output_type file @@ -72,7 +71,6 @@ server_audit_file_rotate_now OFF server_audit_file_rotate_size 1000000 server_audit_file_rotations 9 server_audit_incl_users odin, root, dva, tri -server_audit_loc_info server_audit_logging ON server_audit_mode 0 server_audit_output_type file @@ -218,7 +216,6 @@ server_audit_file_rotate_now OFF server_audit_file_rotate_size 1000000 server_audit_file_rotations 9 server_audit_incl_users odin, root, dva, tri -server_audit_loc_info server_audit_logging ON server_audit_mode 1 server_audit_output_type file diff --git a/mysql-test/suite/plugins/r/thread_pool_server_audit.result b/mysql-test/suite/plugins/r/thread_pool_server_audit.result index 2dcfa107103a3..c807107534dba 100644 --- a/mysql-test/suite/plugins/r/thread_pool_server_audit.result +++ b/mysql-test/suite/plugins/r/thread_pool_server_audit.result @@ -8,7 +8,6 @@ server_audit_file_rotate_now OFF server_audit_file_rotate_size 1000000 server_audit_file_rotations 9 server_audit_incl_users -server_audit_loc_info server_audit_logging OFF server_audit_mode 0 server_audit_output_type file @@ -72,7 +71,6 @@ server_audit_file_rotate_now OFF server_audit_file_rotate_size 1000000 server_audit_file_rotations 9 server_audit_incl_users odin, root, dva, tri -server_audit_loc_info server_audit_logging ON server_audit_mode 0 server_audit_output_type file @@ -218,7 +216,6 @@ server_audit_file_rotate_now OFF server_audit_file_rotate_size 1000000 server_audit_file_rotations 9 server_audit_incl_users odin, root, dva, tri -server_audit_loc_info server_audit_logging ON server_audit_mode 1 server_audit_output_type file diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 30b7cdb5dcb0a..95150c82f25ef 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -429,9 +429,8 @@ static MYSQL_SYSVAR_UINT(query_log_limit, query_log_limit, char locinfo_ini_value[sizeof(struct connection_info)+4]; static MYSQL_THDVAR_STR(loc_info, - PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, - "Auxiliary info.", NULL, NULL, - locinfo_ini_value); + PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_MEMALLOC, + "Internal info", NULL, NULL, locinfo_ini_value); static const char *syslog_facility_names[]= { diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index c8c8c8ba32440..2ec67a8974678 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -2756,6 +2756,22 @@ static st_bookmark *find_bookmark(const char *plugin, const char *name, } +static size_t var_storage_size(int flags) +{ + switch (flags & PLUGIN_VAR_TYPEMASK) { + case PLUGIN_VAR_BOOL: return sizeof(my_bool); + case PLUGIN_VAR_INT: return sizeof(int); + case PLUGIN_VAR_LONG: return sizeof(long); + case PLUGIN_VAR_ENUM: return sizeof(long); + case PLUGIN_VAR_LONGLONG: return sizeof(ulonglong); + case PLUGIN_VAR_SET: return sizeof(ulonglong); + case PLUGIN_VAR_STR: return sizeof(char*); + case PLUGIN_VAR_DOUBLE: return sizeof(double); + default: DBUG_ASSERT(0); return 0; + } +} + + /* returns a bookmark for thd-local variables, creating if neccessary. returns null for non thd-local variables. @@ -2764,39 +2780,13 @@ static st_bookmark *find_bookmark(const char *plugin, const char *name, static st_bookmark *register_var(const char *plugin, const char *name, int flags) { - uint length= strlen(plugin) + strlen(name) + 3, size= 0, offset, new_size; + uint length= strlen(plugin) + strlen(name) + 3, size, offset, new_size; st_bookmark *result; char *varname, *p; - if (!(flags & PLUGIN_VAR_THDLOCAL)) - return NULL; - - switch (flags & PLUGIN_VAR_TYPEMASK) { - case PLUGIN_VAR_BOOL: - size= sizeof(my_bool); - break; - case PLUGIN_VAR_INT: - size= sizeof(int); - break; - case PLUGIN_VAR_LONG: - case PLUGIN_VAR_ENUM: - size= sizeof(long); - break; - case PLUGIN_VAR_LONGLONG: - case PLUGIN_VAR_SET: - size= sizeof(ulonglong); - break; - case PLUGIN_VAR_STR: - size= sizeof(char*); - break; - case PLUGIN_VAR_DOUBLE: - size= sizeof(double); - break; - default: - DBUG_ASSERT(0); - return NULL; - }; + DBUG_ASSERT(flags & PLUGIN_VAR_THDLOCAL); + size= var_storage_size(flags); varname= ((char*) my_alloca(length)); strxmov(varname + 1, plugin, "_", name, NullS); for (p= varname + 1; *p; p++) @@ -3005,25 +2995,17 @@ void sync_dynamic_session_variables(THD* thd, bool global_lock) */ for (idx= 0; idx < bookmark_hash.records; idx++) { - sys_var_pluginvar *pi; - sys_var *var; st_bookmark *v= (st_bookmark*) my_hash_element(&bookmark_hash,idx); if (v->version <= thd->variables.dynamic_variables_version) continue; /* already in thd->variables */ - if (!(var= intern_find_sys_var(v->key + 1, v->name_len)) || - !(pi= var->cast_pluginvar()) || - v->key[0] != plugin_var_bookmark_key(pi->plugin_var->flags)) - continue; - /* Here we do anything special that may be required of the data types */ - if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR && - pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC) + if ((v->key[0] & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR && + v->key[0] & BOOKMARK_MEMALLOC) { - int offset= ((thdvar_str_t *)(pi->plugin_var))->offset; - char **pp= (char**) (thd->variables.dynamic_variables_ptr + offset); + char **pp= (char**) (thd->variables.dynamic_variables_ptr + v->offset); if (*pp) *pp= my_strdup(*pp, MYF(MY_WME|MY_FAE)); } @@ -3284,69 +3266,58 @@ bool sys_var_pluginvar::session_update(THD *thd, set_var *var) return false; } -bool sys_var_pluginvar::global_update(THD *thd, set_var *var) +static const void *var_def_ptr(st_mysql_sys_var *pv) { - DBUG_ASSERT(!is_readonly()); - mysql_mutex_assert_owner(&LOCK_global_system_variables); - - void *tgt= real_value_ptr(thd, var->type); - const void *src= &var->save_result; - - if (!var->value) - { - switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_THDLOCAL)) { + switch (pv->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_THDLOCAL)) { case PLUGIN_VAR_INT: - src= &((sysvar_uint_t*) plugin_var)->def_val; - break; + return &((sysvar_uint_t*) pv)->def_val; case PLUGIN_VAR_LONG: - src= &((sysvar_ulong_t*) plugin_var)->def_val; - break; + return &((sysvar_ulong_t*) pv)->def_val; case PLUGIN_VAR_LONGLONG: - src= &((sysvar_ulonglong_t*) plugin_var)->def_val; - break; + return &((sysvar_ulonglong_t*) pv)->def_val; case PLUGIN_VAR_ENUM: - src= &((sysvar_enum_t*) plugin_var)->def_val; - break; + return &((sysvar_enum_t*) pv)->def_val; case PLUGIN_VAR_SET: - src= &((sysvar_set_t*) plugin_var)->def_val; - break; + return &((sysvar_set_t*) pv)->def_val; case PLUGIN_VAR_BOOL: - src= &((sysvar_bool_t*) plugin_var)->def_val; - break; + return &((sysvar_bool_t*) pv)->def_val; case PLUGIN_VAR_STR: - src= &((sysvar_str_t*) plugin_var)->def_val; - break; + return &((sysvar_str_t*) pv)->def_val; case PLUGIN_VAR_DOUBLE: - src= &((sysvar_double_t*) plugin_var)->def_val; - break; + return &((sysvar_double_t*) pv)->def_val; case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL: - src= &((thdvar_uint_t*) plugin_var)->def_val; - break; + return &((thdvar_uint_t*) pv)->def_val; case PLUGIN_VAR_LONG | PLUGIN_VAR_THDLOCAL: - src= &((thdvar_ulong_t*) plugin_var)->def_val; - break; + return &((thdvar_ulong_t*) pv)->def_val; case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL: - src= &((thdvar_ulonglong_t*) plugin_var)->def_val; - break; + return &((thdvar_ulonglong_t*) pv)->def_val; case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL: - src= &((thdvar_enum_t*) plugin_var)->def_val; - break; + return &((thdvar_enum_t*) pv)->def_val; case PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL: - src= &((thdvar_set_t*) plugin_var)->def_val; - break; + return &((thdvar_set_t*) pv)->def_val; case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL: - src= &((thdvar_bool_t*) plugin_var)->def_val; - break; + return &((thdvar_bool_t*) pv)->def_val; case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL: - src= &((thdvar_str_t*) plugin_var)->def_val; - break; + return &((thdvar_str_t*) pv)->def_val; case PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL: - src= &((thdvar_double_t*) plugin_var)->def_val; - break; + return &((thdvar_double_t*) pv)->def_val; default: DBUG_ASSERT(0); + return NULL; } - } +} + + +bool sys_var_pluginvar::global_update(THD *thd, set_var *var) +{ + DBUG_ASSERT(!is_readonly()); + mysql_mutex_assert_owner(&LOCK_global_system_variables); + + void *tgt= real_value_ptr(thd, var->type); + const void *src= &var->save_result; + + if (!var->value) + src= var_def_ptr(plugin_var); plugin_var->update(thd, plugin_var, tgt, src); return false; @@ -3713,7 +3684,18 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, *(int*)(opt + 1)= offset= v->offset; if (opt->flags & PLUGIN_VAR_NOCMDOPT) + { + char *val= global_system_variables.dynamic_variables_ptr + offset; + if (((opt->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR) && + (opt->flags & PLUGIN_VAR_MEMALLOC)) + { + char *def_val= *(char**)var_def_ptr(opt); + *(char**)val= def_val ? my_strdup(def_val, MYF(0)) : NULL; + } + else + memcpy(val, var_def_ptr(opt), var_storage_size(opt->flags)); continue; + } optname= (char*) memdup_root(mem_root, v->key + 1, (optnamelen= v->name_len) + 1); @@ -3912,9 +3894,10 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, *str->value= strdup_root(mem_root, *str->value); } + var= find_bookmark(plugin_name.str, o->name, o->flags); if (o->flags & PLUGIN_VAR_NOSYSVAR) continue; - if ((var= find_bookmark(plugin_name.str, o->name, o->flags))) + if (var) v= new (mem_root) sys_var_pluginvar(&chain, var->key + 1, o, tmp); else {