The config_parse_units function uses 64-bit arithmetic, but does not detect 64-bit overflow. This means that values like "20000000 TB", which should be rejected, are instead mis-parsed.
Since this function is only used for configuration parsing, it's not a huge issue, but it should be simple enough to resolve this.
Found while working on 30893.
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items ...
Show closed items
Linked items 0
Link issues together to show that they're related.
Learn more.
Nick added a couple of commented out tests in which it is expected for config_parse_memunit (and thus config_parse_units) to return 0 instead of UINT64_MAX when detecting 64-bit overflow.
Is this the expected behavior, or should it fallback to UINT64_MAX?
I think that's a better behavior for config_parse_memunit(). In the case of config_parse_memunit(), it's better that the user be told about the problem than to have us silently ignore their request.
Should lib/intmath/*.h be appended to confmgt .may_include?
Yes, that's fine. The purpose of .may_include is to make sure that low-level modules don't include headers from high-level modules, and lib/intmath is a nice low-level module.
Is this the expected behavior, or should it fallback to UINT64_MAX?
I think that's a better behavior for config_parse_memunit(). In the case of config_parse_memunit(), it's better that the user be told about the problem than to have us silently ignore their request.
Understood, in that case is it ok to detect overflow inside config_parse_memunit() by check if nowrap_multiplication yielded UINTMAX_64? It seems quite strange in my opinion to specify such value explicitly.
In addition to that I'm not sure if float multiplication should be handled as well or this ticket should just focus on unsigned integer.
Is this the expected behavior, or should it fallback to UINT64_MAX?
I think that's a better behavior for config_parse_memunit(). In the case of config_parse_memunit(), it's better that the user be told about the problem than to have us silently ignore their request.
Understood, in that case is it ok to detect overflow inside config_parse_memunit() by check if nowrap_multiplication yielded UINTMAX_64? It seems quite strange in my opinion to specify such value explicitly.
Maybe we should fail on anything larger than SSIZE_T_MAX?
(SSIZE_T_MAX is half the maximum possible memory size.)
In addition to that I'm not sure if float multiplication should be handled as well or this ticket should just focus on unsigned integer.
No, we don't have any critical code that uses float multiplication.
You're right, SSIZE_MAX is 2^31^ on 32-bit platforms, which would be a valid value for bandwidth on 32-bit machines. And memory on machines that allow processes to take up more than 2 GB.
Let's check that the value is less than INT64_MAX?
And let's check the result of the float multiplication, before we cast it to a uint64_t.
(We want to use a value that's significantly lower than UINT64_MAX, so that floating point calculations can't change the result.)
Let's check that the value is less than INT64_MAX?
And let's check the result of the float multiplication, before we cast it to a uint64_t.
(We want to use a value that's significantly lower than UINT64_MAX, so that floating point calculations can't change the result.)
Not sure if I got it right, waiting for an OK because I ended up writing the same block for the float as the uint case.