From 79b26f1ac5c4abe3a2ebbb8679f023cf3a2dd412 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 28 Oct 2024 09:54:21 +0200 Subject: [PATCH] Make keystore read protected by transaction lock too Take read-only transaction lock at the rpmts side, pass it down the rpmKeystoreLoad() hatch. Somehow this feels like an overkill but then our keystores haven't been designed with concurrent access in mind *at all*, so play safe and just take a read lock while loading they keystore. It also balances the API: everything just takes a txn item now. Related: #3342 --- lib/keystore.cc | 15 ++++++++------- lib/keystore.hh | 2 +- lib/rpmts.cc | 6 +++++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/keystore.cc b/lib/keystore.cc index 55fcd62345..fc7582157e 100644 --- a/lib/keystore.cc +++ b/lib/keystore.cc @@ -24,11 +24,11 @@ using std::string; static int makePubkeyHeader(rpmts ts, rpmPubkey key, Header * hdrp); -static int rpmtsLoadKeyringFromFiles(rpmts ts, rpmKeyring keyring) +static int rpmtsLoadKeyringFromFiles(rpmtxn txn, rpmKeyring keyring) { ARGV_t files = NULL; /* XXX TODO: deal with chroot path issues */ - char *pkpath = rpmGetPath(ts->rootDir, "%{_keyringpath}/*.key", NULL); + char *pkpath = rpmGetPath(rpmtxnRootDir(txn), "%{_keyringpath}/*.key", NULL); int nkeys = 0; rpmlog(RPMLOG_DEBUG, "loading keyring from pubkeys in %s\n", pkpath); @@ -133,14 +133,14 @@ static rpmRC rpmtsImportFSKey(rpmtxn txn, rpmPubkey key, rpmFlags flags, int rep return rc; } -static int rpmtsLoadKeyringFromDB(rpmts ts, rpmKeyring keyring) +static int rpmtsLoadKeyringFromDB(rpmtxn txn, rpmKeyring keyring) { Header h; rpmdbMatchIterator mi; int nkeys = 0; rpmlog(RPMLOG_DEBUG, "loading keyring from rpmdb\n"); - mi = rpmtsInitIterator(ts, RPMDBI_NAME, "gpg-pubkey", 0); + mi = rpmtsInitIterator(rpmtxnTs(txn), RPMDBI_NAME, "gpg-pubkey", 0); while ((h = rpmdbNextIterator(mi)) != NULL) { struct rpmtd_s pubkeys; const char *key; @@ -405,13 +405,14 @@ rpmRC rpmKeystoreDeletePubkey(rpmtxn txn, rpmPubkey key) return rc; } -int rpmKeystoreLoad(rpmts ts, rpmKeyring keyring) +int rpmKeystoreLoad(rpmtxn txn, rpmKeyring keyring) { int nkeys = 0; + rpmts ts = rpmtxnTs(txn); if (ts->keyringtype == KEYRING_FS) { - nkeys = rpmtsLoadKeyringFromFiles(ts, keyring); + nkeys = rpmtsLoadKeyringFromFiles(txn, keyring); } else { - nkeys = rpmtsLoadKeyringFromDB(ts, keyring); + nkeys = rpmtsLoadKeyringFromDB(txn, keyring); } return nkeys; } diff --git a/lib/keystore.hh b/lib/keystore.hh index fc0f7b5bfa..5849f66a38 100644 --- a/lib/keystore.hh +++ b/lib/keystore.hh @@ -9,7 +9,7 @@ enum { }; RPM_GNUC_INTERNAL -int rpmKeystoreLoad(rpmts ts, rpmKeyring keyring); +int rpmKeystoreLoad(rpmtxn txn, rpmKeyring keyring); RPM_GNUC_INTERNAL rpmRC rpmKeystoreImportPubkey(rpmtxn txn, rpmPubkey key, int replace = 0); diff --git a/lib/rpmts.cc b/lib/rpmts.cc index 1e856115fd..66381e1c3b 100644 --- a/lib/rpmts.cc +++ b/lib/rpmts.cc @@ -289,7 +289,11 @@ static void loadKeyring(rpmts ts) if (!ts->keyringtype) ts->keyringtype = getKeyringType(); ts->keyring = rpmKeyringNew(); - rpmKeystoreLoad(ts, ts->keyring); + rpmtxn txn = rpmtxnBegin(ts, RPMTXN_READ); + if (txn) { + rpmKeystoreLoad(txn, ts->keyring); + rpmtxnEnd(txn); + } } }