~ubuntu-branches/ubuntu/lucid/samba/lucid-security

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
Description: fix mtab corruption via resource limits
Origin: backport, http://git.samba.org/?p=cifs-utils.git;a=commitdiff;h=f6eae44a3d05b6515a59651e6bed8b6dde689aec

Index: samba-3.4.7~dfsg/source3/client/mount.cifs.c
===================================================================
--- samba-3.4.7~dfsg.orig/source3/client/mount.cifs.c	2011-09-29 09:27:30.269335212 -0400
+++ samba-3.4.7~dfsg/source3/client/mount.cifs.c	2011-09-29 09:31:01.057340608 -0400
@@ -1097,6 +1097,7 @@
 	int gid = 0;
 	int optlen = 0;
 	int orgoptlen = 0;
+	int fd, tmprc;
 	size_t options_size = 0;
 	size_t current_len;
 	int retry = 0; /* set when we have to retry mount with uppercase */
@@ -1578,6 +1580,23 @@
 		rc = EX_FILEIO;
 		goto mount_exit;
 	}
+
+	fd = fileno(pmntfile);
+	if (fd < 0) {
+		fprintf(stderr, "mntent does not appear to be valid\n");
+		unlock_mtab();
+		rc = EX_FILEIO;
+		goto mount_exit;
+	}
+	rc = fstat(fd, &statbuf);
+	if (rc != 0) {
+		fprintf(stderr, "unable to fstat open mtab\n");
+		endmntent(pmntfile);
+		unlock_mtab();
+		rc = EX_FILEIO;
+		goto mount_exit;
+	}
+
 	mountent.mnt_fsname = dev_name;
 	mountent.mnt_dir = mountpoint;
 	mountent.mnt_type = CONST_DISCARD(char *,"cifs");
@@ -1609,8 +1628,17 @@
 	}
 	mountent.mnt_freq = 0;
 	mountent.mnt_passno = 0;
-	rc = addmntent(pmntfile,&mountent);
-	endmntent(pmntfile);
+	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;
+	}
 	unlock_mtab();
 	SAFE_FREE(mountent.mnt_opts);
 	if (rc)
Index: samba-3.4.7~dfsg/source3/client/mount.h
===================================================================
--- samba-3.4.7~dfsg.orig/source3/client/mount.h	2011-09-29 09:27:32.797335278 -0400
+++ samba-3.4.7~dfsg/source3/client/mount.h	2011-09-29 09:31:09.457340826 -0400
@@ -34,5 +34,6 @@
 
 extern int lock_mtab(void);
 extern void unlock_mtab(void);
+extern int my_endmntent(FILE *stream, off_t size);
 
 #endif /* ! _MOUNT_H_ */
Index: samba-3.4.7~dfsg/source3/client/mtab.c
===================================================================
--- samba-3.4.7~dfsg.orig/source3/client/mtab.c	2011-09-29 09:27:36.725335379 -0400
+++ samba-3.4.7~dfsg/source3/client/mtab.c	2011-09-29 09:31:31.637341388 -0400
@@ -217,3 +217,30 @@
 	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;
+}