summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mount.cifs.c27
-rw-r--r--mount.h1
-rw-r--r--mtab.c27
3 files changed, 53 insertions, 2 deletions
diff --git a/mount.cifs.c b/mount.cifs.c
index 9d7e107..107a5a5 100644
--- a/mount.cifs.c
+++ b/mount.cifs.c
@@ -1428,10 +1428,11 @@ static int check_mtab(const char *progname, const char *devname,
static int
add_mtab(char *devname, char *mountpoint, unsigned long flags, const char *fstype)
{
- int rc = 0;
+ int rc = 0, tmprc, fd;
uid_t uid;
char *mount_user = NULL;
struct mntent mountent;
+ struct stat statbuf;
FILE *pmntfile;
sigset_t mask, oldmask;
@@ -1483,6 +1484,23 @@ add_mtab(char *devname, char *mountpoint, unsigned long flags, const char *fstyp
goto add_mtab_exit;
}
+ fd = fileno(pmntfile);
+ if (fd < 0) {
+ fprintf(stderr, "mntent does not appear to be valid\n");
+ unlock_mtab();
+ rc = EX_FILEIO;
+ goto add_mtab_exit;
+ }
+
+ rc = fstat(fd, &statbuf);
+ if (rc != 0) {
+ fprintf(stderr, "unable to fstat open mtab\n");
+ endmntent(pmntfile);
+ unlock_mtab();
+ rc = EX_FILEIO;
+ goto add_mtab_exit;
+ }
+
mountent.mnt_fsname = devname;
mountent.mnt_dir = mountpoint;
mountent.mnt_type = (char *)(void *)fstype;
@@ -1514,9 +1532,14 @@ add_mtab(char *devname, char *mountpoint, unsigned long flags, const char *fstyp
rc = addmntent(pmntfile, &mountent);
if (rc) {
fprintf(stderr, "unable to add mount entry to mtab\n");
+ ftruncate(fd, statbuf.st_size);
+ rc = EX_FILEIO;
+ }
+ tmprc = my_endmntent(pmntfile, statbuf.st_size);
+ if (tmprc) {
+ fprintf(stderr, "error %d detected on close of mtab\n", tmprc);
rc = EX_FILEIO;
}
- endmntent(pmntfile);
unlock_mtab();
SAFE_FREE(mountent.mnt_opts);
add_mtab_exit:
diff --git a/mount.h b/mount.h
index d49c2ea..80bdbe7 100644
--- a/mount.h
+++ b/mount.h
@@ -35,5 +35,6 @@
extern int mtab_unusable(void);
extern int lock_mtab(void);
extern void unlock_mtab(void);
+extern int my_endmntent(FILE *stream, off_t size);
#endif /* ! _MOUNT_H_ */
diff --git a/mtab.c b/mtab.c
index 9cd50d8..de545b7 100644
--- a/mtab.c
+++ b/mtab.c
@@ -251,3 +251,30 @@ lock_mtab (void) {
return 0;
}
+/*
+ * Call fflush and fsync on the mtab, and then endmntent. If either fflush
+ * or fsync fails, then truncate the file back to "size". endmntent is called
+ * unconditionally, and the errno (if any) from fflush and fsync are returned.
+ */
+int
+my_endmntent(FILE *stream, off_t size)
+{
+ int rc, fd;
+
+ fd = fileno(stream);
+ if (fd < 0)
+ return -EBADF;
+
+ rc = fflush(stream);
+ if (!rc)
+ rc = fsync(fd);
+
+ /* truncate file back to "size" -- best effort here */
+ if (rc) {
+ rc = errno;
+ ftruncate(fd, size);
+ }
+
+ endmntent(stream);
+ return rc;
+}