Skip to content

Instantly share code, notes, and snippets.

@smalyshev
Created March 3, 2019 07:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smalyshev/4198b4573b002884ff552cffccbf050a to your computer and use it in GitHub Desktop.
Save smalyshev/4198b4573b002884ff552cffccbf050a to your computer and use it in GitHub Desktop.
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