Skip to content

zeromem: Do not call memset when there is nothing to zero - #1750

Open
yumasansansan wants to merge 1 commit into
juce-framework:developfrom
yumasansansan:ubsan-zeromem
Open

yumasansansan wants to merge 1 commit into
juce-framework:developfrom
yumasansansan:ubsan-zeromem

Conversation

@yumasansansan

Copy link
Copy Markdown

zeromem() passes what it is given straight to memset(), whose declaration forbids a null pointer however many bytes it is asked to fill -- nought included. A buffer of no samples holds no address, so clearing one is a call that UndefinedBehaviorSanitizer stops the program at:

  modules/juce_core/memory/juce_Memory.h:40:79: runtime error: null pointer passed as argument 1, which is declared to never be null

AudioBuffer::clear() is one way there. AudioProcessor::processBlockBypassed() clears the channels the plug-in has no input for, and a host that asks a plug-in for no samples at all may hand over a buffer whose channels are nowhere; FloatVectorOperations::clear() then reaches zeromem() with that pointer and no bytes. Nothing is written either way, so only the call goes away.

This is the shape of #1749's second commit, where MemoryBlock::matches() was given the null pointer of an empty block for memcmp().

A fuzz target of ADLplug-Next found it: it gives an AudioProcessor the blocks a host asks for, of the sizes and the channel counts a host chooses, including none of either.

It is in 9.0.2 and in develop as it stands, and it is independent of the commits of ours that are already open.

zeromem() passes what it is given straight to memset(), whose declaration forbids a null pointer however many bytes it is asked to fill -- nought included. A buffer of no samples holds no address, so clearing one is a call that UndefinedBehaviorSanitizer stops the program at:

  modules/juce_core/memory/juce_Memory.h:40:79: runtime error: null pointer passed as argument 1, which is declared to never be null

AudioBuffer::clear() is one way there: AudioProcessor::processBlockBypassed() clears the channels it has no input for, and a host that asks a plug-in for no samples at all may hand over a buffer whose channels are nowhere. Nothing is written either way, so only the call goes away.

This is the shape of the fix for MemoryBlock::matches(), where memcmp() was given the null pointer of an empty block.

A fuzz target of ADLplug-Next found it, one that gives the plug-in the blocks a host asks for, of the sizes and the channel counts a host chooses.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant