summaryrefslogtreecommitdiff
path: root/sutils
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2014-11-21 04:08:57 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2014-11-21 04:08:57 +0100
commit36f340ae47a0f643be6d59a8190600cdd34eef0c (patch)
treec9e876b6c755dd53bc3a7aeedda1b88295c8fd3e /sutils
parentf981d5bdba78ef72dbbf0d22c146890a305d487c (diff)
Always canonicalize fstab entries with realpath
To avoid spurious ./, /, symlinks, etc. * sutils/fstab.c (fs_set_mntent): Try to call realpath on mnt_fsname and mnt_dir field of `mntent'. (fstab_find_mount): Try to call realpath on `name' parameter. (fstab_find): Do not try to call realpath. (fstab_read): Reset errno to zero before calling getmntent. * utils/umount.c (main): Do not warn about missing fstab entries for active translators.
Diffstat (limited to 'sutils')
-rw-r--r--sutils/fstab.c103
1 files changed, 62 insertions, 41 deletions
diff --git a/sutils/fstab.c b/sutils/fstab.c
index ed591519..e13f15b0 100644
--- a/sutils/fstab.c
+++ b/sutils/fstab.c
@@ -240,16 +240,32 @@ fstypes_find_program (struct fstypes *types, const char *program,
/* Copy MNTENT into FS, copying component strings as well. */
error_t
-fs_set_mntent (struct fs *fs, const struct mntent *mntent)
+fs_set_mntent (struct fs *fs, const struct mntent *provided_mntent)
{
char *end;
size_t needed = 0;
+ struct mntent mntent = *provided_mntent;
+ char *real_fsname = NULL;
+ char *real_dir = NULL;
if (fs->storage)
free (fs->storage);
+ if (mntent.mnt_fsname)
+ {
+ real_fsname = realpath (mntent.mnt_fsname, NULL);
+ if (real_fsname)
+ mntent.mnt_fsname = real_fsname;
+ }
+ if (mntent.mnt_dir)
+ {
+ real_dir = realpath (mntent.mnt_dir, NULL);
+ if (real_dir)
+ mntent.mnt_dir = real_dir;
+ }
+
/* Allocate space for all string mntent fields in FS. */
-#define COUNT(field) if (mntent->field) needed += strlen (mntent->field) + 1;
+#define COUNT(field) if (mntent.field) needed += strlen (mntent.field) + 1;
COUNT (mnt_fsname);
COUNT (mnt_dir);
COUNT (mnt_type);
@@ -258,10 +274,14 @@ fs_set_mntent (struct fs *fs, const struct mntent *mntent)
fs->storage = malloc (needed);
if (! fs->storage)
- return ENOMEM;
+ {
+ free (real_fsname);
+ free (real_dir);
+ return ENOMEM;
+ }
- if (!fs->mntent.mnt_dir || !mntent->mnt_dir
- || strcmp (fs->mntent.mnt_dir, mntent->mnt_dir) != 0)
+ if (!fs->mntent.mnt_dir || !mntent.mnt_dir
+ || strcmp (fs->mntent.mnt_dir, mntent.mnt_dir) != 0)
{
fs->mounted = fs->readonly = -1;
if (fs->fsys != MACH_PORT_NULL)
@@ -270,15 +290,15 @@ fs_set_mntent (struct fs *fs, const struct mntent *mntent)
}
/* Copy MNTENT into FS; string-valued fields will be fixed up next. */
- fs->mntent = *mntent;
+ fs->mntent = mntent;
/* Copy each mntent field from MNTENT into FS's version. */
end = fs->storage;
#define STORE(field) \
- if (mntent->field) \
+ if (mntent.field) \
{ \
fs->mntent.field = end; \
- end = stpcpy (end, mntent->field) + 1; \
+ end = stpcpy (end, mntent.field) + 1; \
} \
else \
fs->mntent.field = 0;
@@ -289,10 +309,13 @@ fs_set_mntent (struct fs *fs, const struct mntent *mntent)
#undef STORE
if (fs->type
- && (!mntent->mnt_type
- || strcasecmp (fs->type->name, mntent->mnt_type) != 0))
+ && (!mntent.mnt_type
+ || strcasecmp (fs->type->name, mntent.mnt_type) != 0))
fs->type = 0; /* Type is different. */
+ free (real_fsname);
+ free (real_dir);
+
return 0;
}
@@ -470,11 +493,21 @@ fstab_find_device (const struct fstab *fstab, const char *name)
if (strcmp (name, "none") == 0)
return NULL;
+ char *real_name = realpath (name, NULL);
+ const char *lookup_name;
+
+ if (real_name)
+ lookup_name = real_name;
+ else
+ lookup_name = name;
+
struct fs *fs;
for (fs = fstab->entries; fs; fs = fs->next)
- if (strcmp (fs->mntent.mnt_fsname, name) == 0)
- return fs;
- return 0;
+ if (strcmp (fs->mntent.mnt_fsname, lookup_name) == 0)
+ break;
+
+ free (real_name);
+ return fs;
}
/* Returns the FS entry in FSTAB with the mount point NAME (there can only
@@ -482,8 +515,6 @@ fstab_find_device (const struct fstab *fstab, const char *name)
inline struct fs *
fstab_find_mount (const struct fstab *fstab, const char *name)
{
- struct fs *fs;
-
/* Don't count "none" or "-" as matching any other mount point.
It is canonical to use "none" for swap partitions, and multiple
such do not in fact conflict with each other. Likewise, the
@@ -494,10 +525,21 @@ fstab_find_mount (const struct fstab *fstab, const char *name)
|| !strcmp (name, "ignore"))
return 0;
+ char *real_name = realpath (name, NULL);
+ const char *lookup_name;
+
+ if (real_name)
+ lookup_name = real_name;
+ else
+ lookup_name = name;
+
+ struct fs *fs;
for (fs = fstab->entries; fs; fs = fs->next)
- if (strcmp (fs->mntent.mnt_dir, name) == 0)
- return fs;
- return 0;
+ if (strcmp (fs->mntent.mnt_dir, lookup_name) == 0)
+ break;
+
+ free (real_name);
+ return fs;
}
/* Returns the FS entry in FSTAB with the device or mount point NAME (there
@@ -505,29 +547,7 @@ fstab_find_mount (const struct fstab *fstab, const char *name)
inline struct fs *
fstab_find (const struct fstab *fstab, const char *name)
{
- struct fs *ret;
- char *real_name;
-
- ret = fstab_find_device (fstab, name);
- if (ret)
- return ret;
-
- ret = fstab_find_mount (fstab, name);
- if (ret)
- return ret;
-
- real_name = realpath (name, NULL);
-
- ret = fstab_find_device (fstab, real_name);
- if (ret) {
- free (real_name);
- return ret;
- }
-
- ret = fstab_find_mount (fstab, real_name);
- free (real_name);
-
- return ret;
+ return fstab_find_device (fstab, name) ?: fstab_find_mount (fstab, name);
}
/* Cons FS onto the beginning of FSTAB's entry list. */
@@ -690,6 +710,7 @@ fstab_read (struct fstab *fstab, const char *name)
{
while (!err && !feof (stream))
{
+ errno = 0;
struct mntent *mntent = getmntent (stream);
if (! mntent)