File tree Expand file tree Collapse file tree 3 files changed +35
-4
lines changed
Expand file tree Collapse file tree 3 files changed +35
-4
lines changed Original file line number Diff line number Diff line change 88 . Fixed bug GH-20695 (Assertion failure in normalize_value() when parsing
99 malformed INI input via parse_ini_string()). (ndossche)
1010 . Fixed bug GH-20714 (Uncatchable exception thrown in generator). (ilutov)
11+ . Fixed bug GH-20352 (UAF in php_output_handler_free via re-entrant
12+ ob_start() during error deactivation). (ndossche)
1113
1214- DOM:
1315 . Fixed bug GH-20722 (Null pointer dereference in DOM namespace node cloning
Original file line number Diff line number Diff line change @@ -187,8 +187,12 @@ PHPAPI void php_output_deactivate(void)
187187 /* release all output handlers */
188188 if (OG (handlers ).elements ) {
189189 while ((handler = zend_stack_top (& OG (handlers )))) {
190- php_output_handler_free (handler );
191190 zend_stack_del_top (& OG (handlers ));
191+ /* It's possible to start a new output handler and mark it as active,
192+ * however this loop will destroy all active handlers. */
193+ OG (active ) = NULL ;
194+ ZEND_ASSERT (OG (running ) == NULL && "output is deactivated therefore running should stay NULL" );
195+ php_output_handler_free (handler );
192196 }
193197 }
194198 zend_stack_destroy (& OG (handlers ));
@@ -718,10 +722,11 @@ PHPAPI void php_output_handler_dtor(php_output_handler *handler)
718722 * Destroy and free an output handler */
719723PHPAPI void php_output_handler_free (php_output_handler * * h )
720724{
721- if (* h ) {
722- php_output_handler_dtor (* h );
723- efree (* h );
725+ php_output_handler * handler = * h ;
726+ if (handler ) {
724727 * h = NULL ;
728+ php_output_handler_dtor (handler );
729+ efree (handler );
725730 }
726731}
727732/* }}} */
Original file line number Diff line number Diff line change 1+ --TEST--
2+ GH-20352 (UAF in php_output_handler_free via re-entrant ob_start() during error deactivation)
3+ --FILE--
4+ <?php
5+ class Test {
6+ public function __destruct () {
7+ // Spray output stack
8+ for ($ i = 0 ; $ i < 1000 ; $ i ++)
9+ ob_start (static function () {});
10+ }
11+
12+ public function __invoke ($ x ) {
13+ // Trigger php_output_deactivate() through forbidden operation
14+ ob_start ('foo ' );
15+ return $ x ;
16+ }
17+ }
18+
19+ ob_start (new Test , 1 );
20+
21+ echo "trigger bug " ;
22+ ?>
23+ --EXPECTF--
24+ Fatal error: ob_start(): Cannot use output buffering in output buffering display handlers in %s on line %d
You can’t perform that action at this time.
0 commit comments