]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.3' into PHP-7.4
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 31 Jan 2020 09:29:26 +0000 (10:29 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 31 Jan 2020 09:29:45 +0000 (10:29 +0100)
* PHP-7.3:
  Fix bug #76047

1  2 
NEWS
Zend/tests/bug78973.phpt
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --cc NEWS
index a4ef1ef469b1169cd1a20c18dd8859dfc49c528c,be9592d19353ed1cd17d7f8c2bb11c7bd4b66036..bc617738de2887bda12e845a8c6e1b4520c983e2
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,15 -1,14 +1,17 @@@
  PHP                                                                        NEWS
  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 -?? ??? ????, PHP 7.3.15
 +?? ??? ????, PHP 7.4.3
  
  - Core:
 -  . Fixed bug #71876 (Memory corruption htmlspecialchars(): charset `*' not
 -    supported). (Nikita)
 -  . Fixed bug ##79146 (cscript can fail to run on some systems). (clarodeus)
 +  . Fixed bug #79146 (cscript can fail to run on some systems). (clarodeus)
 +  . Fixed bug #79155 (Property nullability lost when using multiple property
 +    definition). (Nikita)
    . Fixed bug #78323 (Code 0 is returned on invalid options). (Ivan Mikheykin)
 +  . Fixed bug #78989 (Delayed variance check involving trait segfaults).
 +    (Nikita)
 +  . Fixed bug #79174 (cookie values with spaces fail to round-trip). (cmb)
+   . Fixed bug #76047 (Use-after-free when accessing already destructed
+     backtrace arguments). (Nikita)
  
  - CURL:
    . Fixed bug #79078 (Hypothetical use-after-free in curl_multi_add_handle()).
index e1286e0a85116bcf26fb8510fbf5a0c921c97b68,0000000000000000000000000000000000000000..688f4e6cc54e02fc3e8480faf7ca3d318dc91876
mode 100644,000000..100644
--- /dev/null
@@@ -1,19 -1,0 +1,18 @@@
- #1  test() called at [%s:%d]
 +--TEST--
 +Bug #78973: Destructor during CV freeing causes segfault if opline never saved
 +--INI--
 +opcache.optimization_level=0
 +--FILE--
 +<?php
 +
 +function test($x) {
 +}
 +test(new class {
 +    public function __destruct() {
 +        debug_print_backtrace();
 +    }
 +});
 +
 +?>
 +--EXPECTF--
 +#0  class@anonymous->__destruct() called at [%s:%d]
index 1499b4b5ef4b87820d416e975349f8ce2ce17141,fbd79019e762987e5b4d699d4cba11ce5bf3df9f..f33d07b738f6d6e51831625a522d69b3ee037cb6
@@@ -2873,17 -2396,22 +2873,17 @@@ ZEND_VM_HOT_HELPER(zend_leave_helper, A
  {
        zend_execute_data *old_execute_data;
        uint32_t call_info = EX_CALL_INFO();
 +      SAVE_OPLINE();
  
        if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
+               EG(current_execute_data) = EX(prev_execute_data);
                i_free_compiled_variables(execute_data);
  
 -              if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
 -                      zend_object *object = Z_OBJ(execute_data->This);
 -#if 0
 -                      if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
 -#else
 -                      if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) {
 +#ifdef ZEND_PREFER_RELOAD
 +              call_info = EX_CALL_INFO();
  #endif
-               EG(current_execute_data) = EX(prev_execute_data);
 -                              GC_DELREF(object);
 -                              zend_object_store_ctor_failed(object);
 -                      }
 -                      OBJ_RELEASE(object);
 +              if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
 +                      OBJ_RELEASE(Z_OBJ(execute_data->This));
                } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
                        OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
                }
                LOAD_NEXT_OPLINE();
                ZEND_VM_LEAVE();
        } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
+               EG(current_execute_data) = EX(prev_execute_data);
                i_free_compiled_variables(execute_data);
  
 +#ifdef ZEND_PREFER_RELOAD
 +              call_info = EX_CALL_INFO();
 +#endif
                if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
                        zend_clean_and_cache_symbol_table(EX(symbol_table));
                }
                ZEND_VM_LEAVE();
        } else {
                if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
+                       EG(current_execute_data) = EX(prev_execute_data);
                        i_free_compiled_variables(execute_data);
 +#ifdef ZEND_PREFER_RELOAD
 +                      call_info = EX_CALL_INFO();
 +#endif
                        if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
                                if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
                                        zend_clean_and_cache_symbol_table(EX(symbol_table));
index 1e5f6455e3a10a5bc5b6797fc49c5a41feebc5e9,33518478c32e9731549a7e4b04935f83b95ec50f..3987d1b94501deef03a297fb47019aed8d38e262
@@@ -1130,17 -505,22 +1130,17 @@@ static zend_never_inline ZEND_OPCODE_HA
  {
        zend_execute_data *old_execute_data;
        uint32_t call_info = EX_CALL_INFO();
 +      SAVE_OPLINE();
  
        if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
+               EG(current_execute_data) = EX(prev_execute_data);
                i_free_compiled_variables(execute_data);
  
 -              if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
 -                      zend_object *object = Z_OBJ(execute_data->This);
 -#if 0
 -                      if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
 -#else
 -                      if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) {
 +#ifdef ZEND_PREFER_RELOAD
 +              call_info = EX_CALL_INFO();
  #endif
-               EG(current_execute_data) = EX(prev_execute_data);
 -                              GC_DELREF(object);
 -                              zend_object_store_ctor_failed(object);
 -                      }
 -                      OBJ_RELEASE(object);
 +              if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
 +                      OBJ_RELEASE(Z_OBJ(execute_data->This));
                } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
                        OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
                }
                LOAD_NEXT_OPLINE();
                ZEND_VM_LEAVE();
        } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
+               EG(current_execute_data) = EX(prev_execute_data);
                i_free_compiled_variables(execute_data);
  
 +#ifdef ZEND_PREFER_RELOAD
 +              call_info = EX_CALL_INFO();
 +#endif
                if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
                        zend_clean_and_cache_symbol_table(EX(symbol_table));
                }
                ZEND_VM_LEAVE();
        } else {
                if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
+                       EG(current_execute_data) = EX(prev_execute_data);
                        i_free_compiled_variables(execute_data);
 +#ifdef ZEND_PREFER_RELOAD
 +                      call_info = EX_CALL_INFO();
 +#endif
                        if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
                                if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
                                        zend_clean_and_cache_symbol_table(EX(symbol_table));
@@@ -53672,17 -55377,22 +53672,17 @@@ zend_leave_helper_SPEC_LABEL
  {
        zend_execute_data *old_execute_data;
        uint32_t call_info = EX_CALL_INFO();
 +      SAVE_OPLINE();
  
        if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
+               EG(current_execute_data) = EX(prev_execute_data);
                i_free_compiled_variables(execute_data);
  
 -              if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
 -                      zend_object *object = Z_OBJ(execute_data->This);
 -#if 0
 -                      if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
 -#else
 -                      if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) {
 +#ifdef ZEND_PREFER_RELOAD
 +              call_info = EX_CALL_INFO();
  #endif
-               EG(current_execute_data) = EX(prev_execute_data);
 -                              GC_DELREF(object);
 -                              zend_object_store_ctor_failed(object);
 -                      }
 -                      OBJ_RELEASE(object);
 +              if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
 +                      OBJ_RELEASE(Z_OBJ(execute_data->This));
                } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
                        OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
                }
                LOAD_NEXT_OPLINE();
                ZEND_VM_LEAVE();
        } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
+               EG(current_execute_data) = EX(prev_execute_data);
                i_free_compiled_variables(execute_data);
  
 +#ifdef ZEND_PREFER_RELOAD
 +              call_info = EX_CALL_INFO();
 +#endif
                if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
                        zend_clean_and_cache_symbol_table(EX(symbol_table));
                }
                ZEND_VM_LEAVE();
        } else {
                if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
+                       EG(current_execute_data) = EX(prev_execute_data);
                        i_free_compiled_variables(execute_data);
 +#ifdef ZEND_PREFER_RELOAD
 +                      call_info = EX_CALL_INFO();
 +#endif
                        if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
                                if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
                                        zend_clean_and_cache_symbol_table(EX(symbol_table));