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
106
107
|
Description: fix denial of service via stale mtab lockfile
Origin: backport, http://git.samba.org/?p=cifs-utils.git;a=commitdiff;h=810f7e4e0f2dbcbee0294d9b371071cb08268200
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:21:45.361326382 -0400
+++ samba-3.4.7~dfsg/source3/client/mount.cifs.c 2011-09-29 09:25:33.893332232 -0400
@@ -40,6 +40,7 @@
#include <fcntl.h>
#include <limits.h>
#include "mount.h"
+#include <signal.h>
#define MOUNT_CIFS_VERSION_MAJOR "1"
#define MOUNT_CIFS_VERSION_MINOR "12"
@@ -182,9 +183,9 @@
}
/* caller frees username if necessary */
-static char * getusername(void) {
+static char * getusername(uid_t uid) {
char *username = NULL;
- struct passwd *password = getpwuid(getuid());
+ struct passwd *password = getpwuid(uid);
if (password) {
username = password->pw_name;
@@ -1082,6 +1083,7 @@
const char * ipaddr = NULL;
char * uuid = NULL;
char * mountpoint = NULL;
+ char * mount_user = NULL;
char * options = NULL;
char * optionstail;
char * resolved_path = NULL;
@@ -1105,6 +1107,7 @@
struct sockaddr_in *addr4;
struct sockaddr_in6 *addr6;
FILE * pmntfile;
+ sigset_t mask, oldmask;
/* setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
@@ -1367,7 +1370,7 @@
if (getenv("USER"))
user_name = strdup(getenv("USER"));
if (user_name == NULL)
- user_name = getusername();
+ user_name = getusername(getuid());
got_user = 1;
}
@@ -1530,6 +1533,38 @@
if (nomtab)
goto mount_exit;
+
+ uid = getuid();
+ if (uid != 0)
+ mount_user = getusername(uid);
+
+ /*
+ * Set the real uid to the effective uid. This prevents unprivileged
+ * users from sending signals to this process, though ^c on controlling
+ * terminal should still work.
+ */
+ rc = setreuid(geteuid(), -1);
+ if (rc != 0) {
+ fprintf(stderr, "Unable to set real uid to effective uid: %s\n",
+ strerror(errno));
+ rc = EX_FILEIO;
+ goto mount_exit;
+ }
+
+ rc = sigfillset(&mask);
+ if (rc) {
+ fprintf(stderr, "Unable to set filled signal mask\n");
+ rc = EX_FILEIO;
+ goto mount_exit;
+ }
+
+ rc = sigprocmask(SIG_SETMASK, &mask, &oldmask);
+ if (rc) {
+ fprintf(stderr, "Unable to make process ignore signals\n");
+ rc = EX_FILEIO;
+ goto mount_exit;
+ }
+
atexit(unlock_mtab);
rc = lock_mtab();
if (rc) {
@@ -1548,7 +1583,6 @@
mountent.mnt_type = CONST_DISCARD(char *,"cifs");
mountent.mnt_opts = (char *)malloc(220);
if(mountent.mnt_opts) {
- char * mount_user = getusername();
memset(mountent.mnt_opts,0,200);
if(flags & MS_RDONLY)
strlcat(mountent.mnt_opts,"ro",220);
@@ -1581,6 +1615,7 @@
SAFE_FREE(mountent.mnt_opts);
if (rc)
rc = EX_FILEIO;
+ sigprocmask(SIG_SETMASK, &oldmask, NULL);
mount_exit:
if(mountpassword) {
int len = strlen(mountpassword);
|