Skip to content

Conversation

@cmb69
Copy link
Member

@cmb69 cmb69 commented Feb 6, 2025

The fix for GH-16809[1] used a way too small timeout maximum on Windows. We correct this.

However, later on the timeout is applied to the current timestamp, so we would need to take that into account, but due to the elapsed time between the check and the actual network request, this could not be precise, and the resulting error message would be confusing, since after the developer would adjust the timeout to the reported maximum, the check would fail again, now reporting a lower maximum timeout.

Thus we silently cap the value in php_network_set_limit_time() to avoid undefined behavior, and are not picky about the usec value (we just assume a second more), since there is a bigger issue, namely that we hit the Y2038 problem on Windows.

[1] #16810


Note that ext/standard/tests/http/gh16810.phpt fails for me on Windows with UBSan enabled for the PHP_INT_MIN case (with or without this patch); I wonder if this actually happens on POSIX systems, too. If so, we would also need to check for a minimum timeout on all platforms; otherwise only on Windows. And frankly, I don't quite understand why we would allow negative timeout values at all.

I'll have a look at how the Y2038 problem on Windows could be resolved. It's not super urgent (I don't assume that anybody uses very large timeouts anyway), but since it currently affects even 64bit platforms, that needs to be improved.

The fix for phpGH-16809[1] used a way too small timeout maximum on
Windows.  We correct this.

However, later on the timeout is applied to the current timestamp, so
we would need to take that into account, but due to the elapsed time
between the check and the actual network request, this could not be
precise, and the resulting error message would be confusing, since
after the developer would adjust the timeout to the reported maximum,
the check would fail again, now reporting a lower maximum timeout.

Thus we silently cap the value in `php_network_set_limit_time()` to
avoid undefined behavior, and are not picky about the usec value (we
just assume a second more), since there is a bigger issue, namely that
we hit the Y2038 problem on Windows.

[1] <php#16810>
@cmb69 cmb69 linked an issue Feb 18, 2025 that may be closed by this pull request
@cmb69
Copy link
Member Author

cmb69 commented Feb 18, 2025

Well, let's ignore negative timeouts (and possible overflow) here; the current bug is way more important to fix.

@cmb69 cmb69 marked this pull request as ready for review February 18, 2025 17:36
@cmb69 cmb69 requested a review from bukka as a code owner February 18, 2025 17:36
@ndossche
Copy link
Member

@bukka @cmb69 I believe this should get merged soonish or resolved at least, otherwise we'll have this regression in 8.3 forever when we enter security-only support.

Copy link
Member

@bukka bukka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it looks reasonable. But it needs rebase.

gettimeofday(limit_time, NULL);
# ifdef PHP_WIN32
/* cap timeout (we're not picky regarding usec) */
if (limit_time->tv_sec > (LONG_MAX - timeout->tv_sec) + 1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably remove that +1 just in case it gets called with tv_sec 0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Socket maximum timeout of 2147 seconds?

3 participants