Opened 6 years ago

Closed 6 years ago

#10176 closed bug (fixed)

BMediaFile crashes within AVFormatReader::Sniff() if it cannot handle the file

Reported by: ttcoder Owned by: stippi
Priority: normal Milestone: R1
Component: Audio & Video/Codecs Version: R1/Development
Keywords: ffmpeg Cc:
Blocked By: Blocking:
Has a Patch: no Platform: All

Description

If a file is not audio, or is an mp3 with embedded artwork (JFIF/JPEG) in it, BMediaFile crashes. First seen in our own audio app, though the crash is easily reproduced with MediaPlayer as well.

Seems to have been there a long time: the crash occurs in PM builds but also in old hrev45824; though I didn't find a prior ticket that matches: #6595 is a crash that occurs in the dtor due to post-Open() init, whereas this crash occurs even before Open() is ever called.

We can workaround the non-audio file case easily; we can also probably workaround the embedded art case by loading the file in memory and scanning for 'JFIF' before passing it to BMediaFile but that's of course very hackish. And this will only fix it for us, not for MediaPlayer.

Attaching backtrace...

Attachments (1)

MediaPlayer-18026-debug-06-11-2013-14-41-47.report (13.4 KB ) - added by ttcoder 6 years ago.
MediaPlayer crashes opening an mp3 with embedded art

Download all attachments as: .zip

Change History (8)

by ttcoder, 6 years ago

MediaPlayer crashes opening an mp3 with embedded art

comment:1 by anevilyak, 6 years ago

Owner: changed from nobody to stippi
Status: newassigned

Looks like a problem in the ffmpeg plugin's AVFormatReader implementation.

comment:2 by ttcoder, 6 years ago

MediaPlayer masks most of the problem (but not the embedded art crash) since it filters files on their MIME type. I'm not anxious to upload an example file with embedded art as the one I have is 9 MB; but reproducing this bug with MediaPlayer is doable though it needs a bit of work:

cp myvalid_audio_file.mp3 foo.mp3
> foo.mp3  #this bash redirect will reset foo's size to 0 bytes, which is a valid case to trigger the crash
MediaPlayer foo.mp3

I would have done it with touch and addatr BEOS:TYPE audio/mpeg <file> except it does not work, as addattr adds a CSTR whereas it needs to be a MIMS... But the above works with the right preparation anyway.

EDIT: Here's the StreamBase ctor: http://cgit.haiku-os.org/haiku/tree/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp#n213 To my untrained eye it is odd that it could possibly crash plainly in the ctor body (by opposed to the subfunctions), and the disassembled code shown in Debugger is odd as well with a "call" to an address next to it. Wondering if it's a gcc2 vs. gcc4 memory alignement problem of some sort. I'm on a gcc2h nightly so presumably MediaPlayer is compiled with gcc2?

EDIT2: Thanks evilyak, here's the updated test case:

~/Desktop/New folder> touch foo.mp3
~/Desktop/New folder> addattr -t mime BEOS:TYPE audio/mpeg foo.mp3 
~/Desktop/New folder> MediaPlayer foo.mp3 
Last edited 6 years ago by ttcoder (previous) (diff)

in reply to:  2 comment:3 by anevilyak, 6 years ago

Replying to ttcoder:

I would have done it with touch and addatr BEOS:TYPE audio/mpeg <file> except it does not work, as addattr adds a CSTR whereas it needs to be a MIMS... But the above works with the right preparation anyway.

That's what addattr -t mime is for.

comment:4 by phoudoin, 6 years ago

While the stack trace may suggest it crashed in ctor, maybe it's as in #6595, in StreamBase'dtor. Since #6595 fix, fIOContext was changed to a pointer, and av_free(fIOContext->buffer) is called without checking fIOContext was actually allocated. May I suggest to check fIOContext is not null before doing that, as it's still a possible case...

comment:5 by ttcoder, 6 years ago

Good catch, reading the constructor and destructor side by side it's clear that the dtor should test for pointer validity!

Otherwise just declaring the variable on the stack..

   {
      StreamBase stream;
   }

... and letting it go out of scope makes it crash!

And even without going to that extreme, leaving it in its natural ffmpeg ecosystem :-) it can crash just the same, if Open() fails at any of the last 2 points of failure. So regardless of whether or not this ticket is caused by this variable mishandling, there should be a fix for it indeed:

 StreamBase::~StreamBase()
 {
-       av_free(fIOContext->buffer);
+       if (fIOContext)
+               av_free(fIOContext->buffer);
        av_free(fIOContext);

Tried compiling ffmpeg here but it wants to build the whole libroot.so and kitchen sink before doing it so maybe it would take less time to hack a custom jamfile, which will still take time..

Anyway no need for somebody to check the validity of the "patch", it's painfully obvious it should be applied.

I'll take it on myself of downloading a nightly once the change is commited and check if it fixes this ticket and report here for sure.

comment:6 by ttcoder, 6 years ago

Fixed by pulkomandy in hrev46441, yay! (and thanks!)

comment:7 by anevilyak, 6 years ago

Resolution: fixed
Status: assignedclosed

Thanks for the note!

Note: See TracTickets for help on using tickets.