-
Notifications
You must be signed in to change notification settings - Fork 37.8k
p2p: change CInv::type
from int
to uint32_t
, fix UBSan warning
#19818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
fixes issue bitcoin#19678 UBSan implicit-integer-sign-change Credit to Eugene (Crypt-iQ) for finding and reporting the issue and to Vasil Dimov (vasild) for the original suggestion
@@ -425,7 +425,7 @@ class CInv | |||
// Combined-message helper methods | |||
bool IsGenTxMsg() const { return type == MSG_TX || type == MSG_WTX || type == MSG_WITNESS_TX; } | |||
|
|||
int type; | |||
uint32_t type; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK on using a sized type here.
However, changing from signed to unsigned is, in principle, a P2P protocol change.
This needs to be carefully reviewed for potential unexpected by-effects.
According to https://en.bitcoin.it/wiki/Protocol_documentation#Inventory_Vectors (section written in 2010 by "MagicalTux") this is unsigned. Though, our python tests also treat this as signed. https://btcinformation.org/en/developer-reference#inv doesn't say anything about signedness. Would be good to at least update the python test framework and also add a p2p test. |
ac8a804
to
9e05ed2
Compare
Updated the python test framework and added test coverage. |
1ab179b
to
6c0f4ae
Compare
Concept ACK Thanks for fixing UBSan fuzzing finds! |
6c0f4ae
to
1bb9a92
Compare
@jonatack Just to confirm: if the test changes we're dropped in this change set (keeping only the changes to |
Right. I pushed the changes to |
1bb9a92
to
7bfc631
Compare
btcinformation.org does show this as uint32_t: https://btcinformation.org/en/developer-reference#data-messages. That was added by @harding to the bitcoin.org developer docs here: bitcoin-dot-org/Bitcoin.org@1634212#diff-693f5b3e9d88b97c899694c8d1656cbbR110 Note that even though comparing an int to a uint32_t causes a UBSan warning, it's not actually undefined behaviour: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#:~:text=%2Dfsanitize%3Dimplicit%2Dinteger%2D,the%20new%20value%20is%20negative. However, I think it's still worth changing this, so that we're always comparing / xor'ing a uint32_t with a uint32_t, so concept ACK. |
Great links @jnewbery, thanks.
"-fsanitize=implicit-integer-sign-change: Implicit conversion between integer types, if that changes the sign of the value...issues caught by this sanitizer are not undefined behavior, but are often unintentional." |
7bfc631
to
7984c39
Compare
Thanks everyone for your feedback. I wrote a few tests but they all covered the change to the CInv class in the test framework, not the CInv change in |
Thanks for addressing the comments, the code changes look good to me now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 7984c39
All the values we ever assign to CInv::type
are non-negative within the reach of a signed 32 bit integer. GetDataMsg
is uint32_t
and in some places we |=
a variable of type uint32_t
into CInv::type
:
bitcoin/src/net_processing.cpp
Line 2717 in bab4cce
inv.type |= nFetchFlags; |
So it makes sense to have CInv::type
as uint32_t
.
Actually serializing a signed integer in the way we do it is not portable, it just works because all platforms use two's complement, but that's not guaranteed.
Bitwise arithmetic should definitely use unsigned integers, good point.
I thought this was already guaranteed in C++11, but no, apparently only C++20 will guarantee two's complement signed integers. |
ACK 7984c39 |
ACK 7984c39 🌻 Show signature and timestampSignature:
Timestamp of file with hash |
…`, fix UBSan warning 7984c39 test framework: serialize/deserialize inv type as unsigned int (Jon Atack) 407175e p2p: change CInv::type from int to uint32_t (Jon Atack) Pull request description: Fixes UBSan implicit-integer-sign-change issue per bitcoin#19610 (comment). Credit to Crypt-iQ for finding and reporting the issue and to vasild for the original review suggestion in bitcoin#19590 (review). Closes bitcoin#19678. ACKs for top commit: laanwj: ACK 7984c39 MarcoFalke: ACK 7984c39 🌻 vasild: ACK 7984c39 Tree-SHA512: 59f3a75f40ce066ca6f0bb1927197254238302b4073af1574bdbfe6ed580876437be804be4e47d51467d604f0d9e3a5875159f7f2edbb2351fdb2bb9465100b5
Fixes UBSan implicit-integer-sign-change issue per #19610 (comment).
Credit to Crypt-iQ for finding and reporting the issue and to vasild for the original review suggestion in #19590 (review).
Closes #19678.