Skip to content

Commit 5d83f73

Browse files
Merge branch 'dev/PS-9823-8.0-mysql_migrate_keyring_unusable' into dev/PS-9823-8.4-mysql_migrate_keyring_unusable
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. Removed custom allocator from the 'components/keyrings/common/data/pfs_string.h' header to eliminate divergence from upstream code. 'pfs_string' kept as an alias to 'std::string' to minimize Percona code changes. 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.
2 parents 63b3ad1 + b598edd commit 5d83f73

File tree

37 files changed

+514
-300
lines changed

37 files changed

+514
-300
lines changed

components/keyrings/common/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ SET(KEYRING_COMMON_SOURCES
3030
# Data representation
3131
data/data.cc
3232
data/meta.cc
33-
data/pfs_string.cpp
3433
# File reader/writer
3534
data_file/reader.cc
3635
data_file/writer.cc

components/keyrings/common/data/keyring_alloc.h

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

components/keyrings/common/data/pfs_string.cpp

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

components/keyrings/common/data/pfs_string.h

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

5-
#include <limits>
65
#include <optional>
76
#include <sstream>
8-
#include "my_sys.h"
9-
#include "mysql/service_mysql_alloc.h"
10-
#include "sql/psi_memory_key.h"
7+
#include <string>
118

12-
extern PSI_memory_key KEY_mem_keyring;
13-
14-
/**
15-
Malloc_allocator is based on sql/malloc_allocator.h, but uses a fixed PSI key
16-
instead
17-
*/
18-
template <class T = void *>
19-
class Comp_malloc_allocator {
20-
// This cannot be const if we want to be able to swap.
21-
PSI_memory_key m_key = KEY_mem_keyring;
22-
23-
public:
24-
typedef T value_type;
25-
typedef size_t size_type;
26-
typedef ptrdiff_t difference_type;
27-
28-
typedef T *pointer;
29-
typedef const T *const_pointer;
30-
31-
typedef T &reference;
32-
typedef const T &const_reference;
33-
34-
pointer address(reference r) const { return &r; }
35-
const_pointer address(const_reference r) const { return &r; }
36-
37-
explicit Comp_malloc_allocator() {}
38-
39-
template <class U>
40-
Comp_malloc_allocator(const Comp_malloc_allocator<U> &other [[maybe_unused]])
41-
: m_key(other.psi_key()) {}
42-
43-
template <class U>
44-
Comp_malloc_allocator &operator=(const Comp_malloc_allocator<U> &other
45-
[[maybe_unused]]) {
46-
assert(m_key == other.psi_key()); // Don't swap key.
47-
}
48-
49-
pointer allocate(size_type n, const_pointer hint [[maybe_unused]] = nullptr) {
50-
if (n == 0) return nullptr;
51-
if (n > max_size()) throw std::bad_alloc();
52-
53-
pointer p = static_cast<pointer>(
54-
my_malloc(m_key, n * sizeof(T), MYF(MY_WME | ME_FATALERROR)));
55-
if (p == nullptr) throw std::bad_alloc();
56-
return p;
57-
}
58-
59-
void deallocate(pointer p, size_type) { my_free(p); }
60-
61-
template <class U, class... Args>
62-
void construct(U *p, Args &&... args) {
63-
assert(p != nullptr);
64-
try {
65-
::new ((void *)p) U(std::forward<Args>(args)...);
66-
} catch (...) {
67-
assert(false); // Constructor should not throw an exception.
68-
}
69-
}
70-
71-
void destroy(pointer p) {
72-
assert(p != nullptr);
73-
try {
74-
p->~T();
75-
} catch (...) {
76-
assert(false); // Destructor should not throw an exception
77-
}
78-
}
79-
80-
size_type max_size() const {
81-
return std::numeric_limits<size_t>::max() / sizeof(T);
82-
}
83-
84-
template <class U>
85-
struct rebind {
86-
typedef Comp_malloc_allocator<U> other;
87-
};
88-
89-
PSI_memory_key psi_key() const { return m_key; }
90-
};
91-
92-
template <class T>
93-
bool operator==(const Comp_malloc_allocator<T> &a1,
94-
const Comp_malloc_allocator<T> &a2) {
95-
return a1.psi_key() == a2.psi_key();
96-
}
97-
98-
template <class T>
99-
bool operator!=(const Comp_malloc_allocator<T> &a1,
100-
const Comp_malloc_allocator<T> &a2) {
101-
return a1.psi_key() != a2.psi_key();
102-
}
103-
104-
using pfs_string = std::basic_string<char, std::char_traits<char>,
105-
Comp_malloc_allocator<char>>;
9+
using pfs_string = std::string;
10610

10711
using pfs_optional_string = std::optional<pfs_string>;
10812

109-
using pfs_secure_ostringstream =
110-
std::basic_ostringstream<char, std::char_traits<char>,
111-
Comp_malloc_allocator<char>>;
13+
using pfs_ostringstream = std::ostringstream;
11214

11315
#endif // PFS_STRING_INCLUDED

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: 25 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,16 @@ bool Keyring_kmip_backend::load_cache(
126123
return true;
127124
}
128125
}
129-
126+
} catch (const std::exception &e) {
127+
std::string err_msg = std::string("std exception in function '") +
128+
__func__ + "': " + e.what();
129+
LogComponentErr(ERROR_LEVEL, ER_LOG_PRINTF_MSG, err_msg.c_str());
130+
return true;
130131
} catch (...) {
131-
mysql_components_handle_std_exception(__func__);
132+
std::string err_msg =
133+
std::string("Unknown exception in function '") + __func__ + '\'';
134+
LogComponentErr(ERROR_LEVEL, ER_LOG_PRINTF_MSG, err_msg.c_str());
135+
return true;
132136
}
133137

134138
return false;
@@ -137,13 +141,11 @@ bool Keyring_kmip_backend::load_cache(
137141
bool Keyring_kmip_backend::get(const Metadata &, Data &) const {
138142
/* Shouldn't have reached here if we cache things. */
139143
assert(0);
140-
DBUG_TRACE;
141144
return false;
142145
}
143146

144147
bool Keyring_kmip_backend::store(const Metadata &metadata,
145148
Data_extension<IdExt> &data) {
146-
DBUG_TRACE;
147149
if (!metadata.valid() || !data.valid()) return true;
148150
kmippp::context::id_t id;
149151
try {
@@ -184,8 +186,15 @@ bool Keyring_kmip_backend::store(const Metadata &metadata,
184186
return true;
185187
}
186188
data.set_extension({id});
189+
} catch (const std::exception &e) {
190+
std::string err_msg = std::string("std exception in function '") +
191+
__func__ + "': " + e.what();
192+
LogComponentErr(ERROR_LEVEL, ER_LOG_PRINTF_MSG, err_msg.c_str());
193+
return true;
187194
} catch (...) {
188-
mysql_components_handle_std_exception(__func__);
195+
std::string err_msg =
196+
std::string("Unknown exception in function '") + __func__ + '\'';
197+
LogComponentErr(ERROR_LEVEL, ER_LOG_PRINTF_MSG, err_msg.c_str());
189198
return true;
190199
}
191200
return false;
@@ -204,15 +213,21 @@ size_t Keyring_kmip_backend::size() const {
204213
return keys.size() + secrets.size();
205214
//we may have deactivated keys counted, so we need to count active keys only
206215
//TODO: implement better logic with the new KMIP library
216+
} catch (const std::exception &e) {
217+
std::string err_msg = std::string("std exception in function '") +
218+
__func__ + "': " + e.what();
219+
LogComponentErr(ERROR_LEVEL, ER_LOG_PRINTF_MSG, err_msg.c_str());
220+
return 0;
207221
} catch (...) {
208-
mysql_components_handle_std_exception(__func__);
222+
std::string err_msg =
223+
std::string("Unknown exception in function '") + __func__ + '\'';
224+
LogComponentErr(ERROR_LEVEL, ER_LOG_PRINTF_MSG, err_msg.c_str());
209225
return 0;
210226
}
211227
}
212228

213229
bool Keyring_kmip_backend::erase(const Metadata &metadata,
214230
Data_extension<IdExt> &data) {
215-
DBUG_TRACE;
216231
if (!metadata.valid()) return true;
217232

218233
auto ctx = kmip_ctx();
@@ -238,7 +253,6 @@ bool Keyring_kmip_backend::erase(const Metadata &metadata,
238253
bool Keyring_kmip_backend::generate(const Metadata &metadata,
239254
Data_extension<IdExt> &data,
240255
size_t length) {
241-
DBUG_TRACE;
242256
if (!metadata.valid()) return true;
243257

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

components/keyrings/keyring_kmip/keyring_kmip.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,6 @@ PROVIDES_SERVICE(component_keyring_kmip, keyring_aes),
218218
PROVIDES_SERVICE(component_keyring_kmip, log_builtins_string),
219219
END_COMPONENT_PROVIDES();
220220

221-
PSI_memory_key KEY_mem_keyring_kmip;
222-
223221
/** List of dependencies */
224222
BEGIN_COMPONENT_REQUIRES(component_keyring_kmip)
225223
REQUIRES_SERVICE(registry), REQUIRES_SERVICE(log_builtins),

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_kms "${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(

0 commit comments

Comments
 (0)