Skip to content

Commit 663e77d

Browse files
committed
Merge branch 'PHP-8.5'
* PHP-8.5: Fix session save-handler argv leak on recursive rejection
2 parents 089fabc + 6c1db26 commit 663e77d

2 files changed

Lines changed: 40 additions & 9 deletions

File tree

ext/session/mod_user.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@ static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval)
2727
PS(in_save_handler) = false;
2828
ZVAL_UNDEF(retval);
2929
php_error_docref(NULL, E_WARNING, "Cannot call session save handler in a recursive manner");
30-
return;
31-
}
32-
PS(in_save_handler) = true;
33-
if (call_user_function(NULL, NULL, func, retval, argc, argv) == FAILURE) {
34-
zval_ptr_dtor(retval);
35-
ZVAL_UNDEF(retval);
36-
} else if (Z_ISUNDEF_P(retval)) {
37-
ZVAL_NULL(retval);
30+
} else {
31+
PS(in_save_handler) = true;
32+
if (call_user_function(NULL, NULL, func, retval, argc, argv) == FAILURE) {
33+
zval_ptr_dtor(retval);
34+
ZVAL_UNDEF(retval);
35+
} else if (Z_ISUNDEF_P(retval)) {
36+
ZVAL_NULL(retval);
37+
}
38+
PS(in_save_handler) = false;
3839
}
39-
PS(in_save_handler) = false;
4040
for (i = 0; i < argc; i++) {
4141
zval_ptr_dtor(&argv[i]);
4242
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
ps_call_handler() releases argv when a recursive save-handler call is rejected
3+
--INI--
4+
session.save_path=
5+
session.name=PHPSESSID
6+
--EXTENSIONS--
7+
session
8+
--FILE--
9+
<?php
10+
class H extends SessionHandler {
11+
public bool $tripped = false;
12+
public function write($id, $data): bool {
13+
if (!$this->tripped) {
14+
$this->tripped = true;
15+
session_destroy();
16+
}
17+
return true;
18+
}
19+
}
20+
21+
session_set_save_handler(new H, true);
22+
session_start();
23+
$_SESSION['x'] = 1;
24+
session_write_close();
25+
echo "done\n";
26+
?>
27+
--EXPECTF--
28+
Warning: session_destroy(): Cannot call session save handler in a recursive manner in %s on line %d
29+
30+
Warning: session_destroy(): Session object destruction failed in %s on line %d
31+
done

0 commit comments

Comments
 (0)