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

src: fix freeing unintialized pointer bug in ParseSoaReply #35502

Merged
merged 1 commit into from Oct 8, 2020

Conversation

Copy link
Contributor

@AasthaGupta AasthaGupta commented Oct 4, 2020

ares_expand_name doesn't guarantee that pointer variable is initialized if
return code is ARES_EBADNAME or ARES_ENOMEM. But current usage of the function
in the codebase thinks otherwise.

There seems to be an assumption that pointer is always initialized even though
it is a local variable and we create a unique pointer soon after calling
ares_expand_name. This could potentially crash
the program with an invalid free pointer.

I was able to crash it by poisoning the memory and some manual hooks.

node(9118,0x111471dc0) malloc: *** error for object 0x7b: pointer being freed was not allocated
node(9118,0x111471dc0) malloc: *** set a breakpoint in malloc_error_break to debug
[1] 9118 abort node ../temp.js

By moving the unique_ptr after checking the return code we can fix the problem.
As the underlying function guarantees that pointer is initialized when the
status is ARES_SUCCESS.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines

@AasthaGupta AasthaGupta requested a review from as a code owner Oct 4, 2020
@nodejs-github-bot
Copy link
Contributor

@nodejs-github-bot nodejs-github-bot commented Oct 4, 2020

Review requested:

@nodejs-github-bot nodejs-github-bot added c++ cares labels Oct 4, 2020
@AasthaGupta AasthaGupta force-pushed the pointer-dealloc branch 2 times, most recently from 414fd5a to a23655a Compare Oct 4, 2020
@addaleax
Copy link
Member

@addaleax addaleax commented Oct 4, 2020

Would it make sense to initialize the pointer variables with nullptr instead? That way the code is a bit more “obviously correct”, because then it’s clear (without checking the c-ares API documentation ) that 1. we never leak memory, because unique_ptr always takes ownership, and 2. we never access uninitialized memory, because if the call fails, the unique_ptr will just be empty.

Copy link
Member

@addaleax addaleax left a comment

LGTM either way, but I think initializing the pointers with nullptr instead might be a bit clearer :)

@AasthaGupta
Copy link
Contributor Author

@AasthaGupta AasthaGupta commented Oct 4, 2020

I totally agree with your comment @addaleax

Let me also initialize the variable with nullptr :)

@AasthaGupta
Copy link
Contributor Author

@AasthaGupta AasthaGupta commented Oct 5, 2020

@addaleax Is there anything else that needs to be done?

@addaleax
Copy link
Member

@addaleax addaleax commented Oct 5, 2020

@AasthaGupta We currently have a 48-hour waiting period before PRs are merged, so that’s why this isn’t merged yet. :)

(Btw, my original suggestion here was to initialize with nullptr instead of moving the unique_ptr construction sites, not in addition to – that way it would be clear that any memory allocated by c-ares would always be released without knowing how c-ares works, because even if c-ares did allocate and store data, that would be okay then. But since that’s not what’s currently happening in practice, this isn’t really important to me. :))

@addaleax addaleax added the request-ci label Oct 5, 2020
@github-actions github-actions bot removed the request-ci label Oct 5, 2020
@nodejs-github-bot
Copy link
Contributor

@nodejs-github-bot nodejs-github-bot commented Oct 5, 2020

@addaleax addaleax added author ready review wanted labels Oct 5, 2020
Trott
Trott approved these changes Oct 5, 2020
ares_expand_name doesn't guarantee that pointer variable is initialized
if return code is ARES_EBADNAME or ARES_ENOMEM. But current usage of the
function in the codebase thinks otherwise.

There seems to be an assumption that pointer is always initialized even
though it is a local variable and we create a unique pointer soon after
calling ares_expand_name. This could potentially crash the program with
an invalid free pointer.

I was able to crash it by poisoning the memory and some manual hooks.

By moving the unique_ptr after checking the return code we can fix the
problem. As the underlying function guarantees that pointer is
initialized when the status is ARES_SUCCESS.

PR-URL: nodejs#35502
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
@Trott Trott merged commit 0f41bca into nodejs:master Oct 8, 2020
26 checks passed
@Trott
Copy link
Member

@Trott Trott commented Oct 8, 2020

Landed in 0f41bca.

Thanks for the contribution! 🎉

BethGriggs pushed a commit that referenced this issue Oct 13, 2020
ares_expand_name doesn't guarantee that pointer variable is initialized
if return code is ARES_EBADNAME or ARES_ENOMEM. But current usage of the
function in the codebase thinks otherwise.

There seems to be an assumption that pointer is always initialized even
though it is a local variable and we create a unique pointer soon after
calling ares_expand_name. This could potentially crash the program with
an invalid free pointer.

I was able to crash it by poisoning the memory and some manual hooks.

By moving the unique_ptr after checking the return code we can fix the
problem. As the underlying function guarantees that pointer is
initialized when the status is ARES_SUCCESS.

PR-URL: #35502
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
@MylesBorins MylesBorins mentioned this pull request Oct 14, 2020
MylesBorins pushed a commit that referenced this issue Nov 3, 2020
ares_expand_name doesn't guarantee that pointer variable is initialized
if return code is ARES_EBADNAME or ARES_ENOMEM. But current usage of the
function in the codebase thinks otherwise.

There seems to be an assumption that pointer is always initialized even
though it is a local variable and we create a unique pointer soon after
calling ares_expand_name. This could potentially crash the program with
an invalid free pointer.

I was able to crash it by poisoning the memory and some manual hooks.

By moving the unique_ptr after checking the return code we can fix the
problem. As the underlying function guarantees that pointer is
initialized when the status is ARES_SUCCESS.

PR-URL: #35502
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
@MylesBorins MylesBorins mentioned this pull request Nov 3, 2020
MylesBorins pushed a commit that referenced this issue Nov 16, 2020
ares_expand_name doesn't guarantee that pointer variable is initialized
if return code is ARES_EBADNAME or ARES_ENOMEM. But current usage of the
function in the codebase thinks otherwise.

There seems to be an assumption that pointer is always initialized even
though it is a local variable and we create a unique pointer soon after
calling ares_expand_name. This could potentially crash the program with
an invalid free pointer.

I was able to crash it by poisoning the memory and some manual hooks.

By moving the unique_ptr after checking the return code we can fix the
problem. As the underlying function guarantees that pointer is
initialized when the status is ARES_SUCCESS.

PR-URL: #35502
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
joesepi pushed a commit to joesepi/node that referenced this issue Jan 8, 2021
ares_expand_name doesn't guarantee that pointer variable is initialized
if return code is ARES_EBADNAME or ARES_ENOMEM. But current usage of the
function in the codebase thinks otherwise.

There seems to be an assumption that pointer is always initialized even
though it is a local variable and we create a unique pointer soon after
calling ares_expand_name. This could potentially crash the program with
an invalid free pointer.

I was able to crash it by poisoning the memory and some manual hooks.

By moving the unique_ptr after checking the return code we can fix the
problem. As the underlying function guarantees that pointer is
initialized when the status is ARES_SUCCESS.

PR-URL: nodejs#35502
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready c++ cares review wanted
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants