Skip to content

Commit f8a8f7a

Browse files
Girgiascharmitro
authored andcommitted
ext/session: Fix phpGH-17541 (ext/session NULL pointer dereferencement during ID reset)
Closes phpGH-17541 Closes phpGH-17546
1 parent 1975c6a commit f8a8f7a

File tree

5 files changed

+60
-18
lines changed

5 files changed

+60
-18
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ PHP NEWS
5050

5151
- Session:
5252
. Fix type confusion with session SID constant. (nielsdos)
53+
. Fixed bug GH-17541 (ext/session NULL pointer dereferencement during
54+
ID reset). (Girgias)
5355

5456
- SimpleXML:
5557
. Fixed bug GH-17409 (Assertion failure Zend/zend_hash.c:1730). (nielsdos)

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

@@ -682,7 +683,12 @@ static PHP_INI_MH(OnUpdateName) /* {{{ */
682683
SESSION_CHECK_OUTPUT_STATE;
683684

684685
/* Numeric session.name won't work at all */
685-
if ((!ZSTR_LEN(new_value) || is_numeric_string(ZSTR_VAL(new_value), ZSTR_LEN(new_value), NULL, NULL, 0))) {
686+
if (
687+
ZSTR_LEN(new_value) == 0
688+
|| zend_str_has_nul_byte(new_value)
689+
|| is_numeric_str_function(new_value, NULL, NULL)
690+
|| strpbrk(ZSTR_VAL(new_value), SESSION_FORBIDDEN_CHARS) != NULL
691+
) {
686692
int err_type;
687693

688694
if (stage == ZEND_INI_STAGE_RUNTIME || stage == ZEND_INI_STAGE_ACTIVATE || stage == ZEND_INI_STAGE_STARTUP) {
@@ -693,7 +699,7 @@ static PHP_INI_MH(OnUpdateName) /* {{{ */
693699

694700
/* Do not output error when restoring ini options. */
695701
if (stage != ZEND_INI_STAGE_DEACTIVATE) {
696-
php_error_docref(NULL, err_type, "session.name \"%s\" cannot be numeric or empty", ZSTR_VAL(new_value));
702+
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));
697703
}
698704
return FAILURE;
699705
}
@@ -1421,11 +1427,7 @@ static zend_result php_session_send_cookie(void) /* {{{ */
14211427
return FAILURE;
14221428
}
14231429

1424-
/* Prevent broken Set-Cookie header, because the session_name might be user supplied */
1425-
if (strpbrk(PS(session_name), SESSION_FORBIDDEN_CHARS) != NULL) { /* man isspace for \013 and \014 */
1426-
php_error_docref(NULL, E_WARNING, "session.name cannot contain any of the following '=,;.[ \\t\\r\\n\\013\\014'");
1427-
return FAILURE;
1428-
}
1430+
ZEND_ASSERT(strpbrk(PS(session_name), SESSION_FORBIDDEN_CHARS) == NULL);
14291431

14301432
/* URL encode id because it might be user supplied */
14311433
e_id = php_url_encode(ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)));
@@ -1545,7 +1547,10 @@ PHPAPI zend_result php_session_reset_id(void) /* {{{ */
15451547
}
15461548

15471549
if (PS(use_cookies) && PS(send_cookie)) {
1548-
php_session_send_cookie();
1550+
zend_result cookies_sent = php_session_send_cookie();
1551+
if (UNEXPECTED(cookies_sent == FAILURE)) {
1552+
return FAILURE;
1553+
}
15491554
PS(send_cookie) = 0;
15501555
}
15511556

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: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ ob_start();
1515

1616
echo "*** Testing session_name() : variation ***\n";
1717

18+
var_dump(session_name("\0"));
19+
var_dump(session_start());
20+
var_dump(session_name());
21+
var_dump(session_destroy());
22+
var_dump(session_name());
23+
1824
var_dump(session_name("\t"));
1925
var_dump(session_start());
2026
var_dump(session_name());
@@ -32,20 +38,25 @@ ob_end_flush();
3238
?>
3339
--EXPECTF--
3440
*** Testing session_name() : variation ***
35-
string(9) "PHPSESSID"
3641

37-
Warning: session_start(): session.name cannot contain any of the following '=,;.[ \t\r\n\013\014' in %s on line %d
42+
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
43+
string(9) "PHPSESSID"
3844
bool(true)
39-
string(1) " "
45+
string(9) "PHPSESSID"
4046
bool(true)
41-
string(1) " "
47+
string(9) "PHPSESSID"
4248

43-
Warning: session_name(): session.name "" cannot be numeric or empty in %s on line %d
44-
string(1) " "
49+
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
50+
string(9) "PHPSESSID"
51+
bool(true)
52+
string(9) "PHPSESSID"
53+
bool(true)
54+
string(9) "PHPSESSID"
4555

46-
Warning: session_start(): session.name cannot contain any of the following '=,;.[ \t\r\n\013\014' in %s on line %d
56+
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
57+
string(9) "PHPSESSID"
4758
bool(true)
48-
string(1) " "
59+
string(9) "PHPSESSID"
4960
bool(true)
50-
string(1) " "
61+
string(9) "PHPSESSID"
5162
Done

0 commit comments

Comments
 (0)