Fix invalid dictNext usage when pubsubshard_channels became empty#13033
Fix invalid dictNext usage when pubsubshard_channels became empty#13033oranagra merged 1 commit intoredis:unstablefrom
Conversation
After redis#12822, when pubsubshard_channels became empty, kvstoreDictDelete will delete the dict (which is the only one currently deleting dicts that become empty) and in the next loop, we will make an invalid call to dictNext. After the dict becomes empty, we break out of the loop without calling dictNext.
|
i checked other places, we are goods. |
|
i noticed that after fixing this issue, this use-after-free appeared. The reason is because dictReleaseIterator will call dictResetIterator to use the dict. Add a new dictFreeIterator to call zfree(iter) directly? |
|
this is disturbing. @guybe7 FYI. the options i see are:
maybe 3 is the cleanest because we do create the iterator via a kvstore function, and we do the deletion via a kvstore function, and only the dict release is done directly. |
|
@oranagra what about changing |
|
@guybe7 who will nullify the dict pointer in the iterator? |
After fix for redis#13033, address sanitizer reports this heap-use-after-free error. When the pubsubshard_channels dict becomes empty, we will delete the dict, and the dictReleaseIterator will call dictResetIterator, it will use the dict so we will trigger the error. Instead of releasing the iteraotr via dictReleaseIterator, we release it via a kvstore wrapper. This PR added a new kvstoreDictReleaseIterator to handle this.
After fix for #13033, address sanitizer reports this heap-use-after-free error. When the pubsubshard_channels dict becomes empty, we will delete the dict, and the dictReleaseIterator will call dictResetIterator, it will use the dict so we will trigger the error. This PR introduced a new struct kvstoreDictIterator to wrap dictIterator. Replace the original dict iterator with the new kvstore dict iterator. --------- Co-authored-by: Oran Agra <[email protected]> Co-authored-by: guybe7 <[email protected]>
…dis#13033) After redis#12822, when pubsubshard_channels became empty, kvstoreDictDelete will delete the dict (which is the only one currently deleting dicts that become empty) and in the next loop, we will make an invalid call to dictNext. After the dict becomes empty, we break out of the loop without calling dictNext.
…13038) After fix for redis#13033, address sanitizer reports this heap-use-after-free error. When the pubsubshard_channels dict becomes empty, we will delete the dict, and the dictReleaseIterator will call dictResetIterator, it will use the dict so we will trigger the error. This PR introduced a new struct kvstoreDictIterator to wrap dictIterator. Replace the original dict iterator with the new kvstore dict iterator. --------- Co-authored-by: Oran Agra <[email protected]> Co-authored-by: guybe7 <[email protected]>
…dis#13033) After redis#12822, when pubsubshard_channels became empty, kvstoreDictDelete will delete the dict (which is the only one currently deleting dicts that become empty) and in the next loop, we will make an invalid call to dictNext. After the dict becomes empty, we break out of the loop without calling dictNext.
…13038) After fix for redis#13033, address sanitizer reports this heap-use-after-free error. When the pubsubshard_channels dict becomes empty, we will delete the dict, and the dictReleaseIterator will call dictResetIterator, it will use the dict so we will trigger the error. This PR introduced a new struct kvstoreDictIterator to wrap dictIterator. Replace the original dict iterator with the new kvstore dict iterator. --------- Co-authored-by: Oran Agra <[email protected]> Co-authored-by: guybe7 <[email protected]>
After #12822, when pubsubshard_channels became empty, kvstoreDictDelete
will delete the dict (which is the only one currently deleting dicts that
become empty) and in the next loop, we will make an invalid call to dictNext.
After the dict becomes empty, we break out of the loop without calling dictNext.