diff options
author | fanquake <fanquake@gmail.com> | 2020-05-02 20:52:15 +0800 |
---|---|---|
committer | fanquake <fanquake@gmail.com> | 2020-05-02 21:24:05 +0800 |
commit | 68ef9523d1bcd00afbccee2a6585c9f82ddcdb31 (patch) | |
tree | 629945c4ce4f60d94e0926c969895619e8539856 /src/script/script.h | |
parent | 844d2070a2c0106bb7a54be5cad7d4da4d9cd55e (diff) | |
parent | 2748e8793267126c5b40621d75d1930e358f057e (diff) |
Merge #18413: script: prevent UB when computing abs value for num opcode serialize
2748e8793267126c5b40621d75d1930e358f057e script: prevent UB when computing abs value for num opcode serialize (pierrenn)
Pull request description:
This was reported by practicalswift here #18046
It seems that the original author of the line used a reference to glibc `abs`: https://github.com/lattera/glibc/blob/master/stdlib/abs.c
However depending on some implementation details this can be undefined behavior for unusual values.
A detailed explanation of the UB is provided here : https://stackoverflow.com/questions/17313579/is-there-a-safe-way-to-get-the-unsigned-absolute-value-of-a-signed-integer-with (by [Billy O'Neal](https://twitter.com/malwareminigun))
Simple relevant godbolt example : https://godbolt.org/z/yRwtCG
Thanks!
ACKs for top commit:
sipa:
ACK 2748e8793267126c5b40621d75d1930e358f057e
MarcoFalke:
ACK 2748e8793267126c5b40621d75d1930e358f057e, only checked that the bitcoind binary does not change with clang -O2 🎓
practicalswift:
ACK 2748e8793267126c5b40621d75d1930e358f057e
Tree-SHA512: 539a34c636c2674c66cb6e707d9d0dfdce63f59b5525610ed88da10c9a8d59d81466b111ad63b850660cef3750d732fc7755530c81a2d61f396be0707cd86dec
Diffstat (limited to 'src/script/script.h')
-rw-r--r-- | src/script/script.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/script/script.h b/src/script/script.h index daf4224530..773ffbb985 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -329,7 +329,7 @@ public: std::vector<unsigned char> result; const bool neg = value < 0; - uint64_t absvalue = neg ? -value : value; + uint64_t absvalue = neg ? ~static_cast<uint64_t>(value) + 1 : static_cast<uint64_t>(value); while(absvalue) { |