Skip to content

PHPC-1700: Fix memory leak when read preference is invalid #1179

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 2 commits into from
Nov 25, 2020

Conversation

alcaeus
Copy link
Member

@alcaeus alcaeus commented Nov 19, 2020

PHPC-1700

This fixes a memory leak in php_phongo_readpreference_init_from_hash that is caused by not properly separating zvals before modifying read preference tags. The issue can be observed when MongoDB\Driver\ReadPreference::__set_state errors after preparing tag sets (e.g. because tags were combined with a primary mode). Contrary to the original issue, this problem does not affect other instances where the underlying logic from php_phongo_read_preference_prep_tagsets is used, as the same test (tags with primary read preference) does not leak in the ReadPreference constructor.

This PR also adds a regression test for PHPC-1701 that also assumed the same issue would apply when preparing properties for authentication mechanisms. This test does not leak since all involved zvals are separated, but the test is included to prevent regressions.

@alcaeus alcaeus requested a review from sgolemon November 19, 2020 10:36
@alcaeus alcaeus self-assigned this Nov 19, 2020
if (Z_TYPE_P(tagSets) == IS_ARRAY) {
bson_t* tags = bson_new();

/* Separate tagSets as php_phongo_read_preference_prep_tagsets may
* modify these tags. */
SEPARATE_ZVAL_NOREF(tagSets);
Copy link
Member Author

Choose a reason for hiding this comment

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

Keeping with the tradition of using ZVAL_DEREF and SEPARATE_ZVAL_NOREF. If it's more sensible to use SEPARATE_ZVAL here (and in other cases where we separate), I'd like to create a separate ticket for this.

Copy link
Member

@jmikola jmikola Nov 24, 2020

Choose a reason for hiding this comment

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

Does this address the following comment from PHPC-1700?

Additionally, Manager may also leak if an exception occurs after preparing the readPreferenceTags key in the URI options array. That may be possible if merge_context_options or phongo_manager_init throws.

The fix here is only for php_phongo_readpreference_init_from_hash, which Manager doesn't use.

Copy link
Member Author

Choose a reason for hiding this comment

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

Manager does not leak in that case. manager-ctor-read_prefernece-error-001.phpt already checks for this by attempting to create a manager by combining primary read preference with tags. That test did not leak when I ran it with memcheck.

The leak does not originate from throwing an exception after preparing tagsets, but from the missing zval separation in __set_state. This is also evidenced by the change necessary to fix bug1698-001.phpt, which started failing after the fix. This is because the expectation there is for the tags to be an object after calling __set_state, which shouldn't happen if we separated the zval.

Copy link
Member

@jmikola jmikola left a comment

Choose a reason for hiding this comment

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

One question about Manager's handling of tagsets.

Apart from that, I ran all of the readPreference/ and manager/ tests that use "readPreferenceTags" with Valgrind and observed on leaks; however, I didn't create a separate test where the Manager constructor errors out after preparing tag sets.

Copy link
Member

@jmikola jmikola left a comment

Choose a reason for hiding this comment

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

Thanks for the explanation about set_state. That makes more sense.

@alcaeus alcaeus merged commit d70efb6 into mongodb:v1.9 Nov 25, 2020
@alcaeus alcaeus deleted the phpc-1700 branch November 25, 2020 09:39
alcaeus added a commit that referenced this pull request Nov 25, 2020
* v1.9:
  PHPC-1700: Fix memory leak when read preference is invalid (#1179)
  PHPC-1706: Don't try linking against libresolv on AIX (#1172)
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.

2 participants