From e8959617b6ab87272a916034e02dfcb743c2b327 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 1 Oct 2021 13:15:52 -0400 Subject: [PATCH] fix bug in dirContains dirContains ".." "../.." was incorrectly True. This does not seem to be an exploitable security hole, at least as dirContains is used in git-annex. Sponsored-by: Jochen Bartl on Patreon --- Utility/Path.hs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Utility/Path.hs b/Utility/Path.hs index 8c6aa7f704..4fbc2805c0 100644 --- a/Utility/Path.hs +++ b/Utility/Path.hs @@ -95,13 +95,27 @@ upFrom dir dirContains :: RawFilePath -> RawFilePath -> Bool dirContains a b = a == b || a' == b' - || (addTrailingPathSeparator a') `B.isPrefixOf` b' + || (a'' `B.isPrefixOf` b' && avoiddotdotb) || a' == "." && normalise ("." b') == b' where a' = norm a + a'' = addTrailingPathSeparator a' b' = norm b norm = normalise . simplifyPath + {- This handles the case where a is ".." and b is "../..", + - which is not inside a. Similarly, "../.." does not contain + - "../../../". Due to the use of norm, cases like + - "../../foo/../../" get converted to eg "../../.." and + - so do not need to be handled specially here. + - + - When this is called, we already know that + - a'' is a prefix of b', so all that needs to be done is drop + - that prefix, and check if the next path component is ".." + -} + avoiddotdotb = not $ any (== "..") $ + splitPath $ B.drop (B.length a'') b' + {- Given an original list of paths, and an expanded list derived from it, - which may be arbitrarily reordered, generates a list of lists, where - each sublist corresponds to one of the original paths. -- 2.30.2