Otherwise CAddrMan::_Check()
will complain.
An alternative would be to remove the check from CAddrMan::_Check()
.
Otherwise CAddrMan::_Check()
will complain.
An alternative would be to remove the check from CAddrMan::_Check()
.
nKey
is a random integer. Why treat 0 specially? It is a possible valid value and no less or more likely to be set in nKey = FastRandomContext::rand256();
than any other value, e.g. 0xFFFF...
or 0x5555...
.
Zero is a special value because it is used to clear the memory before destructing addrman. Though, I see your point, which is why I mentioned the alternative in OP:
An alternative would be to remove the check from CAddrMan::_Check().
Are you saying I should remove the check from _Check
?
ACK fa52c7e2c20ca6a4c3f217f9a00c165e5fff7e91
Needs rebase.
Are you saying I should remove the check from _Check?
I don’t have strong opinion and this is so minor that it will work either way. Personally I would remove it from Check()
and remove the SetNull()
from addrman destructor. Nowadays there are better ways to detect use-after-free than setting select members to magic values in the destructor.
Or add a comment to m_key
to explain the magic value or make the magic value a static member constant or:
0- nKey = insecure_rand.rand256();
1+ do {
2+ nKey = insecure_rand.rand256();
3+ } while (nKey.IsNull());
to make it explicit.
to make it explicit
… to the reader that 0 is treated specially, it would be more of a documentation than avoiding a 1/2^256
chance.
Needs rebase.
Not if it is merged after the pull that it conflicts with ;)
I don’t have strong opinion and this is so minor that it will work either way. Personally I would remove it from Check() and remove the SetNull() from addrman destructor. Nowadays there are better ways to detect use-after-free than setting select members to magic values in the destructor.
Makes sense. Will do, because addrman is only destructed on shutdown, at which point is seems unlikely that someone successfully pulls an attack after exploiting a use-after-free on m_key.
I’d still say so, yes. This is no different from wallet private keys in an unencrypted wallet.
Leaving it in memory means it risks ending up in uninitialized memory that’s allocated, where it may leak in case of other bugs. The addrman key is of course not nearly as sensitive as wallet keys, and the fact that it remains in use almost the entire lifetime of the process makes it less of an issue further, but I think it’s good practice in general to wipe key material that is unused.
We could go further and allocate it using the locked pool, actually.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
No conflicts as of last run.
m_key.SetNull()
in this pull. It seems unrelated anyway. Also, I took this out of draft and force pushed to fixup the tests in the first commit, which I forgot initially.
addrman_tests/remove_invalid
and addrman_tests/addrman_serialization
are failing due to the new check: “Corrupt CAddrMan serialization, m_key is all zeros”
The same errors occurred.
fatal error: in "addrman_tests/addrman_serialization": std::ios_base::failure[abi:cxx11]: Corrupt CAddrMan serialization, m_key is all zeros.: iostream error
fatal error: in "addrman_tests/remove_invalid": std::ios_base::failure[abi:cxx11]: Corrupt CAddrMan serialization, m_key is all zeros.: iostream error
Otherwise CAddrMan::_Check() will complain.