MDEV-38915: Fix signed/unsigned type mismatch in setval() for GET_ULONG#4691
MDEV-38915: Fix signed/unsigned type mismatch in setval() for GET_ULONG#4691luckyxhq wants to merge 1 commit intoMariaDB:10.11from
Conversation
3d637ec to
88ad7db
Compare
|
@gkodinov All checks have passed successfully. Could you please review and merge this PR when convenient? |
grooverdan
left a comment
There was a problem hiding this comment.
Nice find with a simple fix. Btw how did you notice this?
|
I found it while reviewing type handling in setval(). The GET_ULONG branch looked inconsistent because it was casting to long, even though getopt_ull() returns an unsigned value. |
gkodinov
left a comment
There was a problem hiding this comment.
Thank you for your contribution! This is a preliminary review.
Some remarks in no particular order:
- processing on our end would be faster if there was a jira filed and mentioned in the topic. I did that for you now. But it takes some time for me.
- please re-base to 10.11 unless you can provide a scenario that this crashes a binary. See the testing remark.
- please provide tests. I can see there's quite a number of GET_ULONG variables around. If neither of these works, please extend the existing unit test. Apparently it doesn't cover this particular case otherwise it would have failed already.
|
Thank you for the review and detailed feedback! I’ll address the points you mentioned: I push the updates shortly. Please let me know if there’s anything else you’d like me to consider. |
88ad7db to
83e38b7
Compare
Done. Thanks. I just edited the target branch in the title.
@luckyxhq, did you find a case? Because I'm not sure there is one. The casting of high values to long fall in the undefined behaviour of the C/C++ standards. Even if you make a test case that fails under the prior to commit implementation, because it's undefined behaviour a different compiler or newer version may implement something different. Whatever test you come up with won't be predictable because a compiler can do what it likes within the undefined behaviour. So what you've done is correct, you've adjusted the implementation to fall within the defined behaviour of the C/C++ standard. So its my opinion that this can change without a test case. Its passed all the existing tests ok and there will probably be some high values of LONG in those that have been tested to product the same result. Are you happy with this @gkodinov ? @luckyxhq Can you include the MDEV-38915: as the prefix in the title of the commit message and force push? I'm happy with this to be merged after that happens. So after that, its on @gkodinov. |
83e38b7 to
1e509b2
Compare
Bug Description
The
GET_ULONGcase insetval()(inmysys/my_getopt.c, line 751) incorrectly used signed types(long*)and(long)to cast and store the result ofgetopt_ull(), which returns an unsigned value (ulonglong).This creates a signed/unsigned type mismatch that triggers implementation-defined behavior when processing large unsigned long values with the high bit set (i.e., values >
LONG_MAX). On platforms wheresizeof(long) < sizeof(long long)(32-bit systems, Windows x64), this can silently produce wrong stored values for server configuration variables of typeGET_ULONG.Root Cause
A copy-paste inconsistency: the
GET_ULONGcase insetval()was written with(long*)/(long)casts (matching theGET_LONGcase above it), instead of the correct(ulong*)/(ulong)casts.Evidence: Two other locations handling
GET_ULONGin the same file already use the correct unsigned types:init_one_value()at line 1334:*((ulong*) variable)= (ulong) getopt_ull_limit_value(...)printf("%lu\n", *((ulong*) value))Fix
Changed the
GET_ULONGcase insetval()from:to:
Changes Made
mysys/my_getopt.c: Fixed(long*)→(ulong*)and(long)→(ulong)in theGET_ULONGcase ofsetval()(line 751)Testing
GET_ULONGhandling sites in the same fileunittest/mysys/my_getopt-t.c) includesGET_ULONGtests that continue to passImpact
GET_ULONGserver options on affected platformsGET_ULONGbranch ofsetval()is modifiedsetval()with the already-correct behavior ininit_one_value()and the print path