File tree Expand file tree Collapse file tree 5 files changed +55
-2
lines changed Expand file tree Collapse file tree 5 files changed +55
-2
lines changed Original file line number Diff line number Diff line change @@ -49,6 +49,9 @@ PHP NEWS
49
49
- Reflection:
50
50
. Fixed bug GH-16601 (Memory leak in Reflection constructors). (nielsdos)
51
51
52
+ - Session:
53
+ . Fixed bug GH-16590 (UAF in session_encode()). (nielsdos)
54
+
52
55
- SPL:
53
56
. Fixed bug GH-16588 (UAF in Observer->serialize). (nielsdos)
54
57
. Fix GH-16477 (Segmentation fault when calling __debugInfo() after failed
Original file line number Diff line number Diff line change @@ -391,6 +391,8 @@ PHP 8.4 INTERNALS UPGRADE NOTES
391
391
needing to create a zend_string.
392
392
- The ext/session/php_session.h doesn't transitively include the
393
393
ext/hash/php_hash.h header anymore.
394
+ - It is no longer allowed to return out of the PS_ENCODE_LOOP macro.
395
+ Instead, you should break out of the loop instead.
394
396
395
397
i. ext/xml
396
398
- Made the expat compatibility wrapper XML_GetCurrentByteIndex return a long
Original file line number Diff line number Diff line change @@ -291,8 +291,13 @@ PHPAPI zend_result php_session_reset_id(void);
291
291
zend_ulong num_key; \
292
292
zval *struc;
293
293
294
+ /* Do not use a return statement in `code` because that may leak memory.
295
+ * Break out of the loop instead. */
294
296
#define PS_ENCODE_LOOP (code ) do { \
295
- HashTable *_ht = Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))); \
297
+ zval _zv; \
298
+ /* protect against user interference */ \
299
+ ZVAL_COPY (& _zv , Z_REFVAL (PS (http_session_vars ))); \
300
+ HashTable * _ht = Z_ARRVAL (_zv ); \
296
301
ZEND_HASH_FOREACH_KEY (_ht , num_key , key ) { \
297
302
if (key == NULL ) { \
298
303
php_error_docref (NULL , E_WARNING , \
@@ -303,6 +308,7 @@ PHPAPI zend_result php_session_reset_id(void);
303
308
code ; \
304
309
} \
305
310
} ZEND_HASH_FOREACH_END (); \
311
+ zval_ptr_dtor (& _zv ); \
306
312
} while (0 )
307
313
308
314
PHPAPI ZEND_EXTERN_MODULE_GLOBALS (ps )
Original file line number Diff line number Diff line change @@ -1056,6 +1056,7 @@ PS_SERIALIZER_ENCODE_FUNC(php) /* {{{ */
1056
1056
{
1057
1057
smart_str buf = {0 };
1058
1058
php_serialize_data_t var_hash ;
1059
+ bool fail = false;
1059
1060
PS_ENCODE_VARS ;
1060
1061
1061
1062
PHP_VAR_SERIALIZE_INIT (var_hash );
@@ -1065,12 +1066,17 @@ PS_SERIALIZER_ENCODE_FUNC(php) /* {{{ */
1065
1066
if (memchr (ZSTR_VAL (key ), PS_DELIMITER , ZSTR_LEN (key ))) {
1066
1067
PHP_VAR_SERIALIZE_DESTROY (var_hash );
1067
1068
smart_str_free (& buf );
1068
- return NULL ;
1069
+ fail = true;
1070
+ break ;
1069
1071
}
1070
1072
smart_str_appendc (& buf , PS_DELIMITER );
1071
1073
php_var_serialize (& buf , struc , & var_hash );
1072
1074
);
1073
1075
1076
+ if (fail ) {
1077
+ return NULL ;
1078
+ }
1079
+
1074
1080
smart_str_0 (& buf );
1075
1081
1076
1082
PHP_VAR_SERIALIZE_DESTROY (var_hash );
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ GH-16590 (UAF in session_encode())
3
+ --EXTENSIONS--
4
+ session
5
+ --SKIPIF--
6
+ <?php include ('skipif.inc ' ); ?>
7
+ --INI--
8
+ session.use_cookies=0
9
+ session.cache_limiter=
10
+ session.serialize_handler=php
11
+ session.save_handler=files
12
+ --FILE--
13
+ <?php
14
+
15
+ class C {
16
+ function __serialize () {
17
+ $ _SESSION = [];
18
+ return [];
19
+ }
20
+ }
21
+
22
+ session_start ();
23
+
24
+ $ _SESSION ['Lz ' ] = new C ;
25
+ for ($ i = 0 ; $ i < 2 ; $ i ++) {
26
+ $ _SESSION [$ i ] = $ i ;
27
+ }
28
+
29
+ var_dump (session_encode ());
30
+
31
+ ?>
32
+ --EXPECTF--
33
+ Warning: session_encode(): Skipping numeric key 0 in %s on line %d
34
+
35
+ Warning: session_encode(): Skipping numeric key 1 in %s on line %d
36
+ string(15) "Lz|O:1:"C":0:{}"
You can’t perform that action at this time.
0 commit comments