Skip to content

Conversation

pprindeville
Copy link
Contributor

Tested by @MikePetullo here

@tpunt
Copy link
Contributor

tpunt commented Jan 25, 2018

This looks good to me. Also, whilst this is a little tangential, the calling sites for php_iconv_string could also be cleaned up a little by not even bothering to free the allocated out buffer, since it will always be freed by the function itself on error (so places such as here and here).

@pprindeville
Copy link
Contributor Author

@tpunt Did you want me to make that PR as well? Or amend this one?

pprindeville added a commit to pprindeville/packages that referenced this pull request Jan 25, 2018
Depending on which version of libiconv you're using, php_iconv_string()
doesn't always null out *out as part of its initialization.  This
patch makes that behavior invariant.

Submitted upstream as php/php-src#3037 where
it's approved and waiting a merge.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
pprindeville added a commit to pprindeville/packages that referenced this pull request Jan 25, 2018
Depending on which version of libiconv you're using, php_iconv_string()
doesn't always null out *out as part of its initialization.  This
patch makes that behavior invariant.

Submitted upstream as php/php-src#3037 where
it's approved and waiting a merge.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
@tpunt
Copy link
Contributor

tpunt commented Jan 25, 2018

Since removing the superfluous buffer freeing logic would also fix this problem, I'd say just amend this PR with those changes too.

@pprindeville
Copy link
Contributor Author

Done. Ran make test with no surprises.

pprindeville added a commit to pprindeville/packages that referenced this pull request Jan 25, 2018
Depending on which version of libiconv you're using, php_iconv_string()
doesn't always null out *out as part of its initialization.  This
patch makes that behavior invariant.

Submitted upstream as php/php-src#3037 where
it's approved and waiting a merge.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
@pprindeville
Copy link
Contributor Author

@tpunt Are these being affected as a side-effect?

=====================================================================
FAILED TEST SUMMARY
---------------------------------------------------------------------
Bug #48147 (iconv with //IGNORE cuts the string) [ext/iconv/tests/bug48147.phpt]
Bug #52211 (iconv() returns part of string on error) [ext/iconv/tests/bug52211.phpt]
Bug #74230 iconv fails to fail on surrogates [ext/intl/tests/bug74230.phpt]
=====================================================================

Haven't read the test cases so I'm not sure what the scenarios are...

@tpunt
Copy link
Contributor

tpunt commented Jan 25, 2018

Ah, my mistake, it appears the out buffer is not always being freed when erroring. It's strange that the function frees the buffer in the first ifdefed block, but not in the second... Whilst it would probably be best to make them the same (always free on error, since it allocates the buffer), I think that's outside the scope of this PR. The original fix of just nullifying *out therefore seems best.

Also, don't bother checking returned point in error case since it
will always be NULL (and not require free()ing, obviously).
@pprindeville
Copy link
Contributor Author

Just trying to see what Travis finds that doesn't turn up locally if we do as you suggest and always free on error.

@pprindeville
Copy link
Contributor Author

pprindeville commented Jan 25, 2018

@tpunt Well, I took your suggestion all the way and the build didn't have any Failed Tests.

I separated the commits to the original/minimal fix plus the more complete fixes. You can merge just the first or both, as you see fit.

val-kulkov pushed a commit to val-kulkov/openwrt-packages that referenced this pull request Jan 26, 2018
Depending on which version of libiconv you're using, php_iconv_string()
doesn't always null out *out as part of its initialization.  This
patch makes that behavior invariant.

Submitted upstream as php/php-src#3037 where
it's approved and waiting a merge.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
@pprindeville
Copy link
Contributor Author

@tpunt Let me know if you need anything else, otherwise I'm assuming we're good to go.

@tpunt
Copy link
Contributor

tpunt commented Jan 26, 2018

@pprindeville This looks fine to me. I don't have the appropriate karma to merge your PR, though. Perhaps @nikic could merge this instead.

@pprindeville
Copy link
Contributor Author

@tpunt Thanks, understood.

iconv_close(cd);

if (result == (size_t)(-1)) {
zend_string_free(out_buf);
Copy link
Member

Choose a reason for hiding this comment

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

This will cause a use-after-free of out_buf in the code below. If we free out_buf here, then the breaks in the switch below need to be changed to returns. (As is the case for PHP_ICONV_ERR_UNKNOWN, which was the only freeing case previously.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, since it's not clear what the semantic is for "return an error but leave a partially populated buffer" I suggest just going with the first commit.

@nikic
Copy link
Member

nikic commented Jan 26, 2018

There is one use of php_iconv_string in https://github.com/pprindeville/php-src/blob/3763c8f1645983b5abc37c60597e1ecc1bf89019/ext/iconv/iconv.c#L437 where the output is used without an error check. I'm thinking that maybe this is why the code made a distinction between different error types -- it want's this case to be able to use the output even if there was some non-fatal error?

No idea whether or not that's really the case, or if this is just an oversight.

@nikic
Copy link
Member

nikic commented Jan 26, 2018

I'd say merge the *out = NULL part for 7.1+ and the rest only for master.

@pprindeville
Copy link
Contributor Author

I'd say merge the *out = NULL part for 7.1+ and the rest only for master.

Given your previous comment, maybe just go with the first commit everywhere?

@pprindeville
Copy link
Contributor Author

Should I prep separate PR's for 7.1 and 7.2 or will someone else cherry-pick them?

@nikic
Copy link
Member

nikic commented Jan 26, 2018

Okay, let's go with the conservative variant... I've merged the first commit as aad76a9 into 7.1+.

@nikic nikic closed this Jan 26, 2018
@pprindeville
Copy link
Contributor Author

@nikic Do I need to prepare PR's for 7.2 and master or is that already done?

@nikic
Copy link
Member

nikic commented Jan 26, 2018

@pprindeville This is already done. We always apply changes to the lowest branch and then merge upward.

@pprindeville
Copy link
Contributor Author

Okay, thanks.

@cmb69
Copy link
Member

cmb69 commented Feb 24, 2018

JFTR: this fixed bug 75867.

lynxis pushed a commit to lynxis/packages that referenced this pull request Jan 3, 2019
Depending on which version of libiconv you're using, php_iconv_string()
doesn't always null out *out as part of its initialization.  This
patch makes that behavior invariant.

Submitted upstream as php/php-src#3037 where
it's approved and waiting a merge.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
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.

4 participants