Closed Bug 749994 Opened 14 years ago Closed 14 years ago

Opus crash invalid read/write [@nsOggReader::DecodeOpus]

Categories

(Core :: Audio/Video, defect)

x86_64
macOS
defect
Not set
critical

Tracking

()

VERIFIED FIXED
Tracking Status
firefox13 --- unaffected
firefox14 --- unaffected
firefox15 + fixed
firefox-esr10 --- unaffected

People

(Reporter: posidron, Assigned: rillian)

References

Details

(Keywords: crash, sec-critical, testcase, Whiteboard: [sg:critical][advisory-tracking-])

Attachments

(2 files)

Attached file callstack
gdb $ list 450 PRInt32 skip = mOpusState->mPreSkip; 451 PRInt32 goodFrames = frames - skip; 452 NS_ASSERTION(goodFrames > 0, "endTime calculation was wrong"); 453 nsAutoArrayPtr<AudioDataValue> goodBuffer(new AudioDataValue[goodFrames * channels]); 454 for (int i = 0; i < goodFrames*channels; i++) 455 goodBuffer[i] = buffer[skip*channels + i]; 456 457 startTime = mOpusState->Time(endFrame - goodFrames); 458 duration = endTime - startTime; 459 frames = goodFrames; gdb $ p skip $3 = 65535 gdb $ p channels $4 = 1 gdb $ p i $5 = 12679297 gdb $ list 430 425 nsAutoArrayPtr<AudioDataValue> buffer(new AudioDataValue[frames * channels]); 426 427 // Decode to the appropriate sample type. 428 #ifdef MOZ_SAMPLE_TYPE_FLOAT32 429 int ret = opus_decode_float(mOpusState->mDecoder, 430 aPacket->packet, aPacket->bytes, 431 buffer, frames, false); 432 #else 433 int ret = opus_decode(mOpusState->mDecoder, 434 aPacket->packet, aPacket->bytes, gdb $ p frames $7 = 960 gdb $ p channels $8 = 1
Attached file testcase
Whiteboard: [sg:critical]
(In reply to Christoph Diehl [:cdiehl] from comment #0) > 450 PRInt32 skip = mOpusState->mPreSkip; > 451 PRInt32 goodFrames = frames - skip; > 452 NS_ASSERTION(goodFrames > 0, "endTime calculation was wrong"); Ralph, I really don't understand this code. frames is the number of samples in the current packet, which is generally small: at most 5760 (120 ms worth). skip can be as large as 65535 (1.37 seconds worth). You have an "if (endTime < 0) return NS_OK;" check to see if you need to skip an entire packet... but you aren't keeping track of the amount of audio that was skipped from that packet. Instead you try to subtract the entire skip amount from the first packet that has a granpos at least as large as the skip amount, even though that individual packet may have nowhere near enough audio in it. Also, while we're here, if frames==granulepos and frames==skip, you won't take the early return to skip an entire packet, but you will trigger the "endTime calculation was wrong" assertion.
Blocks: fuzzing-opus
Assignee: nobody → giles
This testcast is handled without error with the patch from bug 758833.
Status: NEW → ASSIGNED
Depends on: 758833
Status: ASSIGNED → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
Specifically, this check in nsOpusCodec::ReconstructOpusGranulepos() which blocks the testcase: if (!mDoneReadingHeaders && GetOpusDeltaGP(mUnstamped[0]) > gp) return false;
Sorry, comment #4 was meant for bug 750327.
Christoph, can you verify that this issue is now fixed?
This bug is already marked as resolved/fixed. :)
(In reply to Christoph Diehl [:cdiehl] from comment #7) > This bug is already marked as resolved/fixed. :) Yes, it is. That means code was checked in to fix the problem. We have a "verified" status to be used when we confirm that the fix addresses the problem by checking. I'm asking you to verify that it is actually fixed on Trunk.
Have tested it based comment 3 by myself again - bug is fixed.
Status: RESOLVED → VERIFIED
Whiteboard: [sg:critical] → [sg:critical][advisory-tracking+]
Whiteboard: [sg:critical][advisory-tracking+] → [sg:critical][advisory-tracking-]
Group: core-security
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: