69e578
From 7a990257a05c725d53ca91bc9d080c99102f4e5e Mon Sep 17 00:00:00 2001
69e578
From: Stanislav Malyshev <stas@php.net>
69e578
Date: Mon, 21 Oct 2019 13:17:09 -0700
69e578
Subject: [PATCH] Merge branch 'PHP-7.1' into PHP-7.2
69e578
69e578
* PHP-7.1:
69e578
  Fix bug #78599 (env_path_info underflow can lead to RCE) (CVE-2019-11043)
69e578
  bump versions after release
69e578
  set versions for release
69e578
---
69e578
 sapi/fpm/fpm/fpm_main.c                       |  4 +-
69e578
 .../tests/bug78599-path-info-underflow.phpt   | 61 +++++++++++++++++++
69e578
 sapi/fpm/tests/tester.inc                     | 11 +++-
69e578
 3 files changed, 72 insertions(+), 4 deletions(-)
69e578
 create mode 100644 sapi/fpm/tests/bug78599-path-info-underflow.phpt
69e578
69e578
diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c
69e578
index f0cc3a07a485..b0e6226d9ad8 100644
69e578
--- a/sapi/fpm/fpm/fpm_main.c
69e578
+++ b/sapi/fpm/fpm/fpm_main.c
69e578
@@ -1209,8 +1209,8 @@ static void init_request_info(void)
69e578
 								path_info = script_path_translated + ptlen;
69e578
 								tflag = (slen != 0 && (!orig_path_info || strcmp(orig_path_info, path_info) != 0));
69e578
 							} else {
69e578
-								path_info = env_path_info ? env_path_info + pilen - slen : NULL;
69e578
-								tflag = (orig_path_info != path_info);
69e578
+								path_info = (env_path_info && pilen > slen) ? env_path_info + pilen - slen : NULL;
69e578
+								tflag = path_info && (orig_path_info != path_info);
69e578
 							}
69e578
 
69e578
 							if (tflag) {
69e578
diff --git a/sapi/fpm/tests/bug78599-path-info-underflow.phpt b/sapi/fpm/tests/bug78599-path-info-underflow.phpt
69e578
new file mode 100644
69e578
index 000000000000..edd4e0d49699
69e578
--- /dev/null
69e578
+++ b/sapi/fpm/tests/bug78599-path-info-underflow.phpt
69e578
@@ -0,0 +1,61 @@
69e578
+--TEST--
69e578
+FPM: bug78599 - env_path_info underflow - CVE-2019-11043
69e578
+--SKIPIF--
69e578
+
69e578
+--FILE--
69e578
+
69e578
+
69e578
+require_once "tester.inc";
69e578
+
69e578
+$cfg = <<
69e578
+[global]
69e578
+error_log = {{FILE:LOG}}
69e578
+[unconfined]
69e578
+listen = {{ADDR}}
69e578
+pm = dynamic
69e578
+pm.max_children = 5
69e578
+pm.start_servers = 1
69e578
+pm.min_spare_servers = 1
69e578
+pm.max_spare_servers = 3
69e578
+EOT;
69e578
+
69e578
+$code = <<
69e578
+
69e578
+echo "Test Start\n";
69e578
+var_dump(\$_SERVER["PATH_INFO"]);
69e578
+echo "Test End\n";
69e578
+EOT;
69e578
+
69e578
+$tester = new FPM\Tester($cfg, $code);
69e578
+$tester->start();
69e578
+$tester->expectLogStartNotices();
69e578
+$uri = $tester->makeSourceFile();
69e578
+$tester
69e578
+    ->request(
69e578
+        '',
69e578
+        [
69e578
+            'SCRIPT_FILENAME' => $uri . "/" . str_repeat('A', 35),
69e578
+            'PATH_INFO'       => '',
69e578
+            'HTTP_HUI'        => str_repeat('PTEST', 1000),
69e578
+        ],
69e578
+        $uri
69e578
+    )
69e578
+    ->expectBody(
69e578
+        [
69e578
+            'Test Start',
69e578
+            'string(0) ""',
69e578
+            'Test End'
69e578
+        ]
69e578
+    );
69e578
+$tester->terminate();
69e578
+$tester->close();
69e578
+
69e578
+?>
69e578
+Done
69e578
+--EXPECT--
69e578
+Done
69e578
+--CLEAN--
69e578
+
69e578
+require_once "tester.inc";
69e578
+FPM\Tester::clean();
69e578
+?>
69e578
diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc
69e578
index 70c03ad70f1c..3b6702866cc1 100644
69e578
--- a/sapi/fpm/tests/tester.inc
69e578
+++ b/sapi/fpm/tests/tester.inc
69e578
@@ -513,7 +513,7 @@ class Tester
69e578
             return new Response(null, true);
69e578
         }
69e578
         if (is_null($uri)) {
69e578
-            $uri = $this->makeFile('src.php', $this->code);
69e578
+            $uri = $this->makeSourceFile();
69e578
         }
69e578
 
69e578
         $params = array_merge(
69e578
@@ -538,7 +538,6 @@ class Tester
69e578
             ],
69e578
             $headers
69e578
         );
69e578
-
69e578
         try {
69e578
             $this->response = new Response(
69e578
                 $this->getClient($address, $connKeepAlive)->request_data($params, false)
69e578
@@ -944,6 +943,14 @@ class Tester
69e578
         return $filePath;
69e578
     }
69e578
 
69e578
+    /**
69e578
+     * @return string
69e578
+     */
69e578
+    public function makeSourceFile()
69e578
+    {
69e578
+        return $this->makeFile('src.php', $this->code);
69e578
+    }
69e578
+
69e578
     /**
69e578
      * @param string|null $msg
69e578
      */