Skip to content

Integer overflow in curl_multi_select #15547

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

Closed
Lerchensporn opened this issue Aug 22, 2024 · 7 comments
Closed

Integer overflow in curl_multi_select #15547

Lerchensporn opened this issue Aug 22, 2024 · 7 comments

Comments

@Lerchensporn
Copy link

Lerchensporn commented Aug 22, 2024

Description

In this code line, the timeout is casted to unsigned long:

error = curl_multi_wait(mh->multi, NULL, 0, (unsigned long) (timeout * 1000.0), &numfds);

But the function expects a signed int, see https://curl.se/libcurl/c/curl_multi_wait.html

In consequence, passing a large timeout to the PHP function curl_multi_select causes undefined behavior according to the C standard. Usually it would it cause 100% CPU usage.

PHP Version

PHP 8.3.10

Operating System

No response

@cmb69
Copy link
Member

cmb69 commented Aug 22, 2024

Thanks for reporting!

Indeed, that cast is wrong, but most important seems that we should check that timeout is in the permissible range before even calling the function, and throw a ValueError otherwise (not sure if throwing is okay for stable branches, though).

@devnexen devnexen self-assigned this Aug 22, 2024
devnexen added a commit to devnexen/php-src that referenced this issue Aug 22, 2024
confusion might come from the previous argument type.
PHP expects ms so we check it fits integer boundaries before the cast.
raising a warning at least for stable branches.
@Lerchensporn
Copy link
Author

A comment on the patch.

When the function returns -1, it would be good to always set some Curl error. Otherwise the caller cannot know to which Curl function call the error fetched with curl_multi_errno refers.

Specifically, we can use SAVE_CURLM_ERROR(mh, CURLM_BAD_FUNCTION_ARGUMENT) because this error code is also set in Curl when the timeout is negative: https://github.com/curl/curl/blob/df15d9ff26170125cbaa4d9283f733a2bb35fa20/lib/multi.c#L1288

As a code simplification, we could also assert timeout >= 0.0 because negative values are disallowed anyway. (Curl should better use the unsigned int type here.)

@devnexen
Copy link
Member

sure, fair point for setting curl error.

@novotnicek
Copy link

we have issue with <b>Warning</b>: curl_multi_select(): timeout must be between 0 and 2147484 in <b>/apps/symfony-app/vendor/symfony/http-client/Response/CurlResponse.php</b> on line <b>342</b><br /> in response body.

but if display_errors = Off, then we expect this message in logs, nope in response body.

i don't know if it's depended, but in php-8.4.0RC2 is used zend_argument_value_error() instead of php_error_docref().

@devnexen
Copy link
Member

It s documented on the UPGRADING notes.

@thezagday
Copy link

thezagday commented Oct 28, 2024

@novotnicek Maybe you (or somebody) can explain what the main reason of error curl_multi_select(): timeout must be between 0 and 2147484 ? I understand that timeout has negative value but why ? And how can I fix it ? My PHP version 8.2.24 and recently I've upgraded docker base image php:8.2-fpm-alpine17 up to php:8.2-fpm-alpine20 and now I have this warning.

@novotnicek
Copy link

@thezagday You problem is not alpine17 or alpine20, but PHP patch version (third number in semver). I don't have problem with this warning. I see like problem, this warning ended in response body instead of log files, when my setting is display_errors = Off.

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

Successfully merging a pull request may close this issue.

5 participants