he phar_parse_zipfile function had use-after-free vulnerability because of mishandling of the actual_alias variable. ----- ext/phar/zip.c ----- int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, char **error) /* {{{ */ { ... mydata->alias = entry.is_persistent ? pestrndup(actual_alias, mydata->alias_len, 1) : actual_alias; if (entry.is_persistent) { efree(actual_alias); } zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), actual_alias, mydata->alias_len, mydata); ... --------------------------- `actual_alias` variable is allocated by estrndup function, which string is part of data of the zip file. The above code snippet `mydata->alias` is assigned by `pestrndup(actual_alias, mydata->alias_len, 1)` if entry.is_persistent is true. Or `mydata->alias` is assigned by `actual_alias` variable. And if `entry.is_persistent` is true, `actual_alias` variable is freed by invoke efree function. `actual_alias` variable is used invoke of zend_hash_str_add_ptr function as 2nd argument. Problem is that `actual_alias` variable is freed if `entry.is_persistent` is true, the key of `phar_alias_map` will use freed memory. `entry.is_persistent` is true if `phar.cache_list` fields is defined in php.ini file. So if `phar.cache_list` is defined with target phar path so that `entry.is_persistent` is true, then it can be that `phar_alias_map` hash key would use sensitive freed memory data such as heap addresses that addresses set via linked list after invoke the efree function. Possibly affected versions: php 7.2.32, php 7.3.20, php 7.4.8 Upstream Reference: https://bugs.php.net/bug.php?id=79797 https://www.php.net/ChangeLog-7.php
Created php tracking bugs for this issue: Affects: fedora-all [bug 1868110]
Flaw summary: The flaw is in phar_parse_zipfile() of ext/phar/zip.c. When processing a PHP archive file (phar), if a persistent entry is used as defined in php.ini, then memory pointed to by the actual_alias pointer is freed. Directly after the free, the actual_alias pointer is passed to zend_hash_str_add_ptr, where it is dereferenced. Prior to the function call, a copy of the memory pointed to by actual_alias is duplicated and assigned to the mydata->alias pointer. The patch simply uses the unfreed mydata->alias pointer as an argument to the zend_hash_add_str() call rather than the freed memory pointed to by actual_alias. To trigger this flaw, an attacker needs to place a specially crafted file on the server's filesystem and then load it with PHP. The attacker also needs a setting to be present in PHP's configuration file. Due to this, the attack complexity is high as an attacker would need to find other flaws or already have admin access to the server machine to do this.
in php 5.4 (RHEL7), it's in ext/phar/zip.c ~ line 687: mydata->alias = entry.is_persistent ? pestrndup(actual_alias, mydata->alias_len, 1) : actual_alias; if (entry.is_persistent) { efree(actual_alias); } zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL); In this ver, the function is called zend_hash_add instead of zend_hash_str_add.
This issue has been addressed in the following products: Red Hat Software Collections for Red Hat Enterprise Linux 7 Red Hat Software Collections for Red Hat Enterprise Linux 7.7 EUS Via RHSA-2021:2992 https://access.redhat.com/errata/RHSA-2021:2992
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s): https://access.redhat.com/security/cve/cve-2020-7068
This issue has been addressed in the following products: Red Hat Enterprise Linux 8 Via RHSA-2021:4213 https://access.redhat.com/errata/RHSA-2021:4213