You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Signed overflow in cbor_value_get_int64() / cbor_value_get_int() for out-of-range negative integers #347
cbor_value_get_int64() and cbor_value_get_int() in src/cbor.h do
*result=-*result-1;
for negative integers. If the encoded magnitude is 2^63 (or 2^31 for the int version), *result is already INT64_MIN / INT_MIN at that point, so the negation overflows. That's UB, and it's reachable from untrusted input through the public API. The only precondition is cbor_value_is_integer(), which these inputs satisfy.
With clang -fsanitize=undefined on current main (da6421f):
src/cbor.h:437:19: runtime error: negation of -9223372036854775808 cannot be represented in type 'int64_t' (aka 'long')
src/cbor.h:446:19: runtime error: negation of -2147483648 cannot be represented in type 'int'
I know the docs say to use the _checked variants if the value might not fit, and those are fine. But the unchecked ones are documented as returning a truncated value in that case, not as UB, and in practice a sanitizer build aborts. An optimising compiler is also free to assume the overflow can't happen.
I ran into this while writing CBMC harnesses and fuzzing tinycbor. Happy to open a PR with a fix (~*result instead of -*result - 1, same value, no overflow) and a test if that sounds good.
Thank you for your report. The documentation, as you noted, is very clear:
* Note that this function does not do range-checking: integral values that do
* not fit in a variable of type \c int64_t are silently truncated to fit. Use
* cbor_value_get_int64_checked() that is not acceptable.
I think I can change the implementation to use unsigned arithmetic at this point, which will not incur UB.
Activity
thiagomacieira commentedon Oct 26, 2026
Hello @Tajwarbot
Thank you for your report. The documentation, as you noted, is very clear:
I think I can change the implementation to use unsigned arithmetic at this point, which will not incur UB.
thiagomacieira commentedon Oct 26, 2026
Yes, that worked. Fix in #349
Fix UB in `cbor_value_get_int64()` with out-of-range inputs