From ae712ff8a19a10fa59653145be739e784385f5cf Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Wed, 19 Oct 2016 15:52:02 +0200 Subject: [PATCH] * Filemanager: break infinit recursion stalling eg. login by introducing max. sub-directory depth of 100 Detects infinit recursion caused eg. by fs_dir pointing to a child-directory. No idea how to efficently test for that, without scanning all parents of all filesystme nodes. --- api/src/Vfs/Sqlfs/StreamWrapper.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/api/src/Vfs/Sqlfs/StreamWrapper.php b/api/src/Vfs/Sqlfs/StreamWrapper.php index 6478a1031b..dd95c96d12 100644 --- a/api/src/Vfs/Sqlfs/StreamWrapper.php +++ b/api/src/Vfs/Sqlfs/StreamWrapper.php @@ -1555,6 +1555,11 @@ class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface return $eacls; } + /** + * Max allowed sub-directory depth, to be able to break infinit recursion by wrongly linked directories + */ + const MAX_ID2PATH_RECURSION = 100; + /** * Return the path of given fs_id(s) * @@ -1562,11 +1567,17 @@ class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface * Calls itself recursive to to determine the path of the parent/directory * * @param int|array $fs_ids integer fs_id or array of them - * @return string|array path or array or pathes indexed by fs_id + * @param int $recursion_count =0 internally used to break infinit recursions + * @return false|string|array path or array or pathes indexed by fs_id, or false on error */ - static function id2path($fs_ids) + static function id2path($fs_ids, $recursion_count=0) { if (self::LOG_LEVEL > 1) error_log(__METHOD__.'('.array2string($fs_ids).')'); + if ($recursion_count > self::MAX_ID2PATH_RECURSION) + { + error_log(__METHOD__."(".array2string($fs_ids).", $recursion_count) max recursion depth reached, probably broken filesystem!"); + return false; + } $ids = (array)$fs_ids; $pathes = array(); // first check our stat-cache for the ids @@ -1610,7 +1621,7 @@ class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface } unset($stmt); - if ($parents && !($parents = self::id2path($parents))) + if ($parents && !($parents = self::id2path($parents, $recursion_count+1))) { return false; // parent not found, should never happen ... }