]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.1' into PHP-7.2
authorStanislav Malyshev <stas@php.net>
Mon, 4 Mar 2019 17:17:14 +0000 (09:17 -0800)
committerStanislav Malyshev <stas@php.net>
Mon, 4 Mar 2019 17:17:14 +0000 (09:17 -0800)
* PHP-7.1:
  Fix bug #77630 - safer rename() procedure

1  2 
main/streams/plain_wrapper.c

index 9b36d00ec8723ca6c24ef7face5f375b4ab975f0,7fdf906e6fad1015da6aaa8c46a78d223082d99c..d409fe99f06f2c10eda4d010823d9fbc0c728175
@@@ -1168,34 -1168,51 +1168,51 @@@ static int php_plain_files_rename(php_s
  # 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 */
++# 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) && !defined(NETWARE)
++#  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) && !defined(NETWARE)
++#  if !defined(ZTS) && !defined(TSRM_WIN32)
+                       umask(oldmask);
+ #  endif
+                       return success;
                }
  # endif
  #endif