Towards safe mount #65

Merged
merged 3 commits into from Jun 30, 2016
Jump to file or symbol
Failed to load files and symbols.
+56 −0
Split
@@ -68,9 +68,33 @@ static void test_get_nextpath__weird()
g_assert_cmpstr(result, ==, NULL);
}
+static void test_is_subdir()
+{
+ // Sensible exaples are sensible
+ g_assert_true(is_subdir("/dir/subdir", "/dir/"));
+ g_assert_true(is_subdir("/dir/subdir", "/dir"));
+ g_assert_true(is_subdir("/dir/", "/dir"));
+ g_assert_true(is_subdir("/dir", "/dir"));
+ // Also without leading slash
+ g_assert_true(is_subdir("dir/subdir", "dir/"));
+ g_assert_true(is_subdir("dir/subdir", "dir"));
+ g_assert_true(is_subdir("dir/", "dir"));
+ g_assert_true(is_subdir("dir", "dir"));
+ // Some more ideas
+ g_assert_true(is_subdir("//", "/"));
+ g_assert_true(is_subdir("/", "/"));
+ g_assert_true(is_subdir("", ""));
+ // but this is not true
+ g_assert_false(is_subdir("/", "/dir"));
+ g_assert_false(is_subdir("/rid", "/dir"));
+ g_assert_false(is_subdir("/different/dir", "/dir"));
+ g_assert_false(is_subdir("/", ""));
+}
+
static void __attribute__ ((constructor)) init()
{
g_test_add_func("/mount/get_nextpath/typical",
test_get_nextpath__typical);
g_test_add_func("/mount/get_nextpath/weird", test_get_nextpath__weird);
+ g_test_add_func("/mount/is_subdir", test_is_subdir);
}
View
@@ -392,3 +392,35 @@ static char * __attribute__ ((used))
*offsetp = offset;
return (offset < fulllen) ? &path[offset] : NULL;
}
+
+/**
+ * Check that @subdir is a subdir of @dir.
+**/
+static bool __attribute__ ((used))
+ is_subdir(const char *subdir, const char *dir)
+{
+ size_t dirlen = strlen(dir);
+ size_t subdirlen = strlen(subdir);
+
+ // @dir has to be at least as long as @subdir
+ if (subdirlen < dirlen)
+ return false;
+ // @dir has to be a prefix of @subdir
+ if (strncmp(subdir, dir, dirlen) != 0)
+ return false;
+ // @dir can look like "path/" (that is, end with the directory separator).
+ // When that is the case then given the test above we can be sure @subdir
+ // is a real subdirectory.
+ if (dirlen > 0 && dir[dirlen - 1] == '/')
+ return true;
+ // @subdir can look like "path/stuff" and when the directory separator
+ // is exactly at the spot where @dir ends (that is, it was not caught
+ // by the test above) then @subdir is a real subdirectory.
+ if (subdir[dirlen] == '/' && dirlen > 0)
+ return true;
+ // If both @dir and @subdir have identical length then given that the
+ // prefix check above @subdir is a real subdirectory.
+ if (subdirlen == dirlen)
+ return true;
+ return false;
+}