mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Fix GH-14780: p(f)sockopen overflow on timeout argument.
close GH-14785
This commit is contained in:
parent
40551dd74b
commit
ba909d7c43
5 changed files with 63 additions and 7 deletions
1
NEWS
1
NEWS
|
@ -32,6 +32,7 @@ PHP NEWS
|
||||||
|
|
||||||
- Standard:
|
- Standard:
|
||||||
. Fix passing non-finite timeout values in stream functions. (nielsdos)
|
. Fix passing non-finite timeout values in stream functions. (nielsdos)
|
||||||
|
. Fixed GH-14780 p(f)sockopen timeout overflow. (David Carlier)
|
||||||
|
|
||||||
- Streams:
|
- Streams:
|
||||||
. Fixed bug GH-15028 (Memory leak in ext/phar/stream.c). (nielsdos)
|
. Fixed bug GH-15028 (Memory leak in ext/phar/stream.c). (nielsdos)
|
||||||
|
|
|
@ -60,6 +60,12 @@ PHPAPI ssize_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, cha
|
||||||
#define PHP_FILE_APPEND (1 << 3)
|
#define PHP_FILE_APPEND (1 << 3)
|
||||||
#define PHP_FILE_NO_DEFAULT_CONTEXT (1 << 4)
|
#define PHP_FILE_NO_DEFAULT_CONTEXT (1 << 4)
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define PHP_TIMEOUT_ULL_MAX ULLONG_MAX
|
||||||
|
#else
|
||||||
|
#define PHP_TIMEOUT_ULL_MAX UINT64_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum _php_meta_tags_token {
|
typedef enum _php_meta_tags_token {
|
||||||
TOK_EOF = 0,
|
TOK_EOF = 0,
|
||||||
TOK_OPENTAG,
|
TOK_OPENTAG,
|
||||||
|
|
|
@ -73,14 +73,27 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare the timeout value for use */
|
/* prepare the timeout value for use */
|
||||||
|
if (timeout != -1.0 && !(timeout >= 0.0 && timeout <= (double) PHP_TIMEOUT_ULL_MAX / 1000000.0)) {
|
||||||
|
if (port > 0) {
|
||||||
|
efree(hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hashkey) {
|
||||||
|
efree(hashkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
zend_argument_value_error(6, "must be -1 or between 0 and " ZEND_ULONG_FMT, (PHP_TIMEOUT_ULL_MAX / 1000000.0));
|
||||||
|
RETURN_THROWS();
|
||||||
|
} else {
|
||||||
#ifndef PHP_WIN32
|
#ifndef PHP_WIN32
|
||||||
conv = (time_t) (timeout * 1000000.0);
|
conv = (time_t) (timeout * 1000000.0);
|
||||||
tv.tv_sec = conv / 1000000;
|
tv.tv_sec = conv / 1000000;
|
||||||
#else
|
#else
|
||||||
conv = (long) (timeout * 1000000.0);
|
conv = (long) (timeout * 1000000.0);
|
||||||
tv.tv_sec = conv / 1000000;
|
tv.tv_sec = conv / 1000000;
|
||||||
#endif
|
#endif
|
||||||
tv.tv_usec = conv % 1000000;
|
tv.tv_usec = conv % 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
stream = php_stream_xport_create(hostname, hostname_len, REPORT_ERRORS,
|
stream = php_stream_xport_create(hostname, hostname_len, REPORT_ERRORS,
|
||||||
STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, hashkey, &tv, NULL, &errstr, &err);
|
STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, hashkey, &tv, NULL, &errstr, &err);
|
||||||
|
|
|
@ -33,13 +33,11 @@
|
||||||
#ifndef PHP_WIN32
|
#ifndef PHP_WIN32
|
||||||
#define php_select(m, r, w, e, t) select(m, r, w, e, t)
|
#define php_select(m, r, w, e, t) select(m, r, w, e, t)
|
||||||
typedef unsigned long long php_timeout_ull;
|
typedef unsigned long long php_timeout_ull;
|
||||||
#define PHP_TIMEOUT_ULL_MAX ULLONG_MAX
|
|
||||||
#else
|
#else
|
||||||
#include "win32/select.h"
|
#include "win32/select.h"
|
||||||
#include "win32/sockets.h"
|
#include "win32/sockets.h"
|
||||||
#include "win32/console.h"
|
#include "win32/console.h"
|
||||||
typedef unsigned __int64 php_timeout_ull;
|
typedef unsigned __int64 php_timeout_ull;
|
||||||
#define PHP_TIMEOUT_ULL_MAX UINT64_MAX
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GET_CTX_OPT(stream, wrapper, name, val) (PHP_STREAM_CONTEXT(stream) && NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), wrapper, name)))
|
#define GET_CTX_OPT(stream, wrapper, name, val) (PHP_STREAM_CONTEXT(stream) && NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), wrapper, name)))
|
||||||
|
|
38
ext/standard/tests/streams/gh14780.phpt
Normal file
38
ext/standard/tests/streams/gh14780.phpt
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
--TEST--
|
||||||
|
GH-14780: p(f)sockopen overflow on timeout.
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only");
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$code = null;
|
||||||
|
$err = null;
|
||||||
|
try {
|
||||||
|
pfsockopen('udp://127.0.0.1', '63844', $code, $err, (PHP_INT_MAX/100000)+1);
|
||||||
|
} catch (\ValueError $e) {
|
||||||
|
echo $e->getMessage() . PHP_EOL;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
pfsockopen('udp://127.0.0.1', '63844', $code, $err, (PHP_INT_MIN/100000)-1);
|
||||||
|
} catch (\ValueError $e) {
|
||||||
|
echo $e->getMessage() . PHP_EOL;
|
||||||
|
}
|
||||||
|
var_dump(pfsockopen('udp://127.0.0.1', '63844', $code, $err, -1));
|
||||||
|
try {
|
||||||
|
pfsockopen('udp://127.0.0.1', '63844', $code, $err, NAN);
|
||||||
|
} catch (\ValueError $e) {
|
||||||
|
echo $e->getMessage() . PHP_EOL;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
pfsockopen('udp://127.0.0.1', '63844', $code, $err, INF);
|
||||||
|
} catch (\ValueError $e) {
|
||||||
|
echo $e->getMessage();
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
pfsockopen(): Argument #6 must be -1 or between 0 and %s
|
||||||
|
pfsockopen(): Argument #6 must be -1 or between 0 and %s
|
||||||
|
resource(%d) of type (persistent stream)
|
||||||
|
pfsockopen(): Argument #6 must be -1 or between 0 and %s
|
||||||
|
pfsockopen(): Argument #6 must be -1 or between 0 and %s
|
Loading…
Add table
Add a link
Reference in a new issue