Skip to content

Commit

Permalink
Merge pull request #18425 from ghalliday/issue31486
Browse files Browse the repository at this point in the history
HPCC-31486 Prevent newly resolved secrets from being updated too early

Reviewed-by: Jake Smith <jake.smith@lexisnexisrisk.com>
Merged-by: Gavin Halliday <ghalliday@hpccsystems.com>
  • Loading branch information
ghalliday authored Mar 19, 2024
2 parents 7164f30 + de8d738 commit af02a3a
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 10 deletions.
18 changes: 10 additions & 8 deletions system/jlib/jsecrets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,10 +425,9 @@ class SecretCacheEntry : public CInterface
friend class SecretCache;

public:
//A cache entry is initally created that has a create and access time of now, but the checkTimestamp
//is set so that needsRefresh() will return true.
//A cache entry is initally created that has a create and access,and check time of now
SecretCacheEntry(cache_timestamp _now, const char * _secretKey)
: secretKey(_secretKey), contentTimestamp(_now), accessedTimestamp(_now), checkedTimestamp(_now - 2 * secretTimeoutNs)
: secretKey(_secretKey), contentTimestamp(_now), accessedTimestamp(_now), checkedTimestamp(_now)
{
}

Expand Down Expand Up @@ -530,9 +529,10 @@ class SecretCache
}

//Check to see if a secret exists, and if not add a null entry that has expired.
SecretCacheEntry * getSecret(const std::string & secretKey, cache_timestamp now)
SecretCacheEntry * getSecret(const std::string & secretKey, cache_timestamp now, bool & isNewEntry)
{
SecretCacheEntry * result;
isNewEntry = false;
CriticalBlock block(cs);
auto match = secrets.find(secretKey);
if (match != secrets.cend())
Expand All @@ -542,9 +542,10 @@ class SecretCache
}
else
{
//Insert an entry with a null value that is marked as out of date
//Insert an entry with a null value
result = new SecretCacheEntry(now, secretKey.c_str());
secrets.emplace(secretKey, result);
isNewEntry = true;
}
return result;
}
Expand Down Expand Up @@ -1170,8 +1171,9 @@ static SecretCacheEntry * getSecretEntry(const char * category, const char * nam

std::string key(buildSecretKey(category, name, optVaultId, optVersion));

SecretCacheEntry * match = globalSecretCache.getSecret(key, now);
if (!match->needsRefresh(now))
bool isNewEntry;
SecretCacheEntry * match = globalSecretCache.getSecret(key, now, isNewEntry);
if (!isNewEntry && !match->needsRefresh(now))
return match;

Owned<IPropertyTree> resolved(resolveSecret(category, name, optVaultId, optVersion));
Expand Down Expand Up @@ -1314,7 +1316,7 @@ void CSecret::checkUptoDate() const
if (secret->needsRefresh(now))
{
#ifdef TRACE_SECRETS
DBGLOG("Secret %s is stale updating from %u...", secret->queryTraceName(), secretHash);
DBGLOG("Secret %s is stale updating...", secret->queryTraceName());
#endif
//MORE: This could block or fail - in roxie especially it would be better to return the old value
try
Expand Down
4 changes: 2 additions & 2 deletions testing/unittests/jlibtests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4252,8 +4252,8 @@ class JLibSecretsTest : public CppUnit::TestFixture
CPPUNIT_ASSERT(!secret6->isValid());
CPPUNIT_ASSERT(!secret6->isStale());

//Sleep so the cache entry should have expired and the value reread since reading ahead
MilliSleep(60); // elapsed=110 = 80 + 30
//Sleep so the cache entry should have expired (between 80 and 85ms) and the value reread since reading ahead
MilliSleep(60); // elapsed=110 = 50 + 60
CPPUNIT_ASSERT(secret6->isValid());
CPPUNIT_ASSERT(!secret6->isStale());
unsigned version1 = secret6->getVersion(); // Mark the value as accessed, but too early to be refreshed
Expand Down

0 comments on commit af02a3a

Please sign in to comment.