Skip to content

Commit e7f8c94

Browse files
authored
Merge branch 'TDE_REL_17_STABLE' into backup_new_wal_key
2 parents 6a87351 + 621c3f8 commit e7f8c94

File tree

8 files changed

+58
-11
lines changed

8 files changed

+58
-11
lines changed

ci_scripts/suppressions/lsan.supp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,8 @@ leak:GenerateRecoveryConfig
5959
# Returns strdup'd string which never gets freed in frontend tools. Trying to
6060
# free it leads to comiler complains that it discards 'const' qualifier.
6161
leak:get_progname
62+
63+
# A buch of not freed allocations in putVariableInt right before exit(1). And
64+
# malloced `threads` ("Thread state") never gets released (allocated in main(),
65+
# once, and not in loop).
66+
leak:bin/pgbench/pgbench.c

contrib/pg_tde/src/access/pg_tde_xlog_keys.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "common/pg_tde_utils.h"
1717
#include "encryption/enc_aes.h"
1818
#include "encryption/enc_tde.h"
19+
#include "utils/palloc.h"
1920

2021
#ifdef FRONTEND
2122
#include "pg_tde_fe.h"
@@ -43,7 +44,9 @@ typedef struct WalKeyFileEntry
4344
} WalKeyFileEntry;
4445

4546
static WALKeyCacheRec *tde_wal_key_cache = NULL;
47+
static WALKeyCacheRec *tde_wal_prealloc_record = NULL;
4648
static WALKeyCacheRec *tde_wal_key_last_rec = NULL;
49+
static WalEncryptionKey *tde_wal_prealloc_key = NULL;
4750

4851
static WALKeyCacheRec *pg_tde_add_wal_key_to_cache(WalEncryptionKey *cached_key);
4952
static WalEncryptionKey *pg_tde_decrypt_wal_key(const TDEPrincipalKey *principal_key, WalKeyFileEntry *entry);
@@ -326,6 +329,34 @@ pg_tde_fetch_wal_keys(WalLocation start)
326329
return return_wal_rec;
327330
}
328331

332+
/*
333+
* In special cases, we have to add one more record to the WAL key cache during write (in the critical section, when we can't allocate).
334+
* This method is a helper to deal with that: when adding a single key, we potentially allocate 2 records.
335+
* These variables help preallocate them, so in the critical section we can just use the already allocated objects, and update the cache with them.
336+
*
337+
* While this is somewhat a hack, it is also simple, safe, reliable, and way easier to implement than to refactor the cache or the decryption/encryption loop.
338+
*/
339+
void
340+
pg_tde_wal_cache_extra_palloc(void)
341+
{
342+
#ifndef FRONTEND
343+
MemoryContext oldCtx;
344+
345+
oldCtx = MemoryContextSwitchTo(TopMemoryContext);
346+
#endif
347+
if (tde_wal_prealloc_record == NULL)
348+
{
349+
tde_wal_prealloc_record = palloc0_object(WALKeyCacheRec);
350+
}
351+
if (tde_wal_prealloc_key == NULL)
352+
{
353+
tde_wal_prealloc_key = palloc0_object(WalEncryptionKey);
354+
}
355+
#ifndef FRONTEND
356+
MemoryContextSwitchTo(oldCtx);
357+
#endif
358+
}
359+
329360
static WALKeyCacheRec *
330361
pg_tde_add_wal_key_to_cache(WalEncryptionKey *key)
331362
{
@@ -335,7 +366,8 @@ pg_tde_add_wal_key_to_cache(WalEncryptionKey *key)
335366

336367
oldCtx = MemoryContextSwitchTo(TopMemoryContext);
337368
#endif
338-
wal_rec = palloc0_object(WALKeyCacheRec);
369+
wal_rec = tde_wal_prealloc_record == NULL ? palloc0_object(WALKeyCacheRec) : tde_wal_prealloc_record;
370+
tde_wal_prealloc_record = NULL;
339371
#ifndef FRONTEND
340372
MemoryContextSwitchTo(oldCtx);
341373
#endif
@@ -553,7 +585,9 @@ pg_tde_write_wal_key_file_entry(const WalEncryptionKey *rel_key_data,
553585
static WalEncryptionKey *
554586
pg_tde_decrypt_wal_key(const TDEPrincipalKey *principal_key, WalKeyFileEntry *entry)
555587
{
556-
WalEncryptionKey *key = palloc_object(WalEncryptionKey);
588+
WalEncryptionKey *key = tde_wal_prealloc_key == NULL ? palloc_object(WalEncryptionKey) : tde_wal_prealloc_key;
589+
590+
tde_wal_prealloc_key = NULL;
557591

558592
Assert(principal_key);
559593

contrib/pg_tde/src/access/pg_tde_xlog_smgr.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ TDEXLogShmemInit(void)
158158
{
159159
bool foundBuf;
160160

161+
Assert(LWLockHeldByMeInMode(AddinShmemInitLock, LW_EXCLUSIVE));
162+
161163
EncryptionState = (EncryptionStateData *)
162164
ShmemInitStruct("TDE XLog Encryption State",
163165
TDEXLogEncryptStateSize(),
@@ -248,6 +250,7 @@ TDEXLogSmgrInitWrite(bool encrypt_xlog)
248250

249251
/* cache is empty, prefetch keys from disk */
250252
pg_tde_fetch_wal_keys(start);
253+
pg_tde_wal_cache_extra_palloc();
251254
}
252255

253256
if (key)
@@ -284,8 +287,8 @@ TDEXLogWriteEncryptedPagesOldKeys(int fd, const void *buf, size_t count, off_t o
284287
memcpy(enc_buff, buf, count);
285288

286289
/*
287-
* This method potentially allocates, but only in very early execution
288-
* Shouldn't happen in a write, where we are in a critical section
290+
* This method potentially allocates, but only in very early execution Can
291+
* happen during a write, but we have one more cache entry preallocated.
289292
*/
290293
TDEXLogCryptBuffer(buf, enc_buff, count, offset, tli, segno, segSize);
291294

@@ -342,7 +345,7 @@ tde_ensure_xlog_key_location(WalLocation loc)
342345
lastKeyUsable = (TDEXLogGetEncKeyLsn() != 0);
343346
pg_read_barrier();
344347

345-
if (EncryptionKey.type != WAL_KEY_TYPE_INVALID && !lastKeyUsable)
348+
if (EncryptionKey.type != WAL_KEY_TYPE_INVALID && !lastKeyUsable && afterWriteKey)
346349
{
347350
WALKeyCacheRec *last_key = pg_tde_get_last_wal_key();
348351

@@ -452,10 +455,8 @@ TDEXLogCryptBuffer(const void *buf, void *out_buf, size_t count, off_t offset,
452455
WALKeyCacheRec *last_key = pg_tde_get_last_wal_key();
453456
WalLocation write_loc = {.tli = TDEXLogGetEncKeyTli(),.lsn = write_key_lsn};
454457

455-
Assert(last_key);
456-
457458
/* write has generated a new key, need to fetch it */
458-
if (wal_location_cmp(last_key->start, write_loc) < 0)
459+
if (last_key != NULL && wal_location_cmp(last_key->start, write_loc) < 0)
459460
{
460461
pg_tde_fetch_wal_keys(write_loc);
461462

contrib/pg_tde/src/bin/pg_tde_archive_decrypt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ main(int argc, char *argv[])
212212
if (system(command) != 0)
213213
pg_fatal("ARCHIVE-COMMAND \"%s\" failed: %m", command);
214214

215+
free(command);
216+
215217
if (issegment)
216218
{
217219
if (unlink(tmppath) < 0)

contrib/pg_tde/src/bin/pg_tde_restore_encrypt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ main(int argc, char *argv[])
205205
if (system(command) != 0)
206206
pg_fatal("RESTORE-COMMAND \"%s\" failed: %m", command);
207207

208+
free(command);
209+
208210
if (issegment)
209211
{
210212
write_encrypted_segment(targetpath, sourcename, tmppath);

contrib/pg_tde/src/catalog/tde_principal_key.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ PrincipalKeyShmemInit(void)
127127
char *free_start;
128128
Size required_shmem_size = PrincipalKeyShmemSize();
129129

130-
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
130+
Assert(LWLockHeldByMeInMode(AddinShmemInitLock, LW_EXCLUSIVE));
131131

132132
/* Create or attach to the shared memory state */
133133
ereport(NOTICE, errmsg("PrincipalKeyShmemInit: requested %ld bytes", required_shmem_size));
@@ -175,8 +175,6 @@ PrincipalKeyShmemInit(void)
175175

176176
dshash_detach(dsh);
177177
}
178-
179-
LWLockRelease(AddinShmemInitLock);
180178
}
181179

182180
/*

contrib/pg_tde/src/include/access/pg_tde_xlog_keys.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,6 @@ extern WalEncryptionKey *pg_tde_read_last_wal_key(void);
8282
extern void pg_tde_save_server_key(const TDEPrincipalKey *principal_key, bool write_xlog);
8383
extern void pg_tde_save_server_key_redo(const TDESignedPrincipalKeyInfo *signed_key_info);
8484
extern void pg_tde_wal_last_key_set_location(WalLocation loc);
85+
extern void pg_tde_wal_cache_extra_palloc(void);
8586

8687
#endif /* PG_TDE_XLOG_KEYS_H */

contrib/pg_tde/src/pg_tde.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,15 @@ tde_shmem_startup(void)
6464
if (prev_shmem_startup_hook)
6565
prev_shmem_startup_hook();
6666

67+
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
68+
6769
KeyProviderShmemInit();
6870
PrincipalKeyShmemInit();
6971
TDEXLogShmemInit();
7072
TDEXLogSmgrInit();
7173
TDEXLogSmgrInitWrite(EncryptXLog);
74+
75+
LWLockRelease(AddinShmemInitLock);
7276
}
7377

7478
void

0 commit comments

Comments
 (0)