We keep track of free slots by organizing them in a linked list, with the
first word of every free slot being a pointer to the next one.
In order to make corruptions more difficult to exploit, we check the consistency
of these pointers before dereference by comparing them with a shadow. The shadow
is a copy of the pointer, stored at the end of the slot.
Before this change, an off-by-1 write is enough to produce a valid freelist
pointer. After this change, a bigger out of bound write is required for that.
The difficulty is increase further by mangling the shadow with a secret, and
byte-swapping it, which increases the minimal required out of bound write
length.
Closes GH-14054
These are either undefined or defined (to value 1):
- __DragonFly__
- __FreeBSD__
- HAS_MCAST_EXT
- HAVE_GETCWD
- HAVE_GETWD
- HAVE_GLIBC_ICONV
- HAVE_JIT
- HAVE_LCHOWN
- HAVE_NL_LANGINFO
- HAVE_RL_CALLBACK_READ_CHAR
- HAVE_RL_ON_NEW_LINE
- HAVE_SQL_EXTENDED_FETCH
- HAVE_UTIME
Follow up of GH-5526 (-Wundef)
This syncs few inconsistencies between the Windows and Autotools build
systems:
- HAVE_OPENSSL_EXT is now defined in the same style on both systems
(undefined - extension is not available, defined to 1 - extension is
available)
- HAVE_OPENSSL removed as it was only defined on Windows
* Replace WIN32 conditions with _WIN32 or PHP_WIN32
WIN32 is defined by the SDK and not defined all the time on Windows by
compilers or the environment. _WIN32 is defined as 1 when the
compilation target is 32-bit ARM, 64-bit ARM, x86, or x64. Otherwise,
undefined.
This syncs these usages one step further.
Upstream libgd has replaced WIN32 with _WIN32 via
c60d9fe577
PHP_WIN32 is added to ext/sockets/sockets.stub.php as done in other
*.stub.php files at this point.
* Use PHP_WIN32 in ext/random
* Use PHP_WIN32 in ext/sockets
* Use _WIN32 in xxhash.h as done upstream
See https://github.com/Cyan4973/xxHash/pull/931
* Update end comment with PHP_WIN32
Although the issue was demonstrated using Curl, the issue is purely in
the streams layer of PHP.
Full analysis is written in GH-11078 [1], but here is the brief version:
Here's what actually happens:
1) We're creating a FILE handle from a stream using the casting mechanism.
This will create a cookie-based FILE handle using funopen.
2) We're reading stream data using fread from the userspace stream. This will
temporarily set a buffer into a field _bf.base [2]. This buffer is now equal
to the upload buffer that Curl allocated and note that that buffer is owned
by Curl.
3) The fatal error occurs and we bail out from the fread function, notice how
the reset code is never executed and so the buffer will still point to
Curl's upload buffer instead of FILE's own buffer [3].
4) The resources are destroyed, this includes our opened stream and because the
FILE handle is cached, it gets destroyed as well.
In fact, the stream code calls through fclose on purpose in this case.
5) The fclose code frees the _bs.base buffer [4].
However, this is not the buffer that FILE owns but the one that Curl owns
because it isn't reset properly due to the bailout!
6) The objects are getting destroyed, and so the curl free logic is invoked.
When Curl tries to gracefully clean up, it tries to free the buffer.
But that buffer is actually already freed mistakingly by the C library!
This also explains why we can't reproduce it on Linux: this bizarre buffer
swapping only happens on macOS and BSD, not on Linux.
To solve this, we switch to an unbuffered mode for cookie-based FILEs.
This avoids any stateful problems related to buffers especially when the
bailout mechanism triggers. As streams have their own buffering
mechanism, I don't expect this to impact performance.
[1] https://github.com/php/php-src/issues/11078#issuecomment-2155616843
[2] 5e566be7a7/stdio/FreeBSD/fread.c (L102-L103)
[3] 5e566be7a7/stdio/FreeBSD/fread.c (L117)
[4] 5e566be7a7/stdio/FreeBSD/fclose.c (L66-L67)
Closes GH-14524.
GCC doesn't pessimize the error cases correctly:
https://godbolt.org/z/Pa6xsKMWc
This speeds up the happy case and in this case the code size is also
smaller, so it's a double-win.
This fixes this warning using ZEND_FALLTHROUGH:
```
php-src/sapi/litespeed/lsapi_main.c: In function ‘parse_opt’:
php-src/sapi/litespeed/lsapi_main.c:1196:16: warning: this statement may fall through [-Wimplicit-fallthrough=]
1196 | if ( *((*(p-1))+2) == 's' )
| ^
```
* Remove tautologically false condition in php_cli.c
* Make the CLI mode available via the SAPI globals
When hooking into RINIT it is currently pretty much impossible to determine
whether a file will actually be executed or if it just will be linted,
highlighted, or comments stripped: The startup is identical for all of them and
the chosen mode is not currently exposed to other extensions.
The `SG(server_context)` is currently entirely unused for the `cli` SAPI. It
appears to be appropriate to store the mode as a SAPI-specific information
inside of it.
This fixes few more -Wundef warnings in ext/fileinfo. The
PHP_FILEINFO_UNCOMPRESS seems to be present to be defined at some point
but is currently unused in all build systems. Leaving this intact for
now.
Follow up of GH-5526 (-Wundef)
The PG_VERSION_NUM is not available in intended public PostgreSQL
headers unless the pg_config.h is included or the PostgreSQL server
development headers are installed separately. This instead resorts to
checking for the PGVerbosity enum value. The PQERRORS_SQLSTATE was added
to PostgreSQL 12.0. At the time of writing, on Windows, PostgreSQL is at 11.4 so
it is not defined there yet.
These are either undefined or defined to value 1:
- ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE
- ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER
- ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PROTO
- ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PTR
Follow up of GH-5526 (-Wundef)
This moves the new method from magically being added to the PDO class from the driver to just be available on the dedicated subclass.
Drive-by fixes to NEWS and UPGRADING
This syncs the HAVE_GRP_H definition on Windows (manually defined) and
Autotools (checked with AC_CHECK_HEADERS):
HAVE_GRP_H is is either undefined or defined to value 1.
This is a sync of the https://github.com/php/php-src/pull/6252 after few
years:
- ext/date: pending recheck in GH-14187
- ext/hash: warning happens only on 32-bit build in
ext/hash/sha3/generic32lc/KeccakP-1600-inplace32BI.c
- ext/opcache: IR JIT doesn't seem to have this issue
- ext/pcre remains disabled due to pcre2lib/sljit/sljitNativeARM_64.c
(should be rechecked and fixed upstream)