Skip to content

Commit 3930b6f

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: ext/session: Fix GH-17541 (ext/session NULL pointer dereferencement during ID reset)
2 parents d003511 + d35904a commit 3930b6f

File tree

4 files changed

+46
-19
lines changed

4 files changed

+46
-19
lines changed

ext/session/session.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ zend_class_entry *php_session_update_timestamp_iface_entry;
9494
}
9595

9696
#define SESSION_FORBIDDEN_CHARS "=,;.[ \t\r\n\013\014"
97+
#define SESSION_FORBIDDEN_CHARS_FOR_ERROR_MSG "=,;.[ \\t\\r\\n\\013\\014"
9798

9899
#define APPLY_TRANS_SID (PS(use_trans_sid) && !PS(use_only_cookies))
99100

@@ -705,7 +706,12 @@ static PHP_INI_MH(OnUpdateName) /* {{{ */
705706
SESSION_CHECK_OUTPUT_STATE;
706707

707708
/* Numeric session.name won't work at all */
708-
if ((!ZSTR_LEN(new_value) || is_numeric_string(ZSTR_VAL(new_value), ZSTR_LEN(new_value), NULL, NULL, 0))) {
709+
if (
710+
ZSTR_LEN(new_value) == 0
711+
|| zend_str_has_nul_byte(new_value)
712+
|| is_numeric_str_function(new_value, NULL, NULL)
713+
|| strpbrk(ZSTR_VAL(new_value), SESSION_FORBIDDEN_CHARS) != NULL
714+
) {
709715
int err_type;
710716

711717
if (stage == ZEND_INI_STAGE_RUNTIME || stage == ZEND_INI_STAGE_ACTIVATE || stage == ZEND_INI_STAGE_STARTUP) {
@@ -716,7 +722,7 @@ static PHP_INI_MH(OnUpdateName) /* {{{ */
716722

717723
/* Do not output error when restoring ini options. */
718724
if (stage != ZEND_INI_STAGE_DEACTIVATE) {
719-
php_error_docref(NULL, err_type, "session.name \"%s\" cannot be numeric or empty", ZSTR_VAL(new_value));
725+
php_error_docref(NULL, err_type, "session.name \"%s\" must not be numeric, empty, contain null bytes or any of the following characters \"" SESSION_FORBIDDEN_CHARS_FOR_ERROR_MSG "\"", ZSTR_VAL(new_value));
720726
}
721727
return FAILURE;
722728
}
@@ -1430,11 +1436,7 @@ static zend_result php_session_send_cookie(void) /* {{{ */
14301436
return FAILURE;
14311437
}
14321438

1433-
/* Prevent broken Set-Cookie header, because the session_name might be user supplied */
1434-
if (strpbrk(PS(session_name), SESSION_FORBIDDEN_CHARS) != NULL) { /* man isspace for \013 and \014 */
1435-
php_error_docref(NULL, E_WARNING, "session.name cannot contain any of the following '=,;.[ \\t\\r\\n\\013\\014'");
1436-
return FAILURE;
1437-
}
1439+
ZEND_ASSERT(strpbrk(PS(session_name), SESSION_FORBIDDEN_CHARS) == NULL);
14381440

14391441
/* URL encode id because it might be user supplied */
14401442
e_id = php_url_encode(ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)));
@@ -1554,7 +1556,10 @@ PHPAPI zend_result php_session_reset_id(void) /* {{{ */
15541556
}
15551557

15561558
if (PS(use_cookies) && PS(send_cookie)) {
1557-
php_session_send_cookie();
1559+
zend_result cookies_sent = php_session_send_cookie();
1560+
if (UNEXPECTED(cookies_sent == FAILURE)) {
1561+
return FAILURE;
1562+
}
15581563
PS(send_cookie) = 0;
15591564
}
15601565

ext/session/tests/bug66481.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ var_dump(session_name("foo"));
1515
var_dump(session_name("bar"));
1616
?>
1717
--EXPECT--
18-
Warning: PHP Startup: session.name "" cannot be numeric or empty in Unknown on line 0
18+
Warning: PHP Startup: session.name "" must not be numeric, empty, contain null bytes or any of the following characters "=,;.[ \t\r\n\013\014" in Unknown on line 0
1919
string(9) "PHPSESSID"
2020
string(3) "foo"

ext/session/tests/gh17541.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
GH-17541 (ext/session NULL pointer dereferencement during ID reset)
3+
--EXTENSIONS--
4+
session
5+
--SKIPIF--
6+
<?php include('skipif.inc'); ?>
7+
--FILE--
8+
<?php
9+
function errorHandler($errorNumber, $errorMessage, $fileName, $lineNumber) {
10+
// Destroy session while emitting warning from the bogus session name in session_start
11+
session_destroy();
12+
}
13+
14+
set_error_handler('errorHandler');
15+
16+
ob_start();
17+
var_dump(session_name("\t"));
18+
var_dump(session_start());
19+
20+
?>
21+
--EXPECTF--
22+
Warning: session_destroy(): Trying to destroy uninitialized session in %s on line %d
23+
string(9) "PHPSESSID"
24+
bool(true)

ext/session/tests/session_name_variation1.phpt

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,18 @@ ob_end_flush();
3232
?>
3333
--EXPECTF--
3434
*** Testing session_name() : variation ***
35-
string(9) "PHPSESSID"
3635

37-
Warning: session_start(): session.name cannot contain any of the following '=,;.[ \t\r\n\013\014' in %s on line %d
36+
Warning: session_name(): session.name " " must not be numeric, empty, contain null bytes or any of the following characters "=,;.[ \t\r\n\013\014" in %s on line %d
37+
string(9) "PHPSESSID"
3838
bool(true)
39-
string(1) " "
39+
string(9) "PHPSESSID"
4040
bool(true)
41-
string(1) " "
42-
43-
Warning: session_name(): session.name "" cannot be numeric or empty in %s on line %d
44-
string(1) " "
41+
string(9) "PHPSESSID"
4542

46-
Warning: session_start(): session.name cannot contain any of the following '=,;.[ \t\r\n\013\014' in %s on line %d
43+
Warning: session_name(): session.name "" must not be numeric, empty, contain null bytes or any of the following characters "=,;.[ \t\r\n\013\014" in %s on line %d
44+
string(9) "PHPSESSID"
4745
bool(true)
48-
string(1) " "
46+
string(9) "PHPSESSID"
4947
bool(true)
50-
string(1) " "
48+
string(9) "PHPSESSID"
5149
Done

0 commit comments

Comments
 (0)