-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ext/session: Fix cache_expire ini overflow/underflow. #16445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: PHP-8.2
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -710,6 +710,23 @@ static PHP_INI_MH(OnUpdateCookieLifetime) /* {{{ */ | |
} | ||
/* }}} */ | ||
|
||
static PHP_INI_MH(OnUpdateCacheExpire) | ||
{ | ||
SESSION_CHECK_ACTIVE_STATE; | ||
SESSION_CHECK_OUTPUT_STATE; | ||
|
||
#ifdef ZEND_ENABLE_ZVAL_LONG64 | ||
const zend_long maxexpire = ((ZEND_LONG_MAX - INT_MAX) / 60) - 1; | ||
#else | ||
const zend_long maxexpire = ((ZEND_LONG_MAX / 2) / 60) - 1; | ||
#endif | ||
zend_long v = (zend_long)atol(ZSTR_VAL(new_value)); | ||
if (v < 0 || v > maxexpire) { | ||
return SUCCESS; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Surely this should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In fact I applied the same "policy" as for cookie_lifetime as to not disturb things for stable branches but I can return FAILURE sure. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this strategy makes sense. However, the approach appears to be insufficient. For 32bit architectures we have It seems to me that we need to do the overflow check when we're actually calculating the time (maybe instead of failing, just clamping the value). Rejecting very large values in the INI modifcation handler makes sense, but doesn't solve all issues; not even for 64bit architectures when running this code in say 15 years. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alright thx, I ll get back to it in couple of hours. |
||
return OnUpdateLongGEZero(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); | ||
} | ||
|
||
|
||
static PHP_INI_MH(OnUpdateSessionLong) /* {{{ */ | ||
{ | ||
|
@@ -818,7 +835,7 @@ PHP_INI_BEGIN() | |
STD_PHP_INI_BOOLEAN("session.use_strict_mode", "0", PHP_INI_ALL, OnUpdateSessionBool, use_strict_mode, php_ps_globals, ps_globals) | ||
STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateSessionString, extern_referer_chk, php_ps_globals, ps_globals) | ||
STD_PHP_INI_ENTRY("session.cache_limiter", "nocache", PHP_INI_ALL, OnUpdateSessionString, cache_limiter, php_ps_globals, ps_globals) | ||
STD_PHP_INI_ENTRY("session.cache_expire", "180", PHP_INI_ALL, OnUpdateSessionLong, cache_expire, php_ps_globals, ps_globals) | ||
STD_PHP_INI_ENTRY("session.cache_expire", "180", PHP_INI_ALL, OnUpdateCacheExpire, cache_expire, php_ps_globals, ps_globals) | ||
STD_PHP_INI_BOOLEAN("session.use_trans_sid", "0", PHP_INI_ALL, OnUpdateSessionBool, use_trans_sid, php_ps_globals, ps_globals) | ||
PHP_INI_ENTRY("session.sid_length", "32", PHP_INI_ALL, OnUpdateSidLength) | ||
PHP_INI_ENTRY("session.sid_bits_per_character", "4", PHP_INI_ALL, OnUpdateSidBits) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
--TEST-- | ||
session_cache_expire() overflow | ||
--EXTENSIONS-- | ||
session | ||
--SKIPIF-- | ||
<?php include('skipif.inc'); ?> | ||
--FILE-- | ||
<?php | ||
|
||
ob_start(); | ||
|
||
echo "*** Testing session_cache_expire() : overflow test ***\n"; | ||
|
||
session_cache_limiter("public"); | ||
var_dump(session_cache_expire((int)(PHP_INT_MAX/60))); | ||
session_start(); | ||
var_dump(session_cache_expire() * 60); | ||
|
||
echo "Done"; | ||
ob_end_flush(); | ||
?> | ||
--EXPECTF-- | ||
*** Testing session_cache_expire() : overflow test *** | ||
int(180) | ||
int(%s) | ||
Done | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that this is highly platform dependent, since the C standard makes no claim about
time_t
other than that it is an arithmetic type (could even be float/double). Current POSIX states "time_t shall be an integer type with a width of at least 64 bits". Now, that it not true for our x86 Windows builds (it's 32bit wide there); I don't know about other systems.To handle this cleanly, we should probably determine something like
TIME_MIN
andTIME_MAX
during configuration (and deal one way or another with non integraltime_t
implementations).Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concretally, even QNX does not implement time_t as float/double.