Skip to content

C++: Update documentation for cpp/uncontrolled-allocation-size to clarify its scope #17211

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

Merged
merged 4 commits into from
Aug 16, 2024

Conversation

paldepind
Copy link
Contributor

Change the documentation of the cpp/uncontrolled-allocation-size query to clarify its intended behavior/scope.

#11215

Copy link
Contributor

github-actions bot commented Aug 13, 2024

QHelp previews:

cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.qhelp

Uncontrolled allocation size

This code allocates memory using a size value based on user input, with no apparent bound on its magnitude being established. This allows for arbitrary amounts of memory to be allocated.

If the allocation size is calculated by multiplying user input by a sizeof expression, the multiplication can overflow. When an integer multiplication overflows in C, the result wraps around and can be much smaller than intended. A later attempt to write data into the allocated memory can then be out of bounds.

Recommendation

Guard all integer parameters that come from an external user. Implement a guard with the expected range for the parameter and make sure that the input value meets both the minimum and maximum requirements for this range. If the input value fails this guard then reject the request before proceeding further. If the input value passes the guard then subsequent calculations should not overflow.

Example

int factor = atoi(getenv("BRANCHING_FACTOR"));

// BAD: This can allocate too little memory if factor is very large due to overflow.
char **root_node = (char **) malloc(factor * sizeof(char *));

// GOOD: Prevent overflow and unbounded allocation size by checking the input.
if (factor > 0 && factor <= 1000) {
    char **root_node = (char **) malloc(factor * sizeof(char *));
}

This code shows one way to guard that an input value is within the expected range. If factor fails the guard, then an error is returned, and the value is not used as an argument to the subsequent call to malloc. Without this guard, the allocated buffer might be too small to hold the data intended for it.

References

@@ -40,10 +40,10 @@ int main(int argc, char **argv) {
int tainted = atoi(argv[1]);

MyStruct *arr1 = (MyStruct *)malloc(sizeof(MyStruct)); // GOOD
MyStruct *arr2 = (MyStruct *)malloc(tainted); // DUBIOUS (not multiplied by anything)
MyStruct *arr2 = (MyStruct *)malloc(tainted); // BAD
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed this comment as this unbounded allocation size is bad per the updated description of the query.

@paldepind paldepind force-pushed the uncontrolled-allocation-size-docs branch from 9d88021 to 46069af Compare August 13, 2024 11:20
@paldepind paldepind requested a review from geoffw0 August 13, 2024 11:20
Copy link
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

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

Changes LGTM.

Can we change the query message as well ("This allocation size is derived from $@ and might overflow.") to put more focus on the tainted / unbounded allocation size than the possibility (which is likely but not certain) of overflow?

@paldepind paldepind force-pushed the uncontrolled-allocation-size-docs branch from 46069af to 5e8ac5e Compare August 13, 2024 14:27
@paldepind
Copy link
Contributor Author

Good idea, I missed that. I've updated the query message now as well 😄

Copy link
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

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

Looks good to me.

If you add the ready-for-doc-review label, the docs team will check over your .qhelp and query metadata changes.

You should also add the no-change-note-required tag, which will inform CI that you've considered the changes and don't think they require a change note (unless you do, in which case see this doc and it goes here; roughly speaking, any change that affects query results or the way external developers would write queries of their own should have a change note).

@paldepind paldepind added no-change-note-required This PR does not need a change note ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. labels Aug 14, 2024
subatoi
subatoi previously approved these changes Aug 15, 2024
Copy link
Contributor

@subatoi subatoi left a comment

Choose a reason for hiding this comment

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

Looks great, thank you—only some nit comments. Assuming you're happy with the suggestions, feel free to go ahead and merge once you've got an approval from your team (there's no need for me to approve again)

Apologies also if the suggestions mess up some formatting

Comment on lines 7 to 9
<p>This code allocates memory using a size value based on user input
with no apparent bound on its magnitude being established. This allows
for arbitrary amounts of memory being allocated.</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<p>This code allocates memory using a size value based on user input
with no apparent bound on its magnitude being established. This allows
for arbitrary amounts of memory being allocated.</p>
<p>This code allocates memory using a size value based on user input, with no apparent bound on its magnitude being established. This allows for arbitrary amounts of memory to be allocated.</p>

Comment on lines 11 to 15
<p>If the allocation size is calculated by multiplying user input by a
<code>sizeof</code> expression the multiplication can overflow. When
an integer multiplication overflows in C, the result wraps around and
can be much smaller than intended. A later attempt to write data into
the allocated memory can then be out-of-bounds.</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<p>If the allocation size is calculated by multiplying user input by a
<code>sizeof</code> expression the multiplication can overflow. When
an integer multiplication overflows in C, the result wraps around and
can be much smaller than intended. A later attempt to write data into
the allocated memory can then be out-of-bounds.</p>
<p>If the allocation size is calculated by multiplying user input by a
<code>sizeof</code> expression, the multiplication can overflow. When
an integer multiplication overflows in C, the result wraps around and
can be much smaller than intended. A later attempt to write data into
the allocated memory can then be out of bounds.</p>

@paldepind
Copy link
Contributor Author

Thanks @subatoi. I've applied the suggested changes.

Copy link
Contributor

@subatoi subatoi 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!

Copy link
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

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

👍

@paldepind paldepind added the depends on internal PR This PR should only be merged in sync with an internal Semmle PR label Aug 16, 2024
@geoffw0 geoffw0 merged commit b001f47 into github:main Aug 16, 2024
15 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C++ depends on internal PR This PR should only be merged in sync with an internal Semmle PR documentation no-change-note-required This PR does not need a change note ready-for-doc-review This PR requires and is ready for review from the GitHub docs team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants