From 81c6c7902d2d232af03c36a02fc5b6373a08945d Mon Sep 17 00:00:00 2001 From: Malavan Sotheeswaran <105669860+msotheeswaran@users.noreply.github.com> Date: Wed, 22 Feb 2023 19:27:24 -0500 Subject: [PATCH] Fix possible crash in prefetchKeysAsync with flash enabled. (#578) * remove short circuit as it is unsafe --- src/db.cpp | 24 +++++++----------------- src/networking.cpp | 4 +--- src/server.h | 2 +- 3 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index e0f4c862c..b959f178e 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -3265,7 +3265,7 @@ int dbnumFromDb(redisDb *db) serverPanic("invalid database pointer"); } -bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command, bool fExecOK) +void redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command) { if (m_spstorage == nullptr) { #if defined(__x86_64__) || defined(__i386__) @@ -3277,7 +3277,7 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command const char *cmd = szFromObj(command.argv[0]); if (!strcasecmp(cmd, "set") || !strcasecmp(cmd, "get")) { if (c->db->m_spdbSnapshotHOLDER != nullptr) - return false; // this is dangerous enough without a snapshot around + return; // this is dangerous enough without a snapshot around auto h = dictSdsHash(szFromObj(command.argv[1])); for (int iht = 0; iht < 2; ++iht) { auto hT = h & c->db->m_pdict->ht[iht].sizemask; @@ -3297,7 +3297,7 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command } } #endif - return false; + return; } AeLocker lock; @@ -3307,10 +3307,10 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command getKeysResult result = GETKEYS_RESULT_INIT; auto cmd = lookupCommand(szFromObj(command.argv[0])); if (cmd == nullptr) - return false; // Bad command? It's not for us to judge, just bail + return; // Bad command? It's not for us to judge, just bail if (command.argc < std::abs(cmd->arity)) - return false; // Invalid number of args + return; // Invalid number of args int numkeys = getKeysFromCommand(cmd, command.argv, command.argc, &result); for (int ikey = 0; ikey < numkeys; ++ikey) @@ -3343,7 +3343,6 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command } } - bool fNoInsert = false; if (!vecInserts.empty()) { lock.arm(c); for (auto &tuple : vecInserts) @@ -3359,13 +3358,11 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command // While unlocked this was already ensured decrRefCount(o); sdsfree(sharedKey); - fNoInsert = true; } else { if (spexpire != nullptr) { if (spexpire->when() < mstime()) { - fNoInsert = true; break; } } @@ -3392,12 +3389,5 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command lock.disarm(); } - if (fExecOK && !fNoInsert && cmd->proc == getCommand && !vecInserts.empty()) { - robj *o = std::get<1>(vecInserts[0]); - if (o != nullptr) { - addReplyBulk(c, o); - return true; - } - } - return false; -} \ No newline at end of file + return; +} diff --git a/src/networking.cpp b/src/networking.cpp index eb8cabeb7..c9223c8ae 100644 --- a/src/networking.cpp +++ b/src/networking.cpp @@ -2595,9 +2595,7 @@ void parseClientCommandBuffer(client *c) { (g_pserver->m_pstorageFactory || aeLockContested(cserver.cthreads/2) || cserver.cthreads == 1) && !GlobalLocksAcquired()) { auto &query = c->vecqueuedcmd.back(); if (query.argc > 0 && query.argc == query.argcMax) { - if (c->db->prefetchKeysAsync(c, query, c->vecqueuedcmd.size() == 1)) { - c->vecqueuedcmd.erase(c->vecqueuedcmd.begin()); - } + c->db->prefetchKeysAsync(c, query); } } c->reqtype = 0; diff --git a/src/server.h b/src/server.h index f052d0595..23eb912bc 100644 --- a/src/server.h +++ b/src/server.h @@ -1204,7 +1204,7 @@ public: void disableKeyCache(); bool keycacheIsEnabled(); - bool prefetchKeysAsync(client *c, struct parsed_command &command, bool fExecOK); + void prefetchKeysAsync(client *c, struct parsed_command &command); bool FSnapshot() const { return m_spdbSnapshotHOLDER != nullptr; }