Skip to content

Commit a7179e7

Browse files
authored
Sentinel: fix a free-after-use issue re-registering Sentinels. (redis#10333)
In case HELLO message received from another sentinel, with same address like another instance registered in the past but with different runid. Then there was cumbersome logic to modify the instance the port to 0 to in order to mark as invalid and later on to delete it. But the deletion is happening during update of instances in such a way that we might end up accessing an instance that was deleted just before. Didn't find a good reason why to postpone the deletion action of an obsolete instance (deletion is taking place instantly, for other cases ) -> Lets delete at once There is a mixture of logic of Sentinel address update with the logic of deletion of Sentinels that match a given Address -> Split to two!
1 parent 488aecb commit a7179e7

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

src/sentinel.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,10 +1190,6 @@ int sentinelUpdateSentinelAddressInAllMasters(sentinelRedisInstance *ri) {
11901190
if (match->link->pc != NULL)
11911191
instanceLinkCloseConnection(match->link,match->link->pc);
11921192

1193-
/* Remove any sentinel with port number set to 0 */
1194-
if (match->addr->port == 0)
1195-
dictDelete(master->sentinels,match->name);
1196-
11971193
if (match == ri) continue; /* Address already updated for it. */
11981194

11991195
/* Update the address of the matching Sentinel by copying the address
@@ -2878,9 +2874,22 @@ void sentinelProcessHelloMessage(char *hello, int hello_len) {
28782874
getSentinelRedisInstanceByAddrAndRunID(
28792875
master->sentinels, token[0],port,NULL);
28802876
if (other) {
2877+
/* If there is already other sentinel with same address (but
2878+
* different runid) then remove the old one across all masters */
28812879
sentinelEvent(LL_NOTICE,"+sentinel-invalid-addr",other,"%@");
2882-
other->addr->port = 0; /* It means: invalid address. */
2883-
sentinelUpdateSentinelAddressInAllMasters(other);
2880+
dictIterator *di;
2881+
dictEntry *de;
2882+
2883+
/* Keep a copy of runid. 'other' about to be deleted in loop. */
2884+
sds runid_obsolete = sdsnew(other->runid);
2885+
2886+
di = dictGetIterator(sentinel.masters);
2887+
while((de = dictNext(di)) != NULL) {
2888+
sentinelRedisInstance *master = dictGetVal(de);
2889+
removeMatchingSentinelFromMaster(master, runid_obsolete);
2890+
}
2891+
dictReleaseIterator(di);
2892+
sdsfree(runid_obsolete);
28842893
}
28852894
}
28862895

0 commit comments

Comments
 (0)