summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2021-02-26 16:37:24 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2021-03-03 17:27:31 +0530
commit703d69c2a89c57905c47bd9708f6356bbeb9028d (patch)
tree21219f217b77a56eb901b6de4b8ca4a0f3887e47
parent80ac9ec1cc10d56b048272642653d5d301394779 (diff)
downloadmariadb-git-bb-10.6-MDEV-14180_1.tar.gz
MDEV-14180 Automatically disable key rotation checks for file_key_managment pluginbb-10.6-MDEV-14180_1
- InnoDB iterates the fil_system space list to encrypt the tablespace in case of key rotation.But it is not necessary for any encryption plugin which doesn't do any key rotation. InnoDB should avoid key rotation for file key management encryption plugin. Introduce new encryption service called encryption_set_no_rotation() and encryption_get_rotation(). Encryption plugin should call encryption_set_no_rotation() in case it doesn't support key rotation. Introduce a new variable called srv_encrypt_rotate and it should be assigned via encryption_get_rotation(). If it doesn't do key rotation then InnoDB should add the tablespace to rotation list.
-rw-r--r--include/my_crypt.h1
-rw-r--r--include/mysql/plugin_audit.h.pp8
-rw-r--r--include/mysql/plugin_auth.h.pp8
-rw-r--r--include/mysql/plugin_data_type.h.pp8
-rw-r--r--include/mysql/plugin_encryption.h.pp8
-rw-r--r--include/mysql/plugin_ftparser.h.pp8
-rw-r--r--include/mysql/plugin_function.h.pp8
-rw-r--r--include/mysql/plugin_password_validation.h.pp8
-rw-r--r--include/mysql/service_encryption_rotation.h52
-rw-r--r--include/mysql/services.h1
-rw-r--r--include/service_versions.h1
-rw-r--r--libservices/CMakeLists.txt1
-rw-r--r--libservices/encryption_rotation_service.c18
-rw-r--r--mysql-test/suite/encryption/r/innodb-key-rotation-disable.result4
-rw-r--r--mysql-test/suite/encryption/t/innodb-key-rotation-disable.test3
-rw-r--r--mysys/mf_iocache.c25
-rw-r--r--plugin/file_key_management/file_key_management_plugin.cc1
-rw-r--r--sql/sql_plugin_services.ic9
-rw-r--r--storage/innobase/fil/fil0crypt.cc13
-rw-r--r--storage/innobase/fil/fil0fil.cc5
-rw-r--r--storage/innobase/include/fil0crypt.h4
21 files changed, 182 insertions, 12 deletions
diff --git a/include/my_crypt.h b/include/my_crypt.h
index eced2cd400f..5dbfb72eb22 100644
--- a/include/my_crypt.h
+++ b/include/my_crypt.h
@@ -20,5 +20,6 @@
#include <my_config.h> /* HAVE_EncryptAes128{Ctr,Gcm} */
#include <mysql/service_my_crypt.h>
+#include <mysql/service_encryption_rotation.h>
#endif /* MY_CRYPT_INCLUDED */
diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp
index 07fe16ea92f..afda10df035 100644
--- a/include/mysql/plugin_audit.h.pp
+++ b/include/mysql/plugin_audit.h.pp
@@ -464,6 +464,14 @@ int json_escape_string(const char *str,const char *str_end,
int json_unescape_json(const char *json_str, const char *json_end,
char *res, char *res_end);
}
+extern "C" {
+extern struct encryption_rotation_service_st {
+ int (*encrypt_set_no_rotate_ptr)(void);
+ int (*encrypt_get_no_rotate_ptr)(void);
+} *encryption_rotation_service;
+int encryption_set_no_rotation(void);
+int encryption_get_no_rotation(void);
+}
}
struct st_mysql_xid {
long formatID;
diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp
index 18eebd5e04a..ac8c9baa232 100644
--- a/include/mysql/plugin_auth.h.pp
+++ b/include/mysql/plugin_auth.h.pp
@@ -464,6 +464,14 @@ int json_escape_string(const char *str,const char *str_end,
int json_unescape_json(const char *json_str, const char *json_end,
char *res, char *res_end);
}
+extern "C" {
+extern struct encryption_rotation_service_st {
+ int (*encrypt_set_no_rotate_ptr)(void);
+ int (*encrypt_get_no_rotate_ptr)(void);
+} *encryption_rotation_service;
+int encryption_set_no_rotation(void);
+int encryption_get_no_rotation(void);
+}
}
struct st_mysql_xid {
long formatID;
diff --git a/include/mysql/plugin_data_type.h.pp b/include/mysql/plugin_data_type.h.pp
index 3db2fdd0251..b64960a54fb 100644
--- a/include/mysql/plugin_data_type.h.pp
+++ b/include/mysql/plugin_data_type.h.pp
@@ -464,6 +464,14 @@ int json_escape_string(const char *str,const char *str_end,
int json_unescape_json(const char *json_str, const char *json_end,
char *res, char *res_end);
}
+extern "C" {
+extern struct encryption_rotation_service_st {
+ int (*encrypt_set_no_rotate_ptr)(void);
+ int (*encrypt_get_no_rotate_ptr)(void);
+} *encryption_rotation_service;
+int encryption_set_no_rotation(void);
+int encryption_get_no_rotation(void);
+}
}
struct st_mysql_xid {
long formatID;
diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp
index ff436bb24c4..ff87864136f 100644
--- a/include/mysql/plugin_encryption.h.pp
+++ b/include/mysql/plugin_encryption.h.pp
@@ -464,6 +464,14 @@ int json_escape_string(const char *str,const char *str_end,
int json_unescape_json(const char *json_str, const char *json_end,
char *res, char *res_end);
}
+extern "C" {
+extern struct encryption_rotation_service_st {
+ int (*encrypt_set_no_rotate_ptr)(void);
+ int (*encrypt_get_no_rotate_ptr)(void);
+} *encryption_rotation_service;
+int encryption_set_no_rotation(void);
+int encryption_get_no_rotation(void);
+}
}
struct st_mysql_xid {
long formatID;
diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp
index daefd6b2838..268b458613b 100644
--- a/include/mysql/plugin_ftparser.h.pp
+++ b/include/mysql/plugin_ftparser.h.pp
@@ -464,6 +464,14 @@ int json_escape_string(const char *str,const char *str_end,
int json_unescape_json(const char *json_str, const char *json_end,
char *res, char *res_end);
}
+extern "C" {
+extern struct encryption_rotation_service_st {
+ int (*encrypt_set_no_rotate_ptr)(void);
+ int (*encrypt_get_no_rotate_ptr)(void);
+} *encryption_rotation_service;
+int encryption_set_no_rotation(void);
+int encryption_get_no_rotation(void);
+}
}
struct st_mysql_xid {
long formatID;
diff --git a/include/mysql/plugin_function.h.pp b/include/mysql/plugin_function.h.pp
index 0f915c8413f..de053261bb5 100644
--- a/include/mysql/plugin_function.h.pp
+++ b/include/mysql/plugin_function.h.pp
@@ -464,6 +464,14 @@ int json_escape_string(const char *str,const char *str_end,
int json_unescape_json(const char *json_str, const char *json_end,
char *res, char *res_end);
}
+extern "C" {
+extern struct encryption_rotation_service_st {
+ int (*encrypt_set_no_rotate_ptr)(void);
+ int (*encrypt_get_no_rotate_ptr)(void);
+} *encryption_rotation_service;
+int encryption_set_no_rotation(void);
+int encryption_get_no_rotation(void);
+}
}
struct st_mysql_xid {
long formatID;
diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp
index fc8c3848f8c..d0089bc5bca 100644
--- a/include/mysql/plugin_password_validation.h.pp
+++ b/include/mysql/plugin_password_validation.h.pp
@@ -464,6 +464,14 @@ int json_escape_string(const char *str,const char *str_end,
int json_unescape_json(const char *json_str, const char *json_end,
char *res, char *res_end);
}
+extern "C" {
+extern struct encryption_rotation_service_st {
+ int (*encrypt_set_no_rotate_ptr)(void);
+ int (*encrypt_get_no_rotate_ptr)(void);
+} *encryption_rotation_service;
+int encryption_set_no_rotation(void);
+int encryption_get_no_rotation(void);
+}
}
struct st_mysql_xid {
long formatID;
diff --git a/include/mysql/service_encryption_rotation.h b/include/mysql/service_encryption_rotation.h
new file mode 100644
index 00000000000..b5c1a071b25
--- /dev/null
+++ b/include/mysql/service_encryption_rotation.h
@@ -0,0 +1,52 @@
+#ifndef MYSQL_SERVICE_ENCRYPTION_ROTATION_INCLUDED
+/* Copyright (c) 2021, 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
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ encryption rotation service
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdlib.h>
+#endif
+
+extern struct encryption_rotation_service_st {
+ int (*encrypt_set_no_rotate_ptr)(void);
+ int (*encrypt_get_no_rotate_ptr)(void);
+} *encryption_rotation_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define encryption_set_no_rotation() encryption_rotation_service->encrypt_set_no_rotate_ptr()
+#define encryption_get_no_rotation() encryption_rotation_service->encrypt_get_no_rotate_ptr()
+#else
+
+/* Set encryption rotation variable */
+int encryption_set_no_rotation(void);
+
+int encryption_get_no_rotation(void);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_ENCRYPTION_ROTATION_INCLUDED
+#endif
diff --git a/include/mysql/services.h b/include/mysql/services.h
index 2c3a0ae421b..170fe8bcfab 100644
--- a/include/mysql/services.h
+++ b/include/mysql/services.h
@@ -40,6 +40,7 @@ extern "C" {
#include <mysql/service_thd_timezone.h>
#include <mysql/service_thd_wait.h>
#include <mysql/service_json.h>
+#include <mysql/service_encryption_rotation.h>
/*#include <mysql/service_wsrep.h>*/
#ifdef __cplusplus
diff --git a/include/service_versions.h b/include/service_versions.h
index 369826c8a6c..905fd9bd3a9 100644
--- a/include/service_versions.h
+++ b/include/service_versions.h
@@ -44,3 +44,4 @@
#define VERSION_wsrep 0x0203
#define VERSION_json 0x0100
#define VERSION_thd_mdl 0x0100
+#define VERSION_encryption_rotation 0x0100
diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt
index 274c8ce6dac..b5f3b84b71f 100644
--- a/libservices/CMakeLists.txt
+++ b/libservices/CMakeLists.txt
@@ -38,6 +38,7 @@ SET(MYSQLSERVICES_SOURCES
thd_wait_service.c
wsrep_service.c
json_service.c
+ encryption_rotation_service.c
)
ADD_CONVENIENCE_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
diff --git a/libservices/encryption_rotation_service.c b/libservices/encryption_rotation_service.c
new file mode 100644
index 00000000000..fa33552c37c
--- /dev/null
+++ b/libservices/encryption_rotation_service.c
@@ -0,0 +1,18 @@
+/* Copyright (c) 2021 MariaDB
+ Use is subject to license terms.
+
+ 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
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#include <service_versions.h>
+SERVICE_VERSION encryption_rotation_service= (void*)VERSION_encryption_rotation;
diff --git a/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result b/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result
index 02304fbda17..4e816bea43b 100644
--- a/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result
+++ b/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result
@@ -1,7 +1,3 @@
-SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
-NAME
-SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
-NAME
SET GLOBAL innodb_file_per_table = ON;
set global innodb_compression_algorithm = 1;
create database enctests;
diff --git a/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test b/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test
index dffabaf97f1..96b62f7c05b 100644
--- a/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test
+++ b/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test
@@ -3,9 +3,6 @@
# not embedded because of restarts
-- source include/not_embedded.inc
-SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
-SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
-
let $encryption = `SELECT @@innodb_encrypt_tables`;
SET GLOBAL innodb_file_per_table = ON;
# zlib
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 82ab6f20646..8da1bf77ecc 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -55,6 +55,10 @@ TODO:
PSI_file_key key_file_io_cache;
+/* Variable to indicate whether the encryption plugin supports key
+rotation */
+static my_bool encryption_key_no_rotate;
+
#define lock_append_buffer(info) \
mysql_mutex_lock(&(info)->append_buffer_lock)
#define unlock_append_buffer(info) \
@@ -1793,7 +1797,28 @@ int end_io_cache(IO_CACHE *info)
DBUG_RETURN(error);
} /* end_io_cache */
+/*
+ Declare the encryption plugin that it doesn't
+ support key rotation.
+ @return 0 OK
+*/
+int encryption_set_no_rotation()
+{
+ encryption_key_no_rotate= TRUE;
+ return 0;
+}
+/*
+ Function returns whether the encryption plugin supports key rotation
+ @return 1 encryption supports key rotation
+ @return 0 otherwise
+*/
+int encryption_get_no_rotation()
+{
+ if (encryption_key_no_rotate == TRUE)
+ return 0;
+ return 1;
+}
/**********************************************************************
Testing of MF_IOCACHE
**********************************************************************/
diff --git a/plugin/file_key_management/file_key_management_plugin.cc b/plugin/file_key_management/file_key_management_plugin.cc
index 927045ce175..5a42afd4b5c 100644
--- a/plugin/file_key_management/file_key_management_plugin.cc
+++ b/plugin/file_key_management/file_key_management_plugin.cc
@@ -176,6 +176,7 @@ struct st_mariadb_encryption file_key_management_plugin= {
static int file_key_management_plugin_init(void *p)
{
Parser parser(filename, filekey);
+ encryption_set_no_rotation();
return parser.parse(&keys);
}
diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic
index 25fa4b3afd1..5bee96f2838 100644
--- a/sql/sql_plugin_services.ic
+++ b/sql/sql_plugin_services.ic
@@ -231,6 +231,12 @@ static struct thd_mdl_service_st thd_mdl_handler=
thd_mdl_context
};
+static struct encryption_rotation_service_st rotation_handler=
+{
+ encryption_set_no_rotation,
+ encryption_get_no_rotation
+};
+
static struct st_service_ref list_of_services[]=
{
{ "base64_service", VERSION_base64, &base64_handler },
@@ -255,5 +261,6 @@ static struct st_service_ref list_of_services[]=
{ "thd_wait_service", VERSION_thd_wait, &thd_wait_handler },
{ "wsrep_service", VERSION_wsrep, &wsrep_handler },
{ "json_service", VERSION_json, &json_handler },
- { "thd_mdl_service", VERSION_thd_mdl, &thd_mdl_handler }
+ { "thd_mdl_service", VERSION_thd_mdl, &thd_mdl_handler },
+ { "encryption_rotation_service", VERSION_encryption_rotation, &rotation_handler }
};
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index ec8ea6cbe00..2411761f835 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -55,6 +55,8 @@ UNIV_INTERN uint srv_n_fil_crypt_threads_started = 0;
/** At this age or older a space/page will be rotated */
UNIV_INTERN uint srv_fil_crypt_rotate_key_age;
+static bool srv_encrypt_rotate;
+
/** Condition variable for srv_n_fil_crypt_threads_started */
static pthread_cond_t fil_crypt_cond;
@@ -114,6 +116,8 @@ void fil_space_crypt_init()
{
pthread_cond_init(&fil_crypt_throttle_sleep_cond, nullptr);
mysql_mutex_init(0, &crypt_stat_mutex, nullptr);
+ if (srv_operation == SRV_OPERATION_NORMAL)
+ srv_encrypt_rotate = (encryption_get_no_rotation() == 1);
memset(&crypt_stat, 0, sizeof crypt_stat);
}
@@ -1477,6 +1481,13 @@ inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
return nullptr;
}
+/** If the encryption doesn't have key rotation age variable or
+can't rotate then the tablespace should be added to rotation list. */
+bool fil_crypt_enable_rotation_list()
+{
+ return !srv_fil_crypt_rotate_key_age || !srv_encrypt_rotate;
+}
+
/** Determine the next tablespace for encryption key rotation.
@param space current tablespace (nullptr to start from the beginning)
@param recheck whether the removal condition needs to be rechecked after
@@ -1490,7 +1501,7 @@ inline fil_space_t *fil_space_t::next(fil_space_t *space, bool recheck,
{
mysql_mutex_lock(&fil_system.mutex);
- if (!srv_fil_crypt_rotate_key_age)
+ if (fil_crypt_enable_rotation_list())
space= fil_system.keyrotate_next(space, recheck, encrypt);
else
{
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index f4e33e0d34f..dba11ca48d1 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1010,8 +1010,7 @@ fil_space_t *fil_space_t::create(const char *name, ulint id, ulint flags,
const bool rotate= purpose == FIL_TYPE_TABLESPACE
&& (mode == FIL_ENCRYPTION_ON || mode == FIL_ENCRYPTION_OFF
|| srv_encrypt_tables)
- && !srv_fil_crypt_rotate_key_age
- && srv_n_fil_crypt_threads_started;
+ && fil_crypt_enable_rotation_list();
if (rotate) {
fil_system.rotation_list.push_back(*space);
@@ -1020,7 +1019,7 @@ fil_space_t *fil_space_t::create(const char *name, ulint id, ulint flags,
mysql_mutex_unlock(&fil_system.mutex);
- if (rotate) {
+ if (rotate && srv_n_fil_crypt_threads_started) {
fil_crypt_threads_signal();
}
diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h
index 845b9122343..da25e81f1ab 100644
--- a/storage/innobase/include/fil0crypt.h
+++ b/storage/innobase/include/fil0crypt.h
@@ -429,6 +429,10 @@ void
fil_crypt_total_stat(
fil_crypt_stat_t *stat);
+/** If the encryption doesn't have key rotation age variable or
+can't rotate then the tablespace should be added to rotation list. */
+bool fil_crypt_enable_rotation_list();
+
#include "fil0crypt.ic"
#endif /* !UNIV_INNOCHECKSUM */