Commit graph

212 commits

Author SHA1 Message Date
Niels Dossche
504056888c
Fix GH-17938: UAF with zend_test opline observer and magic_quotes_gpc=1 (#17958) 2025-03-03 08:20:48 +01:00
Niels Dossche
99a14b805e
Fix GH-16013 and bug #80857: Big endian issues
The FFI call return values follow widening rules.
We must widen to `ffi_arg` in the case we're handling a return value for types shorter than the machine width.
From http://www.chiark.greenend.org.uk/doc/libffi-dev/html/The-Closure-API.html:
> In most cases, ret points to an object of exactly the size of the type specified when cif was constructed.
> However, integral types narrower than the system register size are widened.
> In these cases your program may assume that ret points to an ffi_arg object.

If we don't do this, we get wrong values when reading the return values.

Closes GH-17255.

Co-authored-by: Dmitry Stogov <dmitry@zend.com>
2024-12-25 21:33:14 +01:00
Niels Dossche
d9fada4a71
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-16908: _ZendTestMagicCallForward does not handle references well
2024-11-25 19:38:50 +01:00
Niels Dossche
99f5653ebb
Fix GH-16908: _ZendTestMagicCallForward does not handle references well
This testing code was never meant to be used this way, but fixing this
will at least stop fuzzers from complaining about this, so might still
be worthwhile.

Closes GH-16919.
2024-11-25 19:38:33 +01:00
Niels Dossche
16cda10650
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-16628: FPM logs are getting corrupted with this log statement
  Fix GH-16601: Memory leak in Reflection constructors
2024-11-02 19:37:28 +01:00
Niels Dossche
e643129bbb
Fix GH-16628: FPM logs are getting corrupted with this log statement
zlog_buf_prefix() can return a larger length than what actually was
written due to its use of snprintf(). The code in
zlog_stream_prefix_ex() does not take this into account, other callers
do. What ends up happening then is that stream->length is set to the
length as if snprintf() was able to write all bytes, causing
stream->length to become larger than stream->buf.size, causing a
segfault.

In case the buffer was too small we try with a larger buffer up to a
limit of zlog_limit. This makes sure that the stream length will remain
bounded by the buffer size.

This also adds assertions to make the programmer intent clear and catch
this more easily in debug builds.

Closes GH-16680.
2024-11-02 19:36:20 +01:00
Christoph M. Becker
713c71adbd
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-16266: _ZendTestClass::test() segfaults on named parameter
2024-10-21 19:44:34 +02:00
Christoph M. Becker
b73bcaa47c
Fix GH-16266: _ZendTestClass::test() segfaults on named parameter
We need to assign the proper number of arguments.

Closes GH-16271.
2024-10-21 19:43:33 +02:00
Niels Dossche
0338008852
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fixed GH-16233: Observer segfault when calling user function in internal function via trampoline
2024-10-07 17:17:27 +02:00
Niels Dossche
e715dd0afb
Fixed GH-16233: Observer segfault when calling user function in internal function via trampoline
In the test, I have an internal `__call` function for `_ZendTestMagicCallForward` that calls the global function with name `$name` via `call_user_function`.
Note that observer writes the pointer to the previously observed frame in the last temporary of the new call frame (`*prev_observed_frame`).

The following happens:
First, we call `$test->callee`, this will be handled via a trampoline with T=2 for the two arguments. The call frame is allocated at this point. This call frame is not observed because it has `ZEND_ACC_CALL_VIA_TRAMPOLINE` set. Next we use `ZEND_CALL_TRAMPOLINE` to call the trampoline, this reuses the stack frame allocated earlier with T=2, but this time it is observed. The pointer to the previous frame is written outside of the call frame because `T` is too small (should be 3). We are now in the internal function `_ZendTestMagicCallForward::__call` where we call the global function `callee`. This will push a new call frame which will overlap `*prev_observed_frame`. This value gets overwritten by `zend_init_func_execute_data` when `EX(opline)` is set because `*prev_observed_frame` overlaps with `EX(opline)`. From now on, `*prev_observed_frame` is corrupted. When `zend_observer_fcall_end` is called this will result in reading wrong value `*prev_observed_frame` into `current_observed_frame`. This causes issues in `zend_observer_fcall_end_all` leading to the segfault we observe.

Despite function with `ZEND_ACC_CALL_VIA_TRAMPOLINE` not being observed, the reuse of call frames makes problems when `T` is not large enough.
To fix this, we make sure to add 1 to `T` if `ZEND_OBSERVER_ENABLED` is true.

Closes GH-16252.
2024-10-07 17:16:43 +02:00
Arnaud Le Blanc
bc57c77fa2
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  [ci skip] NEWS for GH-14626
  Fix is_zend_ptr() for huge blocks (#14626)
2024-06-25 15:15:46 +02:00
Arnaud Le Blanc
1ff277dee2
Fix is_zend_ptr() for huge blocks (#14626)
is_zend_ptr() expected zend_mm_heap.huge_list to be circular, but it's in fact NULL-terminated. It could crash when at least one huge block exists and the ptr did not belong to any block.
2024-06-25 15:14:00 +02:00
Niels Dossche
ccdd1c4e67
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-11078: PHP Fatal error triggers pointer being freed was not allocated and malloc: double free for ptr errors
2024-06-10 19:39:25 +02:00
Niels Dossche
bc558bf7a3
Fix GH-11078: PHP Fatal error triggers pointer being freed was not allocated and malloc: double free for ptr errors
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.
2024-06-10 19:38:21 +02:00
Niels Dossche
0e98a05a3d
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-14215: Cannot use FFI::load on CRLF header file with apache2handler
2024-05-14 19:52:19 +02:00
Niels Dossche
ebd1a36670
Fix GH-14215: Cannot use FFI::load on CRLF header file with apache2handler
Some modules may reset _fmode, which causes mangling of line endings.
Always be explicit like we do in other places where the native open call
is used.

Closes GH-14218.
2024-05-14 19:49:22 +02:00
David Carlier
c24f621f57 Merge branch 'PHP-8.2' into PHP-8.3 2024-03-14 18:59:44 +00:00
David Carlier
db1f7b1286 zend_test fix copy_file_range test for linux 32 bits
close GH-13708
2024-03-14 18:59:26 +00:00
David Carlier
bbb6ffa545 Merge branch 'PHP-8.2' into PHP-8.3 2024-03-13 19:35:36 +00:00
David Carlier
334419e157 zend test fix copy_file_range for musl.
normally should no longer need off64_t with glibc anyway.
2024-03-13 19:35:23 +00:00
Niels Dossche
f6268b87c7 Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Silence deprecations in zend-test
2023-12-06 23:49:25 +01:00
Niels Dossche
de3c5c0bc8 Silence deprecations in zend-test
Forgot it here...
2023-12-06 23:49:08 +01:00
Ilija Tovilo
b7a468cd06
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix leak of call->extra_named_params on internal __call
2023-12-01 16:50:49 +01:00
Ilija Tovilo
f203edd3c5
Fix leak of call->extra_named_params on internal __call
Fixes GH-12835
Closes GH-12836
2023-12-01 16:49:16 +01:00
Bob Weinand
88537c55b5 Merge branch 'PHP-8.2' into PHP-8.3 2023-11-25 01:01:56 +01:00
Bob Weinand
50ccea31f2 Merge branch 'PHP-8.1' into PHP-8.2 2023-11-25 00:59:26 +01:00
Florian Engelhardt
8d2df86b06
Fix invalid opline in OOM handlers within ZEND_FUNC_GET_ARGS and ZEND_BIND_STATIC (#12768)
* fix segfault in `ZEND_BIND_STATIC`

In case a `ZEND_BIND_STATIC` is being executed, while the current chunk is full,
the `zend_array_dup()` call will trigger a OOM in ZendMM which will crash, as
the opline might be a dangling pointer.

* add missing test

* `assert()`ing seems easier than trying to make the compiler to not optimize

* moved from function call to INI setting, so we can use this in other places as well

* make `assert()` work no NDEBUG builds

* document magic number

* fix segfault in `ZEND_FUNC_GET_ARGS`

In case a `ZEND_FUNC_GET_ARGS` is being executed, while the current chunk is
full, the `zend_new_array()` call will trigger a OOM in ZendMM which will crash,
as the opline might be a dangling pointer.

---------

Co-authored-by: Florian Engelhardt <florian@engelhardt.tc>
2023-11-25 00:54:02 +01:00
Niels Dossche
e6fef2944b Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-12633: sqlite3_defensive.phpt fails with sqlite 3.44.0
  Fix GH-12628: The gh11374 test fails on Alpinelinux
2023-11-10 00:12:47 +01:00
Niels Dossche
fbda6b50a3 Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Fix GH-12633: sqlite3_defensive.phpt fails with sqlite 3.44.0
  Fix GH-12628: The gh11374 test fails on Alpinelinux
2023-11-10 00:08:09 +01:00
Niels Dossche
78fba9cb80 Fix GH-12628: The gh11374 test fails on Alpinelinux
Closes GH-12636.
2023-11-10 00:01:22 +01:00
Máté Kocsis
98e8e277b5
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-12558 Escape \N in generated stubs
2023-10-31 10:09:22 +01:00
Máté Kocsis
d4e40dc0e1
Fix GH-12558 Escape \N in generated stubs (#12562) 2023-10-31 10:06:56 +01:00
Dmitry Stogov
25cb2a40d6 Fix possible NULL dereference (crash on Zend/tests/arginfo_zpp_mismatch.phpt) 2023-10-23 10:23:36 +03:00
George Peter Banyard
d7273c5963 Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Prevents double call to internal iterator rewind handler
  adds failing test case for #12060
2023-09-05 10:36:16 +01:00
George Peter Banyard
c672a06954 Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Prevents double call to internal iterator rewind handler
  adds failing test case for #12060
2023-09-05 10:27:33 +01:00
ju1ius
9658d9ada4 adds failing test case for #12060
Signed-off-by: George Peter Banyard <girgias@php.net>
2023-09-05 10:23:22 +01:00
Niels Dossche
0b9702c9ed Implement GH-11934: Allow to pass CData into struct and/or union fields
Co-authored-by: KapitanOczywisty <44417092+KapitanOczywisty@users.noreply.github.com>

Closes GH-11935.
2023-08-29 17:01:10 +02:00
Máté Kocsis
c934e24197 Fix GH-9967 Add support for generating custom function, class const, and property attributes in stubs 2023-08-26 21:35:31 +02:00
ju1ius
3e0e7e3f90
releases property attributes of internal classes (#11980)
* adds test case for internal class property attribute

* releases property attributes of internal classes
2023-08-24 16:07:00 +02:00
ju1ius
7f1c3bf09b
Adds support for DNF types in internal functions and properties (#11969)
Note that this does not add support for items generated by gen_stubs,
only for items registered dynamically via the Zend API.

Closes GH-10120
2023-08-19 00:11:06 +01:00
George Peter Banyard
65a02f482f
ext/zend_test: Move object handler test objects to their own file (#11852) 2023-08-02 18:52:55 +01:00
Ben Ramsey
3d5f239474
Merge branch 'PHP-8.2' 2023-07-31 20:15:51 -05:00
Ben Ramsey
7ecb284926
Merge branch 'PHP-8.1' into PHP-8.2 2023-07-31 20:06:37 -05:00
Ben Ramsey
ebbccb3dc6
Merge branch 'PHP-8.0' into PHP-8.1 2023-07-31 20:01:03 -05:00
Niels Dossche
62228a2568
Disable global state test on Windows
It looks like the config.w32 uses CHECK_HEADER_ADD_INCLUDE to add the include
path to libxml into the search path.
That doesn't happen in zend-test.
To add to the Windows trouble, libxml is statically linked in, ext/libxml can
only be built statically but ext/zend-test can be built both statically and
dynamically.
So the regression tests won't work in all possible configurations anyway on Windows.
All of this is no problem on Linux because it just uses dynamic linking
and pkg-config, without any magic.

Signed-off-by: Ben Ramsey <ramsey@php.net>
2023-07-31 19:55:10 -05:00
Derick Rethans
797bd9f384 Merge branch 'PHP-8.2' 2023-07-31 20:05:28 +01:00
Derick Rethans
47a347e8b0 Merge branch 'PHP-8.1' into PHP-8.2 2023-07-31 20:05:20 +01:00
Derick Rethans
93b43ac238 Fix broken merge 2023-07-31 20:05:12 +01:00
Derick Rethans
86afbe10e2 Merge branch 'PHP-8.2' 2023-07-31 19:57:02 +01:00
Derick Rethans
deddf4692a Merge branch 'PHP-8.1' into PHP-8.2 2023-07-31 19:54:44 +01:00