From: Nicolas Grekas <nicolas.grekas@gmail.com>
Date: Fri, 18 May 2018 09:42:46 +0200
Subject: [HttpFoundation] Break infinite loop in PdoSessionHandler when MySQL
 is in loose mode

[CVE-2018-11386] https://symfony.com/blog/cve-2018-11386-denial-of-service-when-using-pdosessionhandler

Origin: backport, https://github.com/symfony/symfony/commit/0cf874e23e12cad4e3546de10aa793e5fe8a31f0
---
 .../HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php    | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
index 48e81ee..27b2c0c 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
@@ -510,6 +510,7 @@ class PdoSessionHandler implements \SessionHandlerInterface
         $selectSql = $this->getSelectSql();
         $selectStmt = $this->pdo->prepare($selectSql);
         $selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
+        $insertStmt = null;
         $selectStmt->execute();
 
         $sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM);
@@ -524,6 +525,11 @@ class PdoSessionHandler implements \SessionHandlerInterface
             return is_resource($sessionRows[0][0]) ? stream_get_contents($sessionRows[0][0]) : $sessionRows[0][0];
         }
 
+        if (null !== $insertStmt) {
+            $this->rollback();
+            throw new \RuntimeException('Failed to read session: INSERT reported a duplicate id but next SELECT did not return any data.');
+        }
+
         if (self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) {
             // Exclusive-reading of non-existent rows does not block, so we need to do an insert to block
             // until other connections to the session are committed.
