Skip to content

Conversation

@Fusl
Copy link
Contributor

@Fusl Fusl commented Aug 3, 2025

This one was found by afl++. Executing bitfield 0 set i64 0 1 triggers UBSan at the int64_t minincr = min - value; calculation. To fix the undefined behavior in the minincr calculation and strengthen the protection in the maxincr calculation, we cast both, the minuend and the subtrahend, to an unsigned int, do the calculation, and then cast the result back into a signed int.

@Fusl Fusl force-pushed the fusl-bitops-sub-overflow-fix branch from d2e1473 to fb68a39 Compare August 3, 2025 23:34
Copy link
Contributor

@zuiderkwast zuiderkwast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to add bitfield 0 set i64 0 1 to some test case just to verify the fix?

@Fusl
Copy link
Contributor Author

Fusl commented Aug 4, 2025

Would it make sense to add bitfield 0 set i64 0 1 to some test case just to verify the fix?

I tried adding a test case for this but couldn't trigger it outside of a binary built with afl-clang, maybe I was doing something wrong and didn't supply correct compilation flags when building a custom non-afl binary?

Comment on lines +496 to +497
int64_t maxincr = (int64_t)((uint64_t)max - (uint64_t)value);
int64_t minincr = (int64_t)((uint64_t)min - (uint64_t)value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cast to signed can be implicit, for brevity?

Suggested change
int64_t maxincr = (int64_t)((uint64_t)max - (uint64_t)value);
int64_t minincr = (int64_t)((uint64_t)min - (uint64_t)value);
int64_t maxincr = (uint64_t)max - (uint64_t)value;
int64_t minincr = (uint64_t)min - (uint64_t)value;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this explicit since clang-tidy otherwise complains about it:
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, is implicit cast different to explicit? I didn't know...

Let's keep it explicit then.

Out of curiosity, do you know where this stuff is mentioned in the C standards?

Copy link
Contributor

@zuiderkwast zuiderkwast Aug 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That explicit cast specifically tells clang-tidy "i know what im doing, please stop complaining", there's no other side effect and the explicit and implicit format both get compiled down to the same byte code.

@zuiderkwast
Copy link
Contributor

Would it make sense to add bitfield 0 set i64 0 1 to some test case just to verify the fix?

I tried adding a test case for this but couldn't trigger it outside of a binary built with afl-clang, maybe I was doing something wrong and didn't supply correct compilation flags when building a custom non-afl binary?

Ah, I don't know. We can skip the test.

@zuiderkwast zuiderkwast merged commit b7fe0b6 into valkey-io:unstable Aug 5, 2025
50 checks passed
allenss-amazon pushed a commit to allenss-amazon/valkey-core that referenced this pull request Aug 19, 2025
…ow (valkey-io#2418)

This one was found by
[afl++](https://github.com/AFLplusplus/AFLplusplus). Executing `bitfield
0 set i64 0 1` triggers UBSan at the `int64_t minincr = min - value;`
calculation. To fix the undefined behavior in the `minincr` calculation
and strengthen the protection in the `maxincr` calculation, we cast
both, the minuend and the subtrahend, to an unsigned int, do the
calculation, and then cast the result back into a signed int.

Signed-off-by: Fusl <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants