diff options
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/mountpoint-util.c | 28 |
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. * |