@@ -61,7 +61,9 @@ struct crypt_info_t {
61
61
static crypt_info_t info;
62
62
63
63
/* * Crypt info when upgrading from 10.1 */
64
- static crypt_info_t infos[5 ];
64
+ static crypt_info_t infos[5 * 2 ];
65
+ /* * First unused slot in infos[] */
66
+ static size_t infos_used;
65
67
66
68
/* ********************************************************************/ /* *
67
69
Get a log block's start lsn.
@@ -79,28 +81,6 @@ log_block_get_start_lsn(
79
81
return start_lsn;
80
82
}
81
83
82
- /* ********************************************************************/ /* *
83
- Get crypt info from checkpoint.
84
- @return a crypt info or NULL if not present. */
85
- static
86
- const crypt_info_t *
87
- get_crypt_info (ulint checkpoint_no)
88
- {
89
- /* a log block only stores 4-bytes of checkpoint no */
90
- checkpoint_no &= 0xFFFFFFFF ;
91
- for (unsigned i = 0 ; i < 5 ; i++) {
92
- const crypt_info_t * it = &infos[i];
93
-
94
- if (it->key_version && it->checkpoint_no == checkpoint_no) {
95
- return it;
96
- }
97
- }
98
-
99
- /* If checkpoint contains more than one key and we did not
100
- find the correct one use the first one. */
101
- return infos;
102
- }
103
-
104
84
/* * Encrypt or decrypt log blocks.
105
85
@param[in,out] buf log blocks to encrypt or decrypt
106
86
@param[in] lsn log sequence number of the start of the buffer
@@ -165,9 +145,7 @@ log_crypt(byte* buf, lsn_t lsn, ulint size, bool decrypt)
165
145
@param[in,out] info encryption key
166
146
@param[in] upgrade whether to use the key in MariaDB 10.1 format
167
147
@return whether the operation was successful */
168
- static
169
- bool
170
- init_crypt_key (crypt_info_t * info, bool upgrade = false )
148
+ static bool init_crypt_key (crypt_info_t * info, bool upgrade = false )
171
149
{
172
150
byte mysqld_key[MY_AES_MAX_KEY_LENGTH];
173
151
uint keylen = sizeof mysqld_key;
@@ -252,8 +230,20 @@ log_crypt_101_read_checkpoint(const byte* buf)
252
230
const size_t n = *buf++ == 2 ? std::min (unsigned (*buf++), 5U ) : 0 ;
253
231
254
232
for (size_t i = 0 ; i < n; i++) {
255
- struct crypt_info_t & info = infos[i];
256
- info.checkpoint_no = mach_read_from_4 (buf);
233
+ struct crypt_info_t & info = infos[infos_used];
234
+ unsigned checkpoint_no = mach_read_from_4 (buf);
235
+ for (size_t j = 0 ; j < infos_used; j++) {
236
+ if (infos[j].checkpoint_no == checkpoint_no) {
237
+ /* Do not overwrite an existing slot. */
238
+ goto next_slot;
239
+ }
240
+ }
241
+ if (infos_used >= UT_ARR_SIZE (infos)) {
242
+ ut_ad (!" too many checkpoint pages" );
243
+ goto next_slot;
244
+ }
245
+ infos_used++;
246
+ info.checkpoint_no = checkpoint_no;
257
247
info.key_version = mach_read_from_4 (buf + 4 );
258
248
memcpy (info.crypt_msg .bytes , buf + 8 , sizeof info.crypt_msg );
259
249
memcpy (info.crypt_nonce .bytes , buf + 24 ,
@@ -262,6 +252,7 @@ log_crypt_101_read_checkpoint(const byte* buf)
262
252
if (!init_crypt_key (&info, true )) {
263
253
return false ;
264
254
}
255
+ next_slot:
265
256
buf += 4 + 4 + 2 * MY_AES_BLOCK_SIZE;
266
257
}
267
258
@@ -277,13 +268,19 @@ log_crypt_101_read_block(byte* buf)
277
268
{
278
269
ut_ad (log_block_calc_checksum_format_0 (buf)
279
270
!= log_block_get_checksum (buf));
280
- const crypt_info_t * info = get_crypt_info (
281
- log_block_get_checkpoint_no (buf));
282
-
283
- if (!info || info->key_version == 0 ) {
284
- return false ;
271
+ const uint32_t checkpoint_no
272
+ = uint32_t (log_block_get_checkpoint_no (buf));
273
+ const crypt_info_t * info = infos;
274
+ for (const crypt_info_t * const end = info + infos_used; info < end;
275
+ info++) {
276
+ if (info->key_version
277
+ && info->checkpoint_no == checkpoint_no) {
278
+ goto found;
279
+ }
285
280
}
286
281
282
+ return false ;
283
+ found:
287
284
byte dst[OS_FILE_LOG_BLOCK_SIZE];
288
285
uint dst_len;
289
286
byte aes_ctr_iv[MY_AES_BLOCK_SIZE];
@@ -312,9 +309,7 @@ log_crypt_101_read_block(byte* buf)
312
309
LOG_DEFAULT_ENCRYPTION_KEY,
313
310
info->key_version );
314
311
315
- if (rc != MY_AES_OK || dst_len != src_len
316
- || log_block_calc_checksum_format_0 (dst)
317
- != log_block_get_checksum (dst)) {
312
+ if (rc != MY_AES_OK || dst_len != src_len) {
318
313
return false ;
319
314
}
320
315
0 commit comments