nestegg Xiph lace unbounded accumulation causes sustained DoS via crafted WebM
Categories
(Core :: Audio/Video: Playback, defect, P2)
Tracking
()
People
(Reporter: jmwebdevelopement, Assigned: kinetik)
References
Details
(Keywords: csectype-dos, reporter-external, sec-low, Whiteboard: [adv-main152+])
Attachments
(2 external files)
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36
Steps to reproduce:
- Load a WebM file containing Xiph lacing with repeated 0xFF lace size bytes in Firefox
- Observe browser behavior
Actual results:
Firefox becomes completely unresponsive when loading the file. CPU spikes to over 100% and stays there for 12+ minutes. The tab can't be closed normally — the process has to be force-killed.
traced back to media/libnestegg/src/nestegg.c in the Xiph lace parsing. The function ne_read_xiph_lace_value() has a loop that accumulates values while each byte is 255, but there's no limit on how many iterations it runs or how large the total can get:
total = 0;
do {
read = ne_read_uint(ctx->io, &lace, 1);
total += lace;
} while (lace == 255);
A file with a long run of 0xFF bytes in the lace data keeps the loop going indefinitely.
Verified against mozilla-central commit dd17ef41c29d.
Expected results:
The parser should limit how many bytes it reads for a single lace value to prevent the browser from hanging on bad files.
Updated•7 months ago
|
Updated•7 months ago
|
Comment 1•7 months ago
|
||
Could you attach a WebM with extended Xiph lacing that has been problematic? AFAICT the standard doesn't seem to place any practical limits here, so anything we could do here would be more of a guess of what is reasonable and what is not.
I assume this is the loop you are referring to:
https://searchfox.org/firefox-main/rev/287c6cf323492ae0cc031e468c1d87f623413f50/media/libnestegg/src/nestegg.c#1333-1339
It could cause IO operations through the reading and I wonder if that is what is so expensive:
https://searchfox.org/firefox-main/rev/287c6cf323492ae0cc031e468c1d87f623413f50/dom/media/webm/WebMDemuxer.cpp#53
Thanks!
| Assignee | ||
Updated•7 months ago
|
| Assignee | ||
Comment 2•7 months ago
•
|
||
There's two issues here, which Andrew has already identified: there's no limit in the spec beyond block size to constrain this, and the reason this can be made a DoS is that the Xiph lacing parser triggers a nearly unbounded number of single byte I/O reads.
We already limit frame sizes to 256MB (and block sizes to 1GB), but this check is applied after the lacing is read. Even in the case of a specially crafted file, once the Xiph lacing parse finally completes the parser rejects the result as invalid due to these limits or other block size validation.
Since we already enforce a frame size limit, we can add an early check for that to the Xiph lacing parser and bail out early. That's not a complete fix, but it does bound the number of I/O reads to ~1M.
We can generate files to trigger this behaviour easily, so no need to attach one.
| Assignee | ||
Comment 3•7 months ago
|
||
| Assignee | ||
Comment 4•7 months ago
•
|
||
Adding an upper bound to the number of I/O reads is useful, but ~1M single byte reads is still potentially expensive and may be sufficient to trigger a DoS depending on the cost of the I/O read callback supplied to nestegg. Addressing this involves adding some buffering on the nestegg side, which is fairly simple but we'll need to take care not to break Gecko's existing assumptions about nestegg's behaviour.
Updated•7 months ago
|
| Assignee | ||
Comment 5•7 months ago
|
||
Comment on attachment 9559618 [details] [review]
GitHub Pull Request
Clearing r?, already reviewed upstream.
| Assignee | ||
Comment 6•7 months ago
|
||
| Assignee | ||
Comment 7•7 months ago
|
||
The Xiph lacing limit landed via bug 2027946.
| Reporter | ||
Updated•6 months ago
|
| Assignee | ||
Updated•6 months ago
|
| Assignee | ||
Comment 8•6 months ago
|
||
Buffering changes landed in bug 2034234.
| Assignee | ||
Updated•6 months ago
|
Updated•6 months ago
|
Updated•6 months ago
|
Updated•5 months ago
|
Updated•5 months ago
|
Updated•5 months ago
|
Updated•4 months ago
|
Updated•1 month ago
|
Description
•