commit 1aa17358ef7016661d86aee4154decfca60742e2 | |
Author: Stanislav Malyshev <stas@php.net> | |
Date: Sat Mar 2 23:42:53 2019 -0800 | |
Fix bug #77630 - safer rename() procedure | |
In order to rename safer, we do the following: | |
- set umask to 077 (unfortunately, not TS, so excluding ZTS) | |
- chown() first, to set proper group before allowing group access | |
- chmod() after, even if chown() fails | |
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c | |
index af890a9aa3..7fdf906e6f 100644 | |
--- a/main/streams/plain_wrapper.c | |
+++ b/main/streams/plain_wrapper.c | |
@@ -1168,34 +1168,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) && !defined(NETWARE) | |
+ /* 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) { | |
+ success = 1; | |
# if !defined(TSRM_WIN32) && !defined(NETWARE) | |
- 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; | |
- } | |
+ /* | |
+ * 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) && !defined(NETWARE) | |
+ umask(oldmask); | |
+# endif | |
+ return success; | |
} | |
# endif | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment