You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by "pyckle (via GitHub)" <gi...@apache.org> on 2023/04/23 13:08:53 UTC

[GitHub] [mina-sshd] pyckle commented on a diff in pull request #362: Fix rooted filesystem

pyckle commented on code in PR #362:
URL: https://github.com/apache/mina-sshd/pull/362#discussion_r1174578418


##########
sshd-common/src/main/java/org/apache/sshd/common/util/io/IoUtils.java:
##########
@@ -637,4 +677,75 @@ public static List<String> readAllLines(BufferedReader reader, int lineCountHint
         }
         return result;
     }
+
+    /**
+     * Chroot a path under the new root
+     *
+     * @param  newRoot    the new root
+     * @param  toSanitize the path to sanitize and chroot
+     * @return            the chrooted path under the newRoot filesystem
+     */
+    public static Path chroot(Path newRoot, Path toSanitize) {
+        Objects.requireNonNull(newRoot);
+        Objects.requireNonNull(toSanitize);
+        List<String> sanitized = removeExtraCdUps(toSanitize);
+        return buildPath(newRoot, newRoot.getFileSystem(), sanitized);
+    }
+
+    /**
+     * Remove any extra directory ups from the Path
+     *
+     * @param  toSanitize the path to sanitize
+     * @return            the sanitized path
+     */
+    public static Path removeCdUpAboveRoot(Path toSanitize) {
+        List<String> sanitized = removeExtraCdUps(toSanitize);
+        return buildPath(toSanitize.getRoot(), toSanitize.getFileSystem(), sanitized);
+    }
+
+    private static List<String> removeExtraCdUps(Path toResolve) {
+        List<String> newNames = new ArrayList<>(toResolve.getNameCount());
+
+        int numCdUps = 0;
+        int numDirParts = 0;
+        for (int i = 0; i < toResolve.getNameCount(); i++) {
+            String name = toResolve.getName(i).toString();
+            if ("..".equals(name)) {
+                // If we have more cdups than dir parts, so we ignore the ".." to avoid jail escapes
+                if (numDirParts > numCdUps) {
+                    ++numCdUps;
+                    newNames.add(name);
+                }
+            } else {
+                // if the current directory is a part of the name, don't increment number of dir parts, as it doesn't
+                // add to the number of ".."s that can be present before the root
+                if (!".".equals(name)) {
+                    ++numDirParts;
+                }
+                newNames.add(name);
+            }
+        }
+        return newNames;
+    }
+
+    private static Path buildPath(Path root, FileSystem fs, List<String> namesList) {
+        if (namesList.isEmpty()) {
+            return root == null ? fs.getPath(".") : root;
+        }
+
+        Path cleanedPathToResolve = buildPath(fs, namesList);
+        return root.resolve(cleanedPathToResolve);
+    }
+
+    private static Path buildPath(FileSystem fs, List<String> namesList) {

Review Comment:
   A List is an ordered collection. Why should this API permit an unordered collection?



##########
sshd-common/src/main/java/org/apache/sshd/common/util/io/IoUtils.java:
##########
@@ -637,4 +677,75 @@ public static List<String> readAllLines(BufferedReader reader, int lineCountHint
         }
         return result;
     }
+
+    /**
+     * Chroot a path under the new root
+     *
+     * @param  newRoot    the new root
+     * @param  toSanitize the path to sanitize and chroot
+     * @return            the chrooted path under the newRoot filesystem
+     */
+    public static Path chroot(Path newRoot, Path toSanitize) {
+        Objects.requireNonNull(newRoot);
+        Objects.requireNonNull(toSanitize);
+        List<String> sanitized = removeExtraCdUps(toSanitize);
+        return buildPath(newRoot, newRoot.getFileSystem(), sanitized);
+    }
+
+    /**
+     * Remove any extra directory ups from the Path
+     *
+     * @param  toSanitize the path to sanitize
+     * @return            the sanitized path
+     */
+    public static Path removeCdUpAboveRoot(Path toSanitize) {
+        List<String> sanitized = removeExtraCdUps(toSanitize);
+        return buildPath(toSanitize.getRoot(), toSanitize.getFileSystem(), sanitized);
+    }
+
+    private static List<String> removeExtraCdUps(Path toResolve) {
+        List<String> newNames = new ArrayList<>(toResolve.getNameCount());
+
+        int numCdUps = 0;
+        int numDirParts = 0;
+        for (int i = 0; i < toResolve.getNameCount(); i++) {
+            String name = toResolve.getName(i).toString();
+            if ("..".equals(name)) {
+                // If we have more cdups than dir parts, so we ignore the ".." to avoid jail escapes
+                if (numDirParts > numCdUps) {
+                    ++numCdUps;
+                    newNames.add(name);
+                }
+            } else {
+                // if the current directory is a part of the name, don't increment number of dir parts, as it doesn't
+                // add to the number of ".."s that can be present before the root
+                if (!".".equals(name)) {
+                    ++numDirParts;
+                }
+                newNames.add(name);
+            }
+        }
+        return newNames;
+    }
+
+    private static Path buildPath(Path root, FileSystem fs, List<String> namesList) {

Review Comment:
   A List is an ordered collection. Why should this API permit an unordered collection?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@mina.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@mina.apache.org
For additional commands, e-mail: dev-help@mina.apache.org