Skip to content

Commit 3adf10b

Browse files
PS-9823 fix: mysql_migrate_keyring won't work with PS's components
https://perconadev.atlassian.net/browse/PS-9823 Reworked keyring components to make sure their corresponding '.so' objects do not have unresolved symbols (from the 'dlopen(..., RTLD_NOW)' point of view). This change is needed to ensure that keyring components can be loaded not only from the 'mysqld' executable but from utilities like 'mysql_migrate_keyring' as well. Keyring components' 'CMakeLists.txt' files fortified with aditional linking option '${LINK_FLAG_NO_UNDEFINED}' (-Wl,--no-undefined) which prevents building '.so' shared objects with unresolved sumbols. Reworked 'components/keyrings/common/data/pfs_string.h' header file so that it depends on memory functions form 'mysql/components/library_mysys/component_malloc_allocator.h' (available in 'library_mysys' library ) instead of those from 'mysql/service_mysql_alloc.h' (available in 'mysys' library). Removed 'DBUG_TRACE' calls from the 'component_keyring_kmip' code to get rid of 'mysys' library dependency. Calls to 'mysql_components_handle_std_exception()' inside both 'component_keyring_kmip' and 'component_keyring_vault' replaced with 'LogComponentErr()' to avoid dependency on 'minchassis'. Added explicit dependency on 'OpenSSL::Crypto' for the component_keyring_vault' (needed for AES functions). 'memset_s()' Percona's extension function moved from 'mysys' to 'library_mysys' and renamed to 'my_memset_s()'. Removed unused 'components/keyrings/common/data/keyring_alloc.h'. Removed unused 'plugin/keyring/common/secure_string.h'. Removed unused 'Secure_allocator' class template from the 'plugin/keyring/common/keyring_memory.h'. Added a series of 'component_keyring_xxx.dynamic_loading' MTR test cases (one for each keyring component: 'file', 'vault', 'kmip', 'kms') that checks if the component's '.so' file does not have unresolved symbols in order to make sure that it can be loaded from auxiliary utilities (like 'mysql_migrate_keyring'). These MTR test cases internally build a helper utility from the '.cpp' file ('mysql-test/std_data/dlopen_checker.cpp') that simply performs an attempt to call 'dlopen(..., RTLD_NOW)' for the provided '.so' object. Added 'component_keyring_vault.migrate_keyring' MTR test case that tests for keyring data migration from 'component_keyring_vault' to 'component_keyring_file' and back.
1 parent 63b3ad1 commit 3adf10b

31 files changed

Lines changed: 491 additions & 189 deletions

File tree

components/keyrings/common/data/keyring_alloc.h

Lines changed: 0 additions & 50 deletions
This file was deleted.

components/keyrings/common/data/pfs_string.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22
#ifndef PFS_STRING_INCLUDED
33
#define PFS_STRING_INCLUDED
44

5+
#include <cassert>
56
#include <limits>
7+
#include <new>
68
#include <optional>
79
#include <sstream>
8-
#include "my_sys.h"
9-
#include "mysql/service_mysql_alloc.h"
10-
#include "sql/psi_memory_key.h"
10+
#include <string>
11+
#include <utility>
12+
13+
#include <mysql/components/library_mysys/component_malloc_allocator.h>
14+
15+
#include <my_sys.h>
1116

1217
extern PSI_memory_key KEY_mem_keyring;
1318

components/keyrings/keyring_file/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ MYSQL_ADD_COMPONENT(keyring_file
8585
MODULE_ONLY
8686
)
8787

88+
MY_TARGET_LINK_OPTIONS(component_keyring_file "${LINK_FLAG_NO_UNDEFINED}")
89+
8890
DOWNGRADE_STRINGOP_WARNINGS(component_keyring_file)
8991

9092
IF(APPLE)

components/keyrings/keyring_kmip/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ MYSQL_ADD_COMPONENT(keyring_kmip
8484
LINK_LIBRARIES ${KEYRING_KMIP_LIBRARIES}
8585
MODULE_ONLY
8686
)
87+
88+
MY_TARGET_LINK_OPTIONS(component_keyring_kmip "${LINK_FLAG_NO_UNDEFINED}")
89+
8790
IF(APPLE)
8891
SET_TARGET_PROPERTIES(component_keyring_kmip PROPERTIES
8992
LINK_FLAGS "-undefined dynamic_lookup")

components/keyrings/keyring_kmip/backend/backend.cc

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include <memory>
2626

2727
#include "backend.h"
28-
#include "my_dbug.h"
2928

3029
#include <mysql/components/minimal_chassis.h>
3130

@@ -47,15 +46,13 @@ using keyring_common::utils::get_random_data;
4746

4847
Keyring_kmip_backend::Keyring_kmip_backend(config::Config_pod const &config)
4948
: valid_(false), config_(config) {
50-
DBUG_TRACE;
5149
valid_ = true;
5250
}
5351

5452
bool Keyring_kmip_backend::load_cache(
5553
keyring_common::operations::Keyring_operations<
5654
Keyring_kmip_backend, keyring_common::data::Data_extension<IdExt>>
5755
&operations) {
58-
DBUG_TRACE;
5956
// We have to load keys and secrets with state==ACTIVE only
6057
//TODO: implement better logic with the new KMIP library
6158
try {
@@ -126,9 +123,12 @@ bool Keyring_kmip_backend::load_cache(
126123
return true;
127124
}
128125
}
129-
126+
} catch (const std::exception &e) {
127+
LogComponentErr(ERROR_LEVEL, ER_STD_UNKNOWN_EXCEPTION, e.what(), __func__);
128+
return true;
130129
} catch (...) {
131-
mysql_components_handle_std_exception(__func__);
130+
LogComponentErr(ERROR_LEVEL, ER_UNKNOWN_ERROR, MYF(0));
131+
return true;
132132
}
133133

134134
return false;
@@ -137,13 +137,11 @@ bool Keyring_kmip_backend::load_cache(
137137
bool Keyring_kmip_backend::get(const Metadata &, Data &) const {
138138
/* Shouldn't have reached here if we cache things. */
139139
assert(0);
140-
DBUG_TRACE;
141140
return false;
142141
}
143142

144143
bool Keyring_kmip_backend::store(const Metadata &metadata,
145144
Data_extension<IdExt> &data) {
146-
DBUG_TRACE;
147145
if (!metadata.valid() || !data.valid()) return true;
148146
kmippp::context::id_t id;
149147
try {
@@ -184,8 +182,11 @@ bool Keyring_kmip_backend::store(const Metadata &metadata,
184182
return true;
185183
}
186184
data.set_extension({id});
185+
} catch (const std::exception &e) {
186+
LogComponentErr(ERROR_LEVEL, ER_STD_UNKNOWN_EXCEPTION, e.what(), __func__);
187+
return true;
187188
} catch (...) {
188-
mysql_components_handle_std_exception(__func__);
189+
LogComponentErr(ERROR_LEVEL, ER_UNKNOWN_ERROR, MYF(0));
189190
return true;
190191
}
191192
return false;
@@ -204,15 +205,17 @@ size_t Keyring_kmip_backend::size() const {
204205
return keys.size() + secrets.size();
205206
//we may have deactivated keys counted, so we need to count active keys only
206207
//TODO: implement better logic with the new KMIP library
208+
} catch (const std::exception &e) {
209+
LogComponentErr(ERROR_LEVEL, ER_STD_UNKNOWN_EXCEPTION, e.what(), __func__);
210+
return 0;
207211
} catch (...) {
208-
mysql_components_handle_std_exception(__func__);
212+
LogComponentErr(ERROR_LEVEL, ER_UNKNOWN_ERROR, MYF(0));
209213
return 0;
210214
}
211215
}
212216

213217
bool Keyring_kmip_backend::erase(const Metadata &metadata,
214218
Data_extension<IdExt> &data) {
215-
DBUG_TRACE;
216219
if (!metadata.valid()) return true;
217220

218221
auto ctx = kmip_ctx();
@@ -238,7 +241,6 @@ bool Keyring_kmip_backend::erase(const Metadata &metadata,
238241
bool Keyring_kmip_backend::generate(const Metadata &metadata,
239242
Data_extension<IdExt> &data,
240243
size_t length) {
241-
DBUG_TRACE;
242244
if (!metadata.valid()) return true;
243245

244246
std::unique_ptr<unsigned char[]> key(new unsigned char[length]);

components/keyrings/keyring_kms/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ SET(KEYRING_KMS_LIBRARIES keyring_common ext::curl OpenSSL::SSL OpenSSL::Crypto)
7373

7474
MYSQL_ADD_COMPONENT(keyring_kms ${KEYRING_KMS_SOURCE} LINK_LIBRARIES ${KEYRING_KMS_LIBRARIES} MODULE_ONLY)
7575

76+
MY_TARGET_LINK_OPTIONS(component_keyring_file "${LINK_FLAG_NO_UNDEFINED}")
77+
7678
MY_CHECK_CXX_COMPILER_WARNING("-Wno-suggest-override" HAS_FLAG)
7779
IF(HAS_FLAG)
7880
TARGET_COMPILE_OPTIONS(component_keyring_kms PUBLIC "-Wno-suggest-override")

components/keyrings/keyring_vault/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,16 @@ set(KEYRING_VAULT_SOURCE
7575
component_callbacks.cc
7676
)
7777

78-
set(KEYRING_VAULT_LIBRARIES keyring_common ext::curl extra::rapidjson)
78+
set(KEYRING_VAULT_LIBRARIES keyring_common ext::curl extra::rapidjson OpenSSL::Crypto)
7979

8080
MYSQL_ADD_COMPONENT(keyring_vault
8181
${KEYRING_VAULT_SOURCE}
8282
LINK_LIBRARIES ${KEYRING_VAULT_LIBRARIES}
8383
MODULE_ONLY
8484
)
8585

86+
MY_TARGET_LINK_OPTIONS(component_keyring_vault "${LINK_FLAG_NO_UNDEFINED}")
87+
8688
target_compile_definitions(component_keyring_vault PRIVATE LOG_COMPONENT_TAG="component_keyring_vault")
8789

8890
target_include_directories(

components/keyrings/keyring_vault/backend/backend.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,13 @@ bool Keyring_vault_backend::init() {
8383
m_valid = true;
8484

8585
return false;
86+
} catch (const std::exception &e) {
87+
LogComponentErr(ERROR_LEVEL, ER_STD_UNKNOWN_EXCEPTION, e.what(), __func__);
8688
} catch (...) {
87-
mysql_components_handle_std_exception(__func__);
88-
curl_global_cleanup();
89-
return true;
89+
LogComponentErr(ERROR_LEVEL, ER_UNKNOWN_ERROR, MYF(0));
9090
}
91+
curl_global_cleanup();
92+
return true;
9193
}
9294

9395
bool Keyring_vault_backend::load_cache(

components/keyrings/keyring_vault/backend/i_vault_curl.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ along with this program; if not, write to the Free Software
2020
#define KEYRING_I_VAULT_CURL_INCLUDED
2121

2222
#include <components/keyrings/common/data/data.h>
23-
#include <components/keyrings/common/data/keyring_alloc.h>
2423
#include <components/keyrings/common/data/meta.h>
2524
#include <components/keyrings/common/data/pfs_string.h>
2625
#include <components/keyrings/keyring_vault/config/config.h>
@@ -29,13 +28,11 @@ along with this program; if not, write to the Free Software
2928

3029
namespace keyring_vault::backend {
3130

32-
using keyring_common::data::Comp_keyring_alloc;
3331
using keyring_common::data::Data;
3432
using keyring_common::meta::Metadata;
3533
using keyring_vault::config::Vault_version_type;
3634

37-
class IKeyring_vault_curl : public Comp_keyring_alloc,
38-
private boost::noncopyable {
35+
class IKeyring_vault_curl : private boost::noncopyable {
3936
public:
4037
virtual bool init() = 0;
4138
virtual bool list_keys(pfs_string *response) = 0;

components/keyrings/keyring_vault/backend/vault_base64.cc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <algorithm>
2525
#include <memory>
2626

27+
#include <mysql/components/library_mysys/my_memory.h>
28+
2729
namespace keyring_vault::backend {
2830

2931
bool Vault_base64::encode(const void *src, size_t src_len, pfs_string *encoded,
@@ -35,7 +37,7 @@ bool Vault_base64::encode(const void *src, size_t src_len, pfs_string *encoded,
3537
// provide access to underlying data when they are empty. Calling reserve on
3638
// those containers does not help.
3739
if (::base64_encode(src, src_len, base64_encoded_text.get()) != 0) {
38-
memset_s(base64_encoded_text.get(), memory_needed, 0, memory_needed);
40+
my_memset_s(base64_encoded_text.get(), memory_needed, 0, memory_needed);
3941
return true;
4042
}
4143

@@ -49,7 +51,7 @@ bool Vault_base64::encode(const void *src, size_t src_len, pfs_string *encoded,
4951
// base64 encode below returns data with NULL terminating string - which we do
5052
// not care about
5153
encoded->assign(base64_encoded_text.get(), memory_needed - 1);
52-
memset_s(base64_encoded_text.get(), memory_needed, 0, memory_needed);
54+
my_memset_s(base64_encoded_text.get(), memory_needed, 0, memory_needed);
5355

5456
return false;
5557
}
@@ -59,7 +61,7 @@ bool Vault_base64::decode(const pfs_string &src, pfs_string *dst) {
5961
uint64 data_length = 0;
6062
if (decode(src, data, &data_length)) return true;
6163
dst->assign(data.get(), data_length);
62-
memset_s(data.get(), data_length, 0, data_length);
64+
my_memset_s(data.get(), data_length, 0, data_length);
6365
return false;
6466
}
6567

@@ -74,8 +76,8 @@ bool Vault_base64::decode(const pfs_string &src, std::unique_ptr<char[]> &dst,
7476
::base64_decode(src.c_str(), src.length(), data.get(), nullptr, 0);
7577

7678
if (decoded_length <= 0) {
77-
memset_s(data.get(), base64_length_of_memory_needed_for_decode, 0,
78-
base64_length_of_memory_needed_for_decode);
79+
my_memset_s(data.get(), base64_length_of_memory_needed_for_decode, 0,
80+
base64_length_of_memory_needed_for_decode);
7981
return true;
8082
}
8183

0 commit comments

Comments
 (0)