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

Fixes #3161: "Multiplication result converted to larger type" in client.cpp #3162

Conversation

pljones
Copy link
Collaborator

@pljones pljones commented Aug 28, 2023

Short description of changes

Intended to resolve CodeQL messages "Multiplication result converted to larger type".

CHANGELOG: Client: (Refactor) Prevent multiplication result converting to larger type

Context: Fixes an issue?

Fixes -3161

Does this change need documentation? What needs to be documented and how?

No.

Status of this Pull Request

Looks like it fixes the failed checks:
https://github.com/jamulussoftware/jamulus/security/code-scanning?query=pr%3A3162

(Before: https://github.com/jamulussoftware/jamulus/security/code-scanning?query=branch%3Amain)

What is missing until this pull request can be merged?

Code review by a human. Probably, smoke testing would be a good idea, too :)

Checklist

  • I've verified that this Pull Request follows the general code principles
  • I tested my code and it does what I want
  • My code follows the style guide
  • I waited some time after this Pull Request was opened and all GitHub checks completed without errors.
  • I've filled all the content above

AUTOBUILD: Please build all targets

@pljones pljones added the refactoring Non-behavioural changes, Code cleanup label Aug 28, 2023
@pljones pljones self-assigned this Aug 28, 2023
@pljones pljones added this to the Release 3.11.0 milestone Aug 28, 2023
@@ -1257,15 +1257,15 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
if ( bMuteOutStream )
{
iUnused = opus_custom_encode ( CurOpusEncoder,
&vecZeros[i * iNumAudioChannels * iOPUSFrameSizeSamples],
&vecZeros[static_cast<size_t> ( i * iNumAudioChannels * iOPUSFrameSizeSamples )],
Copy link
Member

Choose a reason for hiding this comment

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

We should calculate an upper bound of these and check if that's valid.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i < iSndCrdFrameSizeFactor which is a small number (usually 1, 2 or 4).
iNumAudioChannels is 1 or 2.
SYSTEM_FRAME_SIZE_SAMPLES is 64 and iOPUSFrameSizeSamples is either that or twice that.

So the result should be < 16K.

Copy link
Member

Choose a reason for hiding this comment

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

Exactly, which illustrates why the CodeQL warning is silly in a lot of contexts, including this one.

I have mentioned an alternative way to fix it in the comments on #3161, and have what I think is an even better way just compiling and about to push to a branch.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We're more likely to see buffer overruns -- but we don't.

vecZeros and vecsStereoSndCrd are 2 * Sound.Init ( iPrefMonoFrameSize ), so likely to be < 16K as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think iSndCrdFrameSizeFactor is used to ensure the buffer overruns don't happen, in fact - calculated from the Sound.Init result.

Copy link
Member

Choose a reason for hiding this comment

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

The CodeQL warnings we are addressing are nothing to do with buffer overruns. Just a perceived arithmetic overflow that will never happen with the values we are using.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

With i, iNumAudioChannels and iOPUSFrameSizeSamples as int, however, MAX_INT * MAX_INT * MAX_INT would be out of bounds for the index type.

Copy link
Member

@ann0see ann0see left a comment

Choose a reason for hiding this comment

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

@softins @pgScorpio I think you both have more C++ experience here.
I'd like to hear your review - please focus ONLY on this code. Design flaws are part of other issues.

@ann0see
Copy link
Member

ann0see commented Aug 28, 2023

How would we test this? With a high number of channels all muted?

@@ -1257,15 +1257,15 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
if ( bMuteOutStream )
{
iUnused = opus_custom_encode ( CurOpusEncoder,
&vecZeros[i * iNumAudioChannels * iOPUSFrameSizeSamples],
&vecZeros[static_cast<size_t> ( i * iNumAudioChannels * iOPUSFrameSizeSamples )],
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this fixes it. The multiplication is still done at the smaller size, before casting the result to the larger size, which is already implicit in the [] operator.

To do it by casting, I think you only cast i, which makes the multiplication be done all at size_t:

...[(static_cast<size_t>(i)) * iNumAudioChannels * iOPUSFrameSizeSamples]
...

Copy link
Contributor

Choose a reason for hiding this comment

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

Multiplication will be done in the type of the first operant. Nevertheless if the result is assigned to a smaller type there should still be a check to handle any overflows.

@softins
Copy link
Member

softins commented Aug 29, 2023

How would we test this? With a high number of channels all muted?

We wouldn't. It's purely a theoretical overflow that is just a nuisance in CodeQL. It wouldn't actually be reached until millions of channels. The sole purpose of this change is to silence the CodeQL warnings. And it makes the code slightly less efficient to do so.

@pljones pljones closed this Aug 30, 2023
@pljones pljones deleted the bugfix/3161-conversion-to-larger-type branch August 30, 2023 11:39
@pljones pljones removed this from the Release 3.11.0 milestone Aug 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactoring Non-behavioural changes, Code cleanup
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants