summaryrefslogtreecommitdiffstats
path: root/src/basic
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-12-17 16:19:09 +0100
committerLennart Poettering <lennart@poettering.net>2020-12-17 19:29:24 +0100
commit95231c7215c3ff14c491eb1d2a93312a8fe0c4f6 (patch)
tree3313cf2b437bc9f3e9c3fc509c372ffe59bc73ae /src/basic
parenttree-wide: suggest meson command lines instead of ninja ones (diff)
downloadsystemd-95231c7215c3ff14c491eb1d2a93312a8fe0c4f6.tar.xz
systemd-95231c7215c3ff14c491eb1d2a93312a8fe0c4f6.zip
test: fix fd_is_mount_point() check
So the currentl and only fd_is_mount_point() check is actually entirely bogus: it passes "/" as filename argument, but that's not actually a a valid filename, but an absolute path. fd_is_mount_point() is written in a way tha the fd refers to a directory and the specified path is a file directly below it that shall be checked. The test call actually violated that rule, but still expected success. Let's fix this, and check for this explicitly, and refuse it. Let's extend the test and move it to test-mountpoint-util.c where the rest of the tests for related calls are placed. Replaces: #18004 Fixes: #17950
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/mountpoint-util.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/basic/mountpoint-util.c b/src/basic/mountpoint-util.c
index 8bed96069f..a6602ad539 100644
--- a/src/basic/mountpoint-util.c
+++ b/src/basic/mountpoint-util.c
@@ -132,6 +132,29 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *ret_mn
return safe_atoi(p, ret_mnt_id);
}
+static bool filename_possibly_with_slash_suffix(const char *s) {
+ const char *slash, *copied;
+
+ /* Checks whether the specified string is either file name, or a filename with a suffix of
+ * slashes. But nothing else.
+ *
+ * this is OK: foo, bar, foo/, bar/, foo//, bar///
+ * this is not OK: "", "/", "/foo", "foo/bar", ".", ".." … */
+
+ slash = strchr(s, '/');
+ if (!slash)
+ return filename_is_valid(s);
+
+ if (slash - s > FILENAME_MAX) /* We want to allocate on the stack below, hence do a size check first */
+ return false;
+
+ if (slash[strspn(slash, "/")] != 0) /* Check that the suffix consist only of one or more slashes */
+ return false;
+
+ copied = strndupa(s, slash - s);
+ return filename_is_valid(copied);
+}
+
int fd_is_mount_point(int fd, const char *filename, int flags) {
_cleanup_free_ struct file_handle *h = NULL, *h_parent = NULL;
int mount_id = -1, mount_id_parent = -1;
@@ -144,6 +167,11 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
assert(filename);
assert((flags & ~(AT_SYMLINK_FOLLOW|AT_EMPTY_PATH)) == 0);
+ /* Insist that the specified filename is actually a filename, and not a path, i.e. some inode further
+ * up or down the tree then immediately below the specified directory fd. */
+ if (!filename_possibly_with_slash_suffix(filename))
+ return -EINVAL;
+
/* First we will try statx()' STATX_ATTR_MOUNT_ROOT attribute, which is our ideal API, available
* since kernel 5.8.
*