-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-40020: fix realloc leak on failure in growable_comment_array_add #19083
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
Conversation
Realloc returns a null pointer on failure, and then growable_comment_array_deallocate crashes later when it dereferences it.
are the workflow tests the same thing as the patchcheck tests? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am LGTM with this change
The realloc(3) says that
If realloc() fails the original block is left untouched; it is not freed or moved
Please ignore the test failure, it's the known issue.
@vstinner Please take a look :) |
Parser/parsetok.c
Outdated
@@ -38,10 +38,11 @@ static int | |||
growable_comment_array_add(growable_comment_array *arr, int lineno, char *comment) { | |||
if (arr->num_items >= arr->size) { | |||
arr->size *= 2; | |||
arr->items = realloc(arr->items, arr->size * sizeof(*arr->items)); | |||
if (!arr->items) { | |||
void *const new_items_array = realloc(arr->items, arr->size * sizeof(*arr->items)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the purpose of "const" here. I suggest to remove it. realloc() return type is void *
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, hey, if you guys don't like const correctness, I can do that. Thankfully, I have enough control over my OCD that it works for me :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, while I'm here, should I also not double the array size on the failure path?
And should I squash the multiple commits?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"hey, if you guys": please use a more inclusive expressions, see https://heyguys.cc/ ;-)
"don't like const correctness": it's assigned to arr->items 3 lines below but growable_comment_array.items isn't constant. I don't see the value of using const here.
You should read https://theartofmachinery.com/2019/08/12/c_const_isnt_for_performance.html "Why const Doesn't Make C Code Faster" :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should I also not double the array size on the failure path?
Right, arr->size should only be modified on success. Replace maybe realloc(arr->items, arr->size * sizeof(*arr->items))
with realloc(arr->items, (arr->size * 2) * sizeof(*arr->items))
.
And should I squash the multiple commits?
That's harmful for reviewers. I prefer to see new commits.
We always squash all commits of a PR when it's merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me explain differently: your usage of const is correct. But IMHO it's not worth it, and I see it more as an annoyance for readers.
Once this change will be merged, I would be interested to see a second change to replace realloc() and free() with PyMem_RawRealloc() and PyMem_RawFree(), to benefit of Python builtin memory debugger. Like detecting buffer underflow and overflow in debug mode: https://docs.python.org/dev/c-api/memory.html#c.PyMem_SetupDebugHooks See PYTHONMALLOC=debug. tracemalloc may also benefit of that, but mostly to measure the peak memory usage. I expect that the parser memory is released before the user gets back control on the program. |
As an interesting side note, I think code analysis only found this because the code used raw realloc and free, since |
Ok, how does this look? |
I merged your PR, thanks. I don't think that it's worth it to backport the fix. |
Backport? Nah, no need. |
Fixes bpo-40020. I have signed the CLA, but I don't know if it's active yet.
I don't have make installed on this machine, but I'm setting it up right now to get the patchcheck run. Will update.
realloc returns a null pointer on failure, and then growable_comment_array_deallocate crashes later when it dereferences it.
https://bugs.python.org/issue40020