* 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.
This commit is contained in:
Ralf Becker 2016-10-19 15:52:02 +02:00
parent 2f4d50b407
commit ae712ff8a1

View File

@ -1555,6 +1555,11 @@ class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface
return $eacls; 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) * 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 * Calls itself recursive to to determine the path of the parent/directory
* *
* @param int|array $fs_ids integer fs_id or array of them * @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 (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; $ids = (array)$fs_ids;
$pathes = array(); $pathes = array();
// first check our stat-cache for the ids // first check our stat-cache for the ids
@ -1610,7 +1621,7 @@ class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface
} }
unset($stmt); 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 ... return false; // parent not found, should never happen ...
} }