[php-src] Issue #10010: Three out-of-bound Bugs in PHP Zend
| From: | kitaharazy | Date: | Mon, 28 Nov 2022 02:13:53 +0000 |
| Subject: | [php-src] Issue #10010: Three out-of-bound Bugs in PHP Zend | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-242957@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/10010
Author: kitaharazy
### Description
- [Zend/zend_API.c:2811](https://github.com/php/php-src/blob/master/Zend/zend_API.c#L2811)
```c
zend_function function, *reg_function;
...
reg_function = malloc(sizeof(zend_internal_function));
```
An implicit Type-Conversion will happen, from ``
zend_internal_function` to
`zend_function`, however the size of
`zend_internal_function` is **bigger than** the size of
`zend_function`` which could cause potential out-of-bound access in the
following codes.
- [Zend/zend_API.c:2859](https://github.com/php/php-src/blob/master/Zend/zend_API.c#L2859)
```c
zend_arg_info *new_arg_info;
/* Treat return type as an extra argument */
num_args++;
new_arg_info = malloc(sizeof(zend_arg_info) * num_args);
memcpy(new_arg_info, arg_info, sizeof(zend_arg_info) * num_args);
reg_function->common.arg_info = new_arg_info + 1;
// access
if (!ZEND_ARG_TYPE_IS_TENTATIVE(&proto->common.arg_info[-1])) {
return INHERITANCE_ERROR;
}
```
Note that in ``reg_function->common.arg_info = new_arg_info + 1;` the
`new_arg_info``'s pointer arithmetic will generate an out-of-bound pointer.
-
[Zend/zend_operators.c:2892](https://github.com/php/php-src/blob/master/Zend/zend_operators.c#L2892)
```c
zend_string *res = zend_string_alloc(length, persistent);
memcpy(ZSTR_VAL(res), ZSTR_VAL(str), p - (unsigned char*) ZSTR_VAL(str));
unsigned char *q = p + (ZSTR_VAL(res) - ZSTR_VAL(str));
// |__________|
// ^ ^
// str p
// |__________|
// ^ ^
// res q
```
The pointer ``p` originally points to somewhere inside the
`str->val``'s chunk.
After a new ``res` is created by `malloc()`, then
`memcpy()` copy the contents from
[`str->val`,`p`] to
`res->val``
In order to find the pointer ``p`'s position in
`res->val`'s chunk, it will execute `p +
(ZSTR_VAL(res) - ZSTR_VAL(str));``
However, a better way of this should be: ``ZSTR_VAL(res) + (p - ZSTR_VAL(str))``
### PHP Version
Newest
### Operating System
Ubuntu 20.04