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

PR for Password Hash RFC #191

Merged
merged 48 commits into from
Oct 16, 2012
Merged

PR for Password Hash RFC #191

merged 48 commits into from
Oct 16, 2012

Conversation

ircmaxell
Copy link
Contributor

This is the pull request for the Password Hash RFC which was accepted.

Please review the changes, and if all looks good I will merge the PR in.

Thanks

Anthony

Anthony Ferrara and others added 30 commits June 24, 2012 22:44
* upstream/master: (34 commits)
  Fixed Bug #62500 (Segfault in DateInterval class when extended)
  Fixed test bug #62312 (warnings changed one more time)
  fix valgrind warning
  fix valgrind warning
  fixed #62433 test for win
  update NEWS
  Fixed bug #62499 (curl_setopt($ch, CURLOPT_COOKIEFILE, "") returns false)
  appease MSVC (doesnt like unary minus of unsigned ints)
  appease MSVC (doesnt like unary minus of unsigned ints)
  appease MSVC (doesnt like unary minus of unsigned ints)
  - Fixed bug #62507 (['REQUEST_TIME'] under mod_php5 returns miliseconds instead of seconds)
  Fixed Bug #62500 (Segfault in DateInterval class when extended)
  Added in NEWS and UPGRADING for feature 55218
  Fix two issues with run-tests.php
  Fix potential integer overflow in nl2br
  Fix potential integer overflow in bin2hex
  This wil be PHP 5.3.16
  Revert change 3f3ad30: There shouldn't be new features in 5.3, especially not if they aren't in 5.4, too.
  fix (signed) integer overflow (part of bug #52550
  fix (signed) integer overflow (part of bug #52550
  ...
* upstream/master: (393 commits)
  forked two tests for windows
  Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice)
  Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice).
  Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice).
  Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice)
  Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice)
  Bug #49510: Boolean validation fails with FILTER_NULL_ON_FAILURE with empty string or false
  Implemented ReflectionFunction::isGenerator()
  Allow null as a default value for length in mb_substr() and mb_strcut()
  Allow null as a default value for length in mb_substr() and mb_strcut()
  folder
  Initializing optional argument description in assert()
  Initializing optional argument description in assert()
  Fix test failed due to new Token T_YIELD
  fix NEWS
  Fix leak when yielding array as key
  Drop obsolete test
  Remove extra blank in notice message, should act as same as vm
  Fixed bug #62987 (Assigning to ArrayObject[null][something] overrides all undefined variables)
  assert() user message
  ...
@ircmaxell
Copy link
Contributor Author

I've just added a commit to switch the algorithms definition to an ENUM (cleaner and allows for better type checking in the algos functions...

typedef enum {
PASSWORD_UNKNOWN,
PASSWORD_BCRYPT
} php_password_algos;
Copy link
Member

Choose a reason for hiding this comment

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

I'd rather call this enum php_password_algo (singular) as it fits in better with parameters and return values. Also I don't see why you removed the PHP_ prefix for the enum values. Those are global, so they should be prefixed too. (Only C++11 has proper non-global enum class values.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed by the next push.

ZEND_BEGIN_ARG_INFO_EX(arginfo_password_get_info, 0, 0, 1)
ZEND_ARG_INFO(0, hash)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_password_needs_rehash, 0, 0, 1)
Copy link
Member

Choose a reason for hiding this comment

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

Here again the last arg should be 2 (as the algo is required too).

{
int newCost = PHP_PASSWORD_BCRYPT_COST, cost = 0;

if (options && zend_symtable_find(options, "cost", 5, (void **) &option_buffer) == SUCCESS) {
Copy link
Member

Choose a reason for hiding this comment

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

Use of the symtable function is not necessary here (only required when you're taking user input as the key), could be just zend_hash_find. The 5 would be better written as sizeof("cost"), to clarify its meaning.

if (options && zend_symtable_find(options, "cost", 5, (void **) &option_buffer) == SUCCESS) {
convert_to_long_ex(option_buffer);
newCost = Z_LVAL_PP(option_buffer);
zval_ptr_dtor(option_buffer);
Copy link
Member

Choose a reason for hiding this comment

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

This zval_ptr_dtor isn't right here. zend_symtable_find does not add an additional ref. Though I'm a bit confused now how this should be properly done when convert_to_long_ex is used...

Copy link
Member

Choose a reason for hiding this comment

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

An example what would usually happen:

==7601== Invalid read of size 4
==7601==    at 0x8250A1E: _zval_ptr_dtor (zend.h:404)
==7601==    by 0x826235E: _zval_ptr_dtor_wrapper (zend_variables.c:180)
==7601==    by 0x8276453: zend_hash_destroy (zend_hash.c:560)
==7601==    by 0x8261EFB: _zval_dtor_func (zend_variables.c:43)
==7601==    by 0x82A6E58: zend_do_fcall_common_helper_SPEC (zend_variables.h:35)
==7601==    by 0x82AE0B9: ZEND_DO_FCALL_SPEC_CONST_HANDLER (zend_vm_execute.h:2447)
==7601==    by 0x82A453E: execute_ex (zend_vm_execute.h:440)
==7601==    by 0x82A4614: execute (zend_vm_execute.h:464)
==7601==    by 0x826665C: zend_execute_scripts (zend.c:1309)
==7601==    by 0x81C861B: php_execute_script (main.c:2459)
==7601==    by 0x83C5358: do_cli (php_cli.c:988)
==7601==    by 0x83C6893: main (php_cli.c:1364)
==7601==  Address 0x43ebe68 is 8 bytes inside a block of size 20 free'd
==7601==    at 0x402B06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==7601==    by 0x822C56A: _efree (zend_alloc.c:2433)
==7601==    by 0x8250AFD: _zval_ptr_dtor (zend_execute_API.c:440)
==7601==    by 0x81BDC94: zif_password_needs_rehash (password.c:250)
==7601==    by 0x82A5FBE: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:655)

=> The value is first freed here and later in the hash dtor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All memory leaks that I could find have been rectified. Please test again...

@nikic
Copy link
Member

nikic commented Oct 6, 2012

I'm still getting a lot of valgrind warnings, e.g.

=29932== Invalid read of size 1
==29932==    at 0x8261B61: _zval_dtor_func (zend_variables.c:35)
==29932==    by 0x82507FE: _zval_ptr_dtor (zend_variables.h:35)
==29932==    by 0x826208A: _zval_ptr_dtor_wrapper (zend_variables.c:180)
==29932==    by 0x827617F: zend_hash_destroy (zend_hash.c:560)
==29932==    by 0x8261C27: _zval_dtor_func (zend_variables.c:43)
==29932==    by 0x82A6B84: zend_do_fcall_common_helper_SPEC (zend_variables.h:35)
==29932==    by 0x82ADDE5: ZEND_DO_FCALL_SPEC_CONST_HANDLER (zend_vm_execute.h:2447)
==29932==    by 0x82A426A: execute_ex (zend_vm_execute.h:440)
==29932==    by 0x82A4340: execute (zend_vm_execute.h:464)
==29932==    by 0x8266388: zend_execute_scripts (zend.c:1309)
==29932==    by 0x81C8347: php_execute_script (main.c:2459)
==29932==    by 0x83C5084: do_cli (php_cli.c:988)
==29932==  Address 0x43ee77b is 3 bytes inside a block of size 4 free'd
==29932==    at 0x402B06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==29932==    by 0x822C296: _efree (zend_alloc.c:2433)
==29932==    by 0x825953C: convert_to_long_base (zend_operators.c:394)
==29932==    by 0x82593FD: convert_to_long (zend_operators.c:364)
==29932==    by 0x81BDF0E: zif_password_hash (password.c:332)
==29932==    by 0x82A5CEA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:655)
==29932==    by 0x82ADDE5: ZEND_DO_FCALL_SPEC_CONST_HANDLER (zend_vm_execute.h:2447)
==29932==    by 0x82A426A: execute_ex (zend_vm_execute.h:440)
==29932==    by 0x82A4340: execute (zend_vm_execute.h:464)
==29932==    by 0x8266388: zend_execute_scripts (zend.c:1309)
==29932==    by 0x81C8347: php_execute_script (main.c:2459)
==29932==    by 0x83C5084: do_cli (php_cli.c:988)

==29932== Invalid free() / delete / delete[] / realloc()
==29932==    at 0x402B06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==29932==    by 0x822C296: _efree (zend_alloc.c:2433)
==29932==    by 0x8261BCA: _zval_dtor_func (zend_variables.c:36)
==29932==    by 0x82507FE: _zval_ptr_dtor (zend_variables.h:35)
==29932==    by 0x826208A: _zval_ptr_dtor_wrapper (zend_variables.c:180)
==29932==    by 0x827617F: zend_hash_destroy (zend_hash.c:560)
==29932==    by 0x8261C27: _zval_dtor_func (zend_variables.c:43)
==29932==    by 0x82A6B84: zend_do_fcall_common_helper_SPEC (zend_variables.h:35)
==29932==    by 0x82ADDE5: ZEND_DO_FCALL_SPEC_CONST_HANDLER (zend_vm_execute.h:2447)
==29932==    by 0x82A426A: execute_ex (zend_vm_execute.h:440)
==29932==    by 0x82A4340: execute (zend_vm_execute.h:464)
==29932==    by 0x8266388: zend_execute_scripts (zend.c:1309)
==29932==  Address 0x43ee778 is 0 bytes inside a block of size 4 free'd
==29932==    at 0x402B06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==29932==    by 0x822C296: _efree (zend_alloc.c:2433)
==29932==    by 0x825953C: convert_to_long_base (zend_operators.c:394)
==29932==    by 0x82593FD: convert_to_long (zend_operators.c:364)
==29932==    by 0x81BDF0E: zif_password_hash (password.c:332)
==29932==    by 0x82A5CEA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:655)
==29932==    by 0x82ADDE5: ZEND_DO_FCALL_SPEC_CONST_HANDLER (zend_vm_execute.h:2447)
==29932==    by 0x82A426A: execute_ex (zend_vm_execute.h:440)
==29932==    by 0x82A4340: execute (zend_vm_execute.h:464)
==29932==    by 0x8266388: zend_execute_scripts (zend.c:1309)
==29932==    by 0x81C8347: php_execute_script (main.c:2459)
==29932==    by 0x83C5084: do_cli (php_cli.c:988)
==29932==

@nikic
Copy link
Member

nikic commented Oct 6, 2012

Also from a quick look at the new code, you're using INIT_PZVAL_COPY to copy the zval, but that macro doesn't invoke the copy constructor. You should use MAKE_COPY_ZVAL instead. (This might be related to the invalid reads above. The lack of copy_ctor probably causes a double free on a string.)

@ircmaxell
Copy link
Contributor Author

Can you provide the test code, so I can integrate it with the unit tests?
On Oct 6, 2012 4:40 PM, "nikic" [email protected] wrote:

Also from a quick look at the new code, you're using INIT_PZVAL_COPY to
copy the zval, but that macro doesn't invoke the copy constructor. You
should use MAKE_COPY_ZVAL instead. (This might be related to the invalid
reads above. The lack of copy_ctor probably causes a double free on a
string.)


Reply to this email directly or view it on GitHubhttps://github.com//pull/191#issuecomment-9199240.

@nikic
Copy link
Member

nikic commented Oct 6, 2012

@ircmaxell I get that when running ext/standard/tests/password/password_bcrypt_errors.phpt. I compiled using --disable-all --enable-debug --enable-maintainer-zts.

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