summaryrefslogtreecommitdiff
path: root/security/CoolKey/patches/patch-ab
blob: b146679d5d43fccfc778ec82b9300df12a713ac6 (plain)
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
$NetBSD: patch-ab,v 1.1.1.1 2008/03/04 11:33:02 shannonjr Exp $

--- src/coolkey/machdep.cpp.orig	2007-02-13 17:46:28.000000000 -0700
+++ src/coolkey/machdep.cpp
@@ -17,6 +17,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  * ***** END COPYRIGHT BLOCK *****/
 
+/* Patch from RedHAT coolkey-1.1.0-5.el5.src.rpm */
+
 #include "machdep.h"
 #include "mypkcs11.h"
 #include "PKCS11Exception.h"
@@ -185,12 +187,20 @@ void OSSleep(int time) 
 #define MAP_INHERIT 0
 #endif
 
+#ifndef BASEPATH
+#ifdef MAC
+#define BASEPATH "/var"
+#else
+#define BASEPATH "/var/cache"
+#endif
+#endif
+
 #ifdef FULL_CLEANUP
 #define RESERVED_OFFSET 256
-#define MEMSEGPATH "/tmp/.pk11ipc"
+#define MEMSEGPATH BASEPATH"/coolkey-lock"
 #else 
 #define RESERVED_OFFSET 0
-#define MEMSEGPATH "/tmp/.pk11ipc1"
+#define MEMSEGPATH BASEPATH"/coolkey"
 #endif
 
 struct SHMemData {
@@ -208,11 +218,6 @@ SHMemData::~SHMemData() { 
 #ifdef FULL_CLEANUP
 	flock(fd,LOCK_EX);
 	unsigned long ref = --(*(unsigned long *)addr); 
-#ifdef notdef
-	if (ref == 0) {
-	    unlink(path);
-	}
-#endif
 	flock(fd, LOCK_UN);
 #endif
 	munmap(addr,size+RESERVED_OFFSET);
@@ -225,6 +230,73 @@ SHMemData::~SHMemData() { 
     }
 }
 
+/*
+ * The cache directory is shared and accessible by anyone, make
+ * sure the cache file we are opening is really a valid cache file.
+ */
+int safe_open(char *path, int flags, int mode, int size)
+{
+    struct stat buf;
+    int fd, ret;
+
+    fd = open (path, flags|O_NOFOLLOW, mode);
+
+    if (fd < 0) {
+	return fd;
+    }
+
+    ret = fstat(fd, &buf);
+    if (ret < 0) {
+	close (fd);
+	return ret;
+    }
+
+    /* our cache files are pretty specific, make sure we are looking
+     * at the correct one */
+
+    /* first, we should own the file ourselves, don't open a file
+     * that someone else wanted us to see. */
+    if (buf.st_uid != getuid()) {
+	close(fd);
+	errno = EACCES;
+	return -1;
+    }
+
+    /* next, there should only be one link in this file. Don't
+     * use this code to trash another file */
+    if (buf.st_nlink != 1) {
+	close(fd);
+	errno = EMLINK;
+	return -1;
+    }
+
+    /* next, This better be a regular file */
+    if (!S_ISREG(buf.st_mode)) {
+	close(fd);
+	errno = EACCES;
+	return -1;
+    }
+
+    /* if the permissions don't match, something is wrong */
+    if ((buf.st_mode & 03777) != mode) {
+	close(fd);
+	errno = EACCES;
+	return -1;
+    }
+
+    /* finally the file should be the correct size. This 
+     * check isn't so much to protect from an attack, as it is to
+     * detect a corrupted cache file */
+    if (buf.st_size != size) {
+	close(fd);
+	errno = EACCES;
+	return -1;
+    }
+
+    /* OK, the file checked out, ok to continue */
+    return fd;
+}
+
 SHMem::SHMem(): shmemData(0) {}
 
 SHMem *
@@ -248,7 +320,7 @@ SHMem::initSegment(const char *name, int
 	return NULL;
     }
     int mask = umask(0);
-    int ret = mkdir (MEMSEGPATH, 0777);
+    int ret = mkdir (MEMSEGPATH, 01777);
     umask(mask);
     if ((ret == -1) && (errno != EEXIST)) {
 	delete shmemData;
@@ -264,21 +336,16 @@ SHMem::initSegment(const char *name, int
     shmemData->path[sizeof(MEMSEGPATH)-1] = '/';
     strcpy(&shmemData->path[sizeof(MEMSEGPATH)],name);
 
-    int mode = 0777;
-    if (strcmp(name,"token_names") != 0) {
-	/* each user gets his own uid array */
-    	sprintf(uid_str, "-%u",getuid());
-    	strcat(shmemData->path,uid_str);
-	mode = 0700;
-    } 
+    sprintf(uid_str, "-%u",getuid());
+    strcat(shmemData->path,uid_str);
+    int mode = 0600;
+
     shmemData->fd = open(shmemData->path, 
 		O_CREAT|O_RDWR|O_EXCL|O_APPEND|O_EXLOCK, mode);
-    if (shmemData->fd  < 0) {
-	needInit = false;
-	shmemData->fd = open(shmemData->path,O_RDWR|O_EXLOCK, mode);
-    }  else {
+    if (shmemData->fd >= 0) {
 	char *buf;
 	int len = size+RESERVED_OFFSET;
+	int ret;
 
 	buf = (char *)calloc(1,len);
 	if (!buf) {
@@ -289,8 +356,22 @@ SHMem::initSegment(const char *name, int
 	    delete shmemData;
 	    return NULL;
 	}
-	write(shmemData->fd,buf,len);
+	ret = write(shmemData->fd,buf,len);
+	if (ret != len) {
+	    unlink(shmemData->path);
+#ifdef FULL_CLEANUP
+	    flock(shmemData->fd, LOCK_UN);
+#endif
+	    delete shmemData;
+	    return NULL;
+	}
+	
 	free(buf);
+    } else if (errno == EEXIST) {
+	needInit = false;
+
+	shmemData->fd = safe_open(shmemData->path,O_RDWR|O_EXLOCK, mode,
+				  size+RESERVED_OFFSET);
     }
     if (shmemData->fd < 0) {
 	delete shmemData;