summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2019-03-04 09:18:22 -0800
committerChristoph M. Becker <cmbecker69@gmx.de>2019-03-04 19:39:57 +0100
commitb0a5e5835af99b3d13288f51c0f4595145462ecd (patch)
treebd59fa9a23db0338af30fa9db7f4d0103c147af9
parent4e1b2bcc591c46c539e440b232f488265ad41065 (diff)
downloadphp-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--NEWS2
-rw-r--r--main/streams/plain_wrapper.c53
2 files changed, 37 insertions, 18 deletions
diff --git a/NEWS b/NEWS
index 96212c2370..6beb52ffe1 100644
--- a/NEWS
+++ b/NEWS
@@ -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