Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
php7.8581
php-CVE-2016-7479.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File php-CVE-2016-7479.patch of Package php7.8581
Index: php-7.0.7/ext/standard/var_unserializer.re =================================================================== --- php-7.0.7.orig/ext/standard/var_unserializer.re 2017-01-16 16:32:01.842652977 +0100 +++ php-7.0.7/ext/standard/var_unserializer.re 2017-01-16 16:33:17.751895627 +0100 @@ -26,6 +26,9 @@ #define VAR_ENTRIES_MAX 1024 #define VAR_ENTRIES_DBG 0 +/* VAR_FLAG used in var_dtor entries to signify an entry on which __wakeup should be called */ +#define VAR_WAKEUP_FLAG 1 + typedef struct { zval *data[VAR_ENTRIES_MAX]; zend_long used_slots; @@ -94,6 +97,7 @@ PHPAPI zval *var_tmp_var(php_unserialize (*var_hashx)->last_dtor = var_hash; } ZVAL_UNDEF(&var_hash->data[var_hash->used_slots]); + Z_VAR_FLAGS(var_hash->data[var_hash->used_slots]) = 0; return &var_hash->data[var_hash->used_slots++]; } @@ -141,6 +145,10 @@ PHPAPI void var_destroy(php_unserialize_ zend_long i; var_entries *var_hash = (*var_hashx)->first; var_dtor_entries *var_dtor_hash = (*var_hashx)->first_dtor; + zend_bool wakeup_failed = 0; + zval wakeup_name; + ZVAL_UNDEF(&wakeup_name); + #if VAR_ENTRIES_DBG fprintf(stderr, "var_destroy(%ld)\n", var_hash?var_hash->used_slots:-1L); #endif @@ -153,15 +161,40 @@ PHPAPI void var_destroy(php_unserialize_ while (var_dtor_hash) { for (i = 0; i < var_dtor_hash->used_slots; i++) { + zval *zv = &var_dtor_hash->data[i]; #if VAR_ENTRIES_DBG fprintf(stderr, "var_destroy dtor(%p, %ld)\n", var_dtor_hash->data[i], Z_REFCOUNT_P(var_dtor_hash->data[i])); #endif - zval_ptr_dtor(&var_dtor_hash->data[i]); + + /* Perform delayed __wakeup calls */ + if (Z_VAR_FLAGS_P(zv) == VAR_WAKEUP_FLAG) { + if (!wakeup_failed) { + zval retval; + if (Z_ISUNDEF(wakeup_name)) { + ZVAL_STRINGL(&wakeup_name, "__wakeup", sizeof("__wakeup") - 1); + } + + BG(serialize_lock)++; + if (call_user_function_ex(CG(function_table), zv, &wakeup_name, &retval, 0, 0, 1, NULL) == FAILURE || Z_ISUNDEF(retval)) { + wakeup_failed = 1; + GC_FLAGS(Z_OBJ_P(zv)) |= IS_OBJ_DESTRUCTOR_CALLED; + } + BG(serialize_lock)--; + + zval_ptr_dtor(&retval); + } else { + GC_FLAGS(Z_OBJ_P(zv)) |= IS_OBJ_DESTRUCTOR_CALLED; + } + } + + zval_ptr_dtor(zv); } next = var_dtor_hash->next; efree_size(var_dtor_hash, sizeof(var_dtor_entries)); var_dtor_hash = next; } + + zval_ptr_dtor(&wakeup_name); } /* }}} */ @@ -481,19 +514,11 @@ static inline int object_common2(UNSERIA } ZVAL_DEREF(rval); - if (has_wakeup) { - ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1); - BG(serialize_lock)++; - if (call_user_function_ex(CG(function_table), rval, &fname, &retval, 0, 0, 1, NULL) == FAILURE || Z_ISUNDEF(retval)) { - GC_FLAGS(Z_OBJ_P(rval)) |= IS_OBJ_DESTRUCTOR_CALLED; - } - BG(serialize_lock)--; - zval_dtor(&fname); - zval_dtor(&retval); - } - - if (EG(exception)) { - return 0; + if (has_wakeup) { + /* Delay __wakeup call until end of serialization */ + zval *wakeup_var = var_tmp_var(var_hash); + ZVAL_COPY(wakeup_var, rval); + Z_VAR_FLAGS_P(wakeup_var) = VAR_WAKEUP_FLAG; } return finish_nested_data(UNSERIALIZE_PASSTHRU);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor