diff options
author | Stanislav Malyshev <stas@php.net> | 2019-03-04 09:18:22 -0800 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2019-03-04 19:39:57 +0100 |
commit | b0a5e5835af99b3d13288f51c0f4595145462ecd (patch) | |
tree | bd59fa9a23db0338af30fa9db7f4d0103c147af9 | |
parent | 4e1b2bcc591c46c539e440b232f488265ad41065 (diff) | |
download | php-git-b0a5e5835af99b3d13288f51c0f4595145462ecd.tar.gz |
Merge branch 'PHP-7.2' into PHP-7.3
* PHP-7.2:
Fix bug #77630 - safer rename() procedure
(cherry picked from commit 609195e991578fb368e3a4a5f79cb1c05514038a)
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | main/streams/plain_wrapper.c | 53 |
2 files changed, 37 insertions, 18 deletions
@@ -13,6 +13,8 @@ PHP NEWS property). (Nikita) . Fixed bug #77530 (PHP crashes when parsing `(2)::class`). (Ekin) . Fixed bug #77546 (iptcembed broken function). (gdegoulet) + . Fixed bug #77630 (rename() across the device may allow unwanted access + during processing). (Stas) - COM: . Fixed bug #77621 (Already defined constants are not properly reported). diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index ed52249637..785da8743b 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -1198,34 +1198,51 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f # ifdef EXDEV if (errno == EXDEV) { zend_stat_t sb; +# if !defined(ZTS) && !defined(TSRM_WIN32) + /* not sure what to do in ZTS case, umask is not thread-safe */ + int oldmask = umask(077); +# endif + int success = 0; if (php_copy_file(url_from, url_to) == SUCCESS) { if (VCWD_STAT(url_from, &sb) == 0) { -# ifndef TSRM_WIN32 - if (VCWD_CHMOD(url_to, sb.st_mode)) { - if (errno == EPERM) { - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); - VCWD_UNLINK(url_from); - return 1; - } + success = 1; +# if !defined(TSRM_WIN32) + /* + * Try to set user and permission info on the target. + * If we're not root, then some of these may fail. + * We try chown first, to set proper group info, relying + * on the system environment to have proper umask to not allow + * access to the file in the meantime. + */ + if (VCWD_CHOWN(url_to, sb.st_uid, sb.st_gid)) { php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); - return 0; + if (errno != EPERM) { + success = 0; + } } - if (VCWD_CHOWN(url_to, sb.st_uid, sb.st_gid)) { - if (errno == EPERM) { + + if (success) { + if (VCWD_CHMOD(url_to, sb.st_mode)) { php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); - VCWD_UNLINK(url_from); - return 1; + if (errno != EPERM) { + success = 0; + } } - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); - return 0; } # endif - VCWD_UNLINK(url_from); - return 1; + if (success) { + VCWD_UNLINK(url_from); + } + } else { + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); } + } else { + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); } - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); - return 0; +# if !defined(ZTS) && !defined(TSRM_WIN32) + umask(oldmask); +# endif + return success; } # endif #endif |