Repository navigation
bound parameter name lookahead to the body in parse_param_name - #4460
Open
Sahana2524 wants to merge 1 commit into
Open
Sahana2524 wants to merge 1 commit into
Sahana2524 wants to merge 1 commit into
Conversation
parse_param_name() read a 4-byte word from the parameter before checking that 4 bytes were left, and after recognizing a parameter name it tested the next byte for '=' without checking that the body had any bytes left. A Digest credentials body ending on a short or value-less parameter (e.g. "Digest a", "Digest realm") or right after a ',' made it read up to 4 bytes past the Authorization / Proxy-Authorization header body. Do the word read only after the length check and require a byte to be left before looking for '='. Add a parser test that runs the credentials parser through the guard-page harness.
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.
Summary
An
Authorization/Proxy-AuthorizationDigest header whose body ends on a short or value-less parameter makesparse_param_name()read up to 4 bytes past the header body.Details
parse_digest_cred()hands each parameter toparse_param_name()inparser/digest/param_parser.c, with_srunning to the end of the header body. Two reads there are not bounded by_s->len:The first reads a 4-byte word before checking that 4 bytes are left, so a trailing parameter shorter than that (
Digest a), or the empty remainder afterDigestor a trailing,(Digest uri=x,), is read past the end. The second one is hit when a recognized name (realm,uri,nonce, ...) is the last thing in the body with no=after it (Digest realm):trim_leading()leaveslen == 0ands[0]is the byte after the body.The header is parsed before anything is authenticated (
pre_auth()viafind_credentials(), the$au/$ar/$aduvariables,dispatcher,call_control,sipcapture,msrp_relay), so the bytes are fully controlled by the sender. Inside a SIP message what follows is usually the header's CRLF, which is likely why this has gone unnoticed, but the parser is still reading memory outside the string it was given.Running
parse_digest_cred()through the same loop asparser/test/test_oob.c(every prefix of a few credential strings placed against a guard page, in both directions) gave 91 faults in 502 runs on the current code and none with the patch.Solution
The
READ(p)now happens after the_s->len < 4check (short names already go toother, which only scans the bytes that are there), and the=test requires_s->len > 0. A name with no value still falls through toother, finds no=and is rejected exactly as before.A new
parser/test/test_parse_digest.cchecks the parsed fields for valid credentials and the rejection of value-less ones, and runs the truncation set through the guard-page harness. It segfaults on the current tree and passes all 509 checks with the fix.Compatibility
No behavior change for well-formed credentials: every field, plus the parsed
algorithmandqop, comes out the same. Bodies ending on a bare name were already rejected (-2) and still are, just without the over-read.Closing issues
None.