Add nullptr-check to CChain::Contains(), tests#34416
Add nullptr-check to CChain::Contains(), tests#34416optout21 wants to merge 2 commits intobitcoin:masterfrom
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34416. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please copy-paste ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
src/net_processing.cpp
Outdated
| bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex) | ||
| { | ||
| AssertLockHeld(cs_main); | ||
| if (!pindex) return false; |
There was a problem hiding this comment.
i think this goes in the wrong direction. All call sites have checked against nullptr, and there should never be a reason to call this with nullptr, so this seems it should be a reference. Just like BlockRequested and FetchBlock take a reference.
There was a problem hiding this comment.
Following this feedback, I will reconsider the switch to pass-by-reference. As mentioned in the description, I started in that direction, but was concerned about consistency.
For consistency, it makes sense to also change the other methods (e.g. Next()), increasing the scope. Const input pointer parameters are relatively easy to change to pass-by-reference; but return values where nullptr is a valid option should be changed to std::option<&...>. These end up in a larger changeset (arguably not adding much value).
There was a problem hiding this comment.
Well, i haven't looked into the lower level chain util methods. For some methods, it could make sense to accept a pointer. My comment was mostly about BlockRequestAllowed, and other similar high level functions that only work on blocks that exist and whose presence has been previously confirmed
There was a problem hiding this comment.
bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex*) should be changed to bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex&)
There was a problem hiding this comment.
i don't understand why the some line of code should be changed, only to revert it in the next commit. Please submit 6539829 as a separate pull request
There was a problem hiding this comment.
also, the name pindex should probably be changed to block_index (or so), like in the function immediately below
There was a problem hiding this comment.
i don't understand why the some line of code should be changed, only to revert it in the next commit. Please submit 6539829 as a separate pull request
I can do it in a separate PR, should be trivial.
The add/remove is a side-effect of independent commits: one commit changed the method called from here (Contains), so a null check had to be added before the call. Then when this method has also been change to take a reference input, the check is no longer needed. (The check moved outwards.)
There was a problem hiding this comment.
Note: BlockRequestAllowed change has been done in #34464.
|
I'm exploring the option to use references, but I've decided to keep this simple PR as first step. As suggested, I look into using references instead of pointers. Howerver, that is a bigger refactor. I think the minimal change (one extra check) and unit tests from this PR make sense in isolation, as the bigger change will be heavier. Draft PR #34440 opened. I will strip this one a bit more. |
7f27d10 to
0c2df01
Compare
|
Marked ready for review. |
src/net_processing.cpp
Outdated
| bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex) | ||
| { | ||
| AssertLockHeld(cs_main); | ||
| if (!pindex) return false; |
There was a problem hiding this comment.
bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex*) should be changed to bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex&)
|
test ACK 0c2df01 |
1f8f7d4 Change BlockRequestAllowed() to take ref (optout) Pull request description: As [suggested here](#34416 (comment)), a minor refactor of `PeerManagerImpl::BlockRequestAllowed()` to take reference parameter (instead of pointer). The motivation is to make the code safer, by minimizing the risk of null-dereference, and to be more consistent. The change is local to the `PeerManagerImpl::BlockRequestAllowed()` class. Related to #34440. ACKs for top commit: maflcko: review ACK 1f8f7d4 🎐 l0rinc: tested ACK 1f8f7d4 stickies-v: ACK 1f8f7d4 Tree-SHA512: 9c2de2d3e7d067e018db7ec54c79f512ccc1da54574d4fb362f6697ee6e235783779d7094cf20856cd34e08a1dbc74609d8351fe7b2287cd8ec0c836ef07be19
Add basic unit tests to the `CChain` class, filling a gap.
The `CChain::Contains()` method dereferences its input without checking, potentially resulting in nullptr-dereference if invoked with `nullptr`. The `Next()` method can also trigger this. Avoid the memory access violation by adding an extra check for the `pindex` input. The result is `false` for `nullptr` input.
0c2df01 to
6c3a91f
Compare
|
Rebased, following merging of #34464 . |
|
ACK 6c3a91f By the way, the CI test failed not because of the PR code. |
Add unit tests to the
CChainclass, and add a nullptr-check toCChain::Contains()to avoid potential memory access violation bynullptrdereference.The
CChain::Contains()method (insrc/chain.h) dereferences its input without checking. TheNext()method also calls into this with anullptrif invoked withnullptr. While most call sites have indirect guarantee that the input is notnullptr, it's not easy to establish this to all call sites with high confidence. These methods are publicly available. There is no known high-level use case to trigger this error, but the fix is easy, and makes the code safer.Also, unit tests were added to the
CChainclass, filling a gap.Changes:
CChainclass methodsCChain::Contains()Alternative. I have considered changing
Contains()to take a reference instead of pointer, however, when applying that to various methods, it grew to a much bigger changeset -- see #34440. Having in mind the friction of larger PRs, I think the present minimal one-check solution (with the tests) makes sense on its own.This change is remotely related to and indirectly triggered by #32875 .