Repository navigation
Reject metaflac numeric arguments that do not fit in 32 bits - #946
Open
trestoncuzzort wants to merge 1 commit into
Open
trestoncuzzort wants to merge 1 commit into
trestoncuzzort wants to merge 1 commit into
Conversation
Where unsigned long has 64 bits, parse_uint32() stored the result of strtoul() in a FLAC__uint32 without a range check, so for example --set-sample-rate=4294967297 set a sample rate of 1. parse_add_padding() and parse_block_number() narrowed their values in the same way: --add-padding=4294967312 added 16 bytes of padding and --block-number=4294967296 selected block 0. Parse the number in 64 bits and reject a value that does not fit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Where
unsigned longhas 64 bits,parse_uint32()stores the result ofstrtoul()in aFLAC__uint32without a range check, so a number above 2^32 − 1 is truncated before the callers check it.parse_add_padding()andparse_block_number()narrow their values in the same way.On Linux x86-64, with a copy of
test/metaflac.flac.in(44100 Hz, 8 bits, 1 channel), each of these exits 0 on master:--set-sample-rate=4294967297--set-channels=4294967298--set-min-blocksize=4294967312--set-min-framesize=4294967297--add-padding=4294967312--list --block-number=4294967296With the change each of them fails with the message that the option already has for a value out of range (for example
ERROR (--set-sample-rate): invalid sample rate), and the file is left as it was.parse_uint32()now goes throughparse_uint64()and rejects a value above 2^32 − 1,parse_add_padding()checks the 2^24 limit before it narrows, andparse_block_number()usesparse_uint32().Tests.
test_metaflac.shgets a block with nine such options, each of which must fail and leave the file unchanged, and a check that values in range are still accepted. On master it stops atTesting that --set-sample-rate=4294967297 is rejected... ERROR: it should have failed but didn't; with the change it passes. All 10 ctest tests pass before and after (CMake build without Ogg, GCC 13.3, Linux x86-64). I did not run the autotools build or the other CI platforms.Not part of this change:
--set-channels=0is accepted on master and still is, although the message says "value must be > 0"; the file then reports 8 channels and a sample rate of 44111. I can add that check here or send it separately, as you prefer.I also checked
parse_uint32()andparse_add_padding()with the CBMC model checker (6.11.0), run through the case gate of my tool dawnr: for every string of up to 11 characters the result and the stored value are compared with the decimal value of the digits. The current functions fail that (for example"9677309084", and the same input fails when run natively) and the changed ones pass. CBMC has nostrtoul, so the model uses stand-ins; a native run of the same harness with glibc over 563,422,433 strings agrees: the current code fails for the 13,110,962 numbers above 2^32 − 1 and the changed code for none. The harness and the results are in https://github.com/trestoncuzzort/dawnr/tree/5d6ac9cc026a2b6ee9513a931c952094f3182a8f/t/native_fixtures/flac-metaflac-parse-uint32.