summaryrefslogtreecommitdiffstats
path: root/src/basic
diff options
context:
space:
mode:
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.
*