Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SoundSourceM4A: Reconfigure decoder after channel config errors #2850

Merged
merged 20 commits into from
Jun 13, 2020
Merged

SoundSourceM4A: Reconfigure decoder after channel config errors #2850

merged 20 commits into from
Jun 13, 2020

Conversation

uklotzde
Copy link
Contributor

@uklotzde uklotzde commented Jun 7, 2020

A fix for the evil FAAD2 2.9.x that required a huge amount of work and testing. Continued and finished after recent discussions in #2738.

I still don't understand why we need all those complex workarounds to decode regular M4A files. VLC is also using lots of custom patches to fix issues.

If more issues arise I recommend to drop FAAD2 entirely. It's not worth to waste so much time on this.

@uklotzde uklotzde added this to the 2.3.0 milestone Jun 7, 2020
@uklotzde uklotzde changed the title FAAD2: Reconfigure decoder after channel config errors SoundSourceM4A: Reconfigure decoder after channel config errors Jun 7, 2020
@Holzhaus
Copy link
Member

Holzhaus commented Jun 7, 2020

Any reasons why we didn't drop FAAD when FFmpeg support was added?

@uklotzde
Copy link
Contributor Author

uklotzde commented Jun 7, 2020

Offsets for cue points might differ slightly.

On the other hand it would allow us to drop libmp4v2 which also seems to be discontinued.

@Holzhaus
Copy link
Member

Holzhaus commented Jun 7, 2020

The offsets would be the same across all OSes, right? If we find a pattern we can correct them with a DB migration. We should switch eventually IMHO.

uklotzde referenced this pull request in knik0/faad2 Jun 9, 2020
Implicit channel mapping reconfiguration is explicitely forbidden by
ISO/IEC 13818-7:2006 (8.5.3.3). Decoders should be able to detect such
files and reject them. FAAD2 does not perform any kind of checks
regarding this.

This leads to security vulnerabilities when processing crafted AAC
files performing such reconfigurations.

Add checks to decode_sce_lfe and decode_cpe to make sure such
inconsistencies are detected as early as possible.

These checks first read hDecoder->frame: if this is not the first
frame then we make sure that the syntax element at the same position
in the previous frame also had element_id id_syn_ele. If not, return
21 as this is a fatal file structure issue.

This patch addresses CVE-2018-20362 (fixes #26) and possibly other
related issues.
Copy link
Member

@daschuer daschuer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the fix and all the useful refactoring.

I am unsure how we should continue here in the long run. Since libmp4v2 was removed from debian.
The faad guys have fixed it by adding their own mp4 stream extraction functions.

During review I have done some fixes
https://github.com/uklotzde/mixxx/pull/15

src/sources/soundsourcem4a.cpp Show resolved Hide resolved
src/sources/soundsourcem4a.cpp Show resolved Hide resolved
src/sources/soundsourcem4a.cpp Outdated Show resolved Hide resolved
src/sources/soundsourcem4a.cpp Show resolved Hide resolved
src/sources/soundsourcem4a.cpp Show resolved Hide resolved
src/sources/soundsourcem4a.cpp Show resolved Hide resolved
writableSampleFrames.writableData(),
std::min(writableSampleFrames.writableLength(), numberOfSamples)));
DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
if (!retryAfterReopeningDecoder) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this condition is always true.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it is not. After exiting the inner loop we will end up here. But now we can continue, see my changes.

m_curSampleBlockId = MP4_INVALID_SAMPLE_ID;
m_inputBufferLength = 0;
if (!reopenDecoder()) {
return {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why returning a empty initializer list, that compiles to a default constructed void();
That is confusing. Please use just return;

This has the advantage that the compiler will complain when we change the function returning something sensible.
Unlike changing the signature from int to double or such we need to reconsider every return path when changing from void.

Please also fix the other occurrences.

Copy link
Contributor Author

@uklotzde uklotzde Jun 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect, please expand the diff.

It returns an empty, default constructed ReadableSampleFrames without redundantly repeating the type name.

@uklotzde
Copy link
Contributor Author

uklotzde commented Jun 13, 2020

Ping. This is needed for fixing .m4a playback on Fedora 32, replacing 2.2 with 2.3 beta. Otherwise I have to switch from FAAD2 to FFmpeg permanently.

// At this point we have failed to decode the current sample
// block twice and need to discard it. The content of the
// sample block is unknown and we simply continue with the
// next block. This is just a workaround! The reason why FAAD2
Copy link
Member

@daschuer daschuer Jun 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by using silence instead ..
or
by skipping the block

I am afraid that the later will produce a cue point offset if the track was originally decoded with a working FAAD2 decoder or if it was decoded with a broken decoder the offset will appear after the decoder is fixed.

Copy link
Contributor Author

@uklotzde uklotzde Jun 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not writing an AAC decoder for the unknown frames rejected blocks. No chance. In this case I will close this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't even know if and how many samples those blocks contain. Sorry, but this is not doable.

@daschuer
Copy link
Member

No, need to fix that. I was just curious to know what this patch means.
Please add a comment about the offset and we can merge.

@uklotzde
Copy link
Contributor Author

sigh

Copy link
Member

@daschuer daschuer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. LGTM

@daschuer daschuer merged commit db4a5b0 into mixxxdj:master Jun 13, 2020
@uklotzde uklotzde mentioned this pull request Jun 13, 2020
@uklotzde uklotzde deleted the faad2 branch June 14, 2020 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants