summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-03-23 22:26:06 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-05-07 11:56:48 +0200
commit41b24382e7849758e456eef50bbf740a1f097c6e (patch)
tree1e6c203e816a17df8a2d90a2b35b286c688d5528
parent491107a044bdfeb5877c413d0f5421bb7afde158 (diff)
downloadsystemd-41b24382e7849758e456eef50bbf740a1f097c6e.tar.gz
mountpoint-util: a symlink is never a mount point
The various flavours of stat() basically tell us for free if something is a symlink. If it is, then it's definitely not a mount point. Use that. All other inode types can be mount point, just symlinks cannot. (cherry picked from commit b898474fecda9e39aa06512ef7ba358c9685d84e)
-rw-r--r--src/basic/mountpoint-util.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/src/basic/mountpoint-util.c b/src/basic/mountpoint-util.c
index c8f6675eb8..6d47419194 100644
--- a/src/basic/mountpoint-util.c
+++ b/src/basic/mountpoint-util.c
@@ -196,13 +196,15 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
if (statx(fd, filename, (FLAGS_SET(flags, AT_SYMLINK_FOLLOW) ? 0 : AT_SYMLINK_NOFOLLOW) |
(flags & AT_EMPTY_PATH) |
- AT_NO_AUTOMOUNT, 0, &sx) < 0) {
+ AT_NO_AUTOMOUNT, STATX_TYPE, &sx) < 0) {
if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
return -errno;
/* If statx() is not available or forbidden, fall back to name_to_handle_at() below */
} else if (FLAGS_SET(sx.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT)) /* yay! */
return FLAGS_SET(sx.stx_attributes, STATX_ATTR_MOUNT_ROOT);
+ else if (FLAGS_SET(sx.stx_mask, STATX_TYPE) && S_ISLNK(sx.stx_mode))
+ return false; /* symlinks are never mount points */
r = name_to_handle_at_loop(fd, filename, &h, &mount_id, flags);
if (IN_SET(r, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL))
@@ -280,6 +282,8 @@ fallback_fstat:
flags |= AT_SYMLINK_NOFOLLOW;
if (fstatat(fd, filename, &a, flags) < 0)
return -errno;
+ if (S_ISLNK(a.st_mode)) /* Symlinks are never mount points */
+ return false;
if (fstatat(fd, "", &b, AT_EMPTY_PATH) < 0)
return -errno;