From 40f6425978917209cb0c2c3be05a25c65c9a900e Mon Sep 17 00:00:00 2001
From: gwx620998 <gulining1@huawei.com>
Date: Sat, 23 Mar 2019 07:14:35 -0400
Subject: [PATCH] CVE-2019-9637

Signed-off-by: gwx620998 <gulining1@huawei.com>
---
 main/streams/plain_wrapper.c | 50 +++++++++++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 17 deletions(-)

diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index 9b36d00..cb9e642 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -1168,34 +1168,50 @@ 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;
 #  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;
-						}
+					/*
+					 * 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
-- 
1.8.3.1

