Skip to content

Conversation

nikic
Copy link
Member

@nikic nikic commented Aug 10, 2016

The (UN)SERIALIZE_INIT/DESTROY macros now go through non-inlined
functions, so any changes to them will apply to extensions without
rebuilds.

Additionally, the (un)serialize_data structures are now no longer
exported.

This means that we are allowed to change these structures in patch
releases without breaking the ABI.

The (UN)SERIALIZE_INIT/DESTROY macros now go through non-inlined
functions, so any changes to them will apply to extensions without
rebuilds.

Additionally, the (un)serialize_data structures are now no longer
exported.

This means that we are allowed to change these structures in patch
releases without breaking the ABI.
@KalleZ
Copy link
Member

KalleZ commented Aug 10, 2016

Great job @nikic , I like this approach a lot and I can see it being even more beneficial with the allowance of changing the structures in patch releases with all the many many recent security related issues due to unserialization. Big +1, I hope this can go into 7.1

cc @dshafik @krakjoe

@nikic
Copy link
Member Author

nikic commented Aug 10, 2016

Motivation is to allow us to do changes like #2050 in a patch release (though that particular one can also be implemented without ABI break in a more complicated fassion, #2004). An example of a bug that likely cannot be fixed without ABI changes is https://bugs.php.net/bug.php?id=72785. I expect that we'll have more security fixes in the future where modifying unserialize data is necessary.

@remicollet
Copy link
Member

+1

@nikic
Copy link
Member Author

nikic commented Aug 15, 2016

@dshafik Any word here?

@dshafik
Copy link
Contributor

dshafik commented Aug 15, 2016

I presume this patch breaks the ABI? (but makes it so we won't have to in future)

What's that going to mean for extension authors upgrading to 7.1?

@nikic
Copy link
Member Author

nikic commented Aug 15, 2016

@dshafik Nothing, unless they manually accessed serialize/unserialize data (which is unlikely). This only means that extensions should be recompiled.

@dshafik
Copy link
Contributor

dshafik commented Aug 15, 2016

@nikic in that case, I would be fine putting it in 7.1 given the amount of security issues lately.

@smalyshev
Copy link
Contributor

The idea looks good to me, also makes fixing bugs like https://bugs.php.net/bug.php?id=72785 easier. I think this should go into 7.1.

@nikic
Copy link
Member Author

nikic commented Aug 15, 2016

Merged via f7caa2b into 7.1.

@nikic nikic closed this Aug 15, 2016
TysonAndre added a commit to TysonAndre/php-src that referenced this pull request Aug 31, 2016
The PHP source code for all versions of php 7 was keeping **pointers**
to object properties, not copies of the object properties.

There are two ways to fix this. This PR chooses the second. So does HHVM.

- Keep copies of **all** zvals instead of pointers to zvals while
  unserializing, increment reference counts.
- Defer calls to __wakeup until the very end. This requires copying only
  the objects of classes implementing __wakeup.
  hhvm handles __wakeup this way.

  https://github.com/facebook/hhvm/blob/2d5f00afbb033aec0cbc51cbe3a897af79cdcb28/hphp/runtime/base/variable-unserializer.cpp#L333
  https://github.com/facebook/hhvm/blob/2d5f00afbb033aec0cbc51cbe3a897af79cdcb28/hphp/runtime/base/variable-unserializer.cpp#L965

Make the publicly exposed APIs var_unserialize and var_unserialize_ex
perform this finalization at the very end.
Many extensions use var_unserialize to unserialize data
(e.g. ext/session, or extensions outside of php-src),
and this change is made in a way that shouldn't break them.

- Move the inner zval deserialization code into a static method, so that
  they won't accidentally be called and miss a call to __wakeup.
- Fix merge conflicts with php#2070
TysonAndre added a commit to TysonAndre/php-src that referenced this pull request Aug 31, 2016
The PHP source code for all versions of php 7 was keeping **pointers**
to object properties, not copies of the object properties.

There are two ways to fix this. This PR chooses the second. So does HHVM.

- Keep copies of **all** zvals instead of pointers to zvals while
  unserializing, increment reference counts.
- Defer calls to __wakeup until the very end. This requires copying only
  the objects of classes implementing __wakeup.
  hhvm handles __wakeup this way.

  https://github.com/facebook/hhvm/blob/2d5f00afbb033aec0cbc51cbe3a897af79cdcb28/hphp/runtime/base/variable-unserializer.cpp#L333
  https://github.com/facebook/hhvm/blob/2d5f00afbb033aec0cbc51cbe3a897af79cdcb28/hphp/runtime/base/variable-unserializer.cpp#L965

Make the publicly exposed APIs var_unserialize and var_unserialize_ex
perform this finalization at the very end.
Many extensions use var_unserialize to unserialize data
(e.g. ext/session, or extensions outside of php-src),
and this change is made in a way that shouldn't break them.

- Move the inner zval deserialization code into a static method, so that
  they won't accidentally be called and miss a call to __wakeup.
- Fix merge conflicts with php#2070
@rlerdorf
Copy link
Member

rlerdorf commented Sep 4, 2016

"This only means that extensions should be recompiled."

Don't we need a PHP API version bump in 7.1 now then? Currently it hasn't been bumped from 7.0

@dshafik
Copy link
Contributor

dshafik commented Sep 4, 2016

@nikic can you confirm and please ensure this is done for RC2 if necessary.

@nikic
Copy link
Member Author

nikic commented Sep 4, 2016

PHP 7.0:

#define ZEND_EXTENSION_API_NO   320151012
#define ZEND_MODULE_API_NO 20151012

PHP 7.1:

#define ZEND_EXTENSION_API_NO   320160303
#define ZEND_MODULE_API_NO 20160303

So API for 7.1 has already been bumped. I think we only do this once per release (when the first API change is done), but not sure.

@rlerdorf
Copy link
Member

rlerdorf commented Sep 4, 2016

Yes, we only bump once per release. However, I meant the PHP API version, not the Zend Extension one.

#define PHP_API_VERSION 20151012

This one hasn't been bumped from 7.0

@nikic
Copy link
Member Author

nikic commented Sep 4, 2016

@rlerdorf Thanks, I wasn't aware we had a third API version. Bumped: 69f0d3d

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.

6 participants