aboutsummaryrefslogtreecommitdiffstats
path: root/mount.cifs.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@samba.org>2011-07-12 08:19:33 -0400
committerJeff Layton <jlayton@samba.org>2011-07-12 08:19:33 -0400
commitf6eae44a3d05b6515a59651e6bed8b6dde689aec (patch)
tree00517eac476b521a2c446cab42e2cc41f0d62aaa /mount.cifs.c
parent775610358cb4cff8a6f322d0e8d5fade078f6f54 (diff)
downloadcifs-utils-f6eae44a3d05b6515a59651e6bed8b6dde689aec.tar.gz
cifs-utils-f6eae44a3d05b6515a59651e6bed8b6dde689aec.tar.xz
cifs-utils-f6eae44a3d05b6515a59651e6bed8b6dde689aec.zip
mtab: handle ENOSPC/EFBIG condition properly when altering mtab
It's possible that when mount.cifs goes to append the mtab that there won't be enough space to do so, and the mntent won't be appended to the file in its entirety. Add a my_endmntent routine that will fflush and then fsync the FILE if that succeeds. If either fails then it will truncate the file back to its provided size. It will then call endmntent unconditionally. Have add_mtab call fstat on the opened mtab file in order to get the size of the file before it has been appended. Assuming that that succeeds, use my_endmntent to ensure that the file is not corrupted before closing it. It's possible that we'll have a small race window where the mtab is incorrect, but it should be quickly corrected. This was reported some time ago as CVE-2011-1678: http://openwall.com/lists/oss-security/2011/03/04/9 ...and it seems to fix the reproducer that I was able to come up with. Signed-off-by: Jeff Layton <jlayton@samba.org> Reviewed-by: Suresh Jayaraman <sjayaraman@suse.de>
Diffstat (limited to 'mount.cifs.c')
-rw-r--r--mount.cifs.c27
1 files changed, 25 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: