|
1 Upstream fixes already included in the latest updates to coolkey v1.1.0 |
|
2 |
|
3 Addresses cache directory, memory leak and compiler issues. |
|
4 Added MAP_FILE definiton for Solaris. |
|
5 |
|
6 --- ORIGINAL/./src/coolkey/machdep.cpp 2016-06-24 16:07:19.527102431 -0400 |
|
7 +++ ././src/coolkey/machdep.cpp 2016-06-27 13:36:57.607064368 -0400 |
|
8 @@ -33,8 +33,18 @@ |
|
9 #include <sys/stat.h> |
|
10 #include <sys/mman.h> |
|
11 #include <pthread.h> |
|
12 +#include <string.h> |
|
13 +#include <stdlib.h> |
|
14 #endif |
|
15 |
|
16 +bool OSLock::needThread = 0; |
|
17 + |
|
18 +// Solaris specific - MAP_FILE needs to be defined |
|
19 +#ifndef MAP_FILE |
|
20 +#define MAP_FILE 0 |
|
21 +#endif |
|
22 + |
|
23 + |
|
24 #ifdef _WIN32 |
|
25 // |
|
26 // Windows functions to grab a named shared memory segment of a specific size, |
|
27 @@ -121,6 +131,10 @@ |
|
28 |
|
29 OSLock::OSLock(bool exceptionAllowed) |
|
30 { |
|
31 + if (!needThread) { |
|
32 + lockData = NULL; |
|
33 + return; |
|
34 + } |
|
35 lockData = new OSLockData; |
|
36 if (lockData) { |
|
37 InitializeCriticalSection(&lockData->mutex); |
|
38 @@ -185,12 +199,20 @@ |
|
39 #define MAP_INHERIT 0 |
|
40 #endif |
|
41 |
|
42 +#ifndef BASEPATH |
|
43 +#ifdef MAC |
|
44 +#define BASEPATH "/var" |
|
45 +#else |
|
46 +#define BASEPATH "/var/cache" |
|
47 +#endif |
|
48 +#endif |
|
49 + |
|
50 #ifdef FULL_CLEANUP |
|
51 #define RESERVED_OFFSET 256 |
|
52 -#define MEMSEGPATH "/tmp/.pk11ipc" |
|
53 +#define MEMSEGPATH BASEPATH"/coolkey-lock" |
|
54 #else |
|
55 #define RESERVED_OFFSET 0 |
|
56 -#define MEMSEGPATH "/tmp/.pk11ipc1" |
|
57 +#define MEMSEGPATH BASEPATH"/coolkey" |
|
58 #endif |
|
59 |
|
60 struct SHMemData { |
|
61 @@ -208,11 +230,6 @@ |
|
62 #ifdef FULL_CLEANUP |
|
63 flock(fd,LOCK_EX); |
|
64 unsigned long ref = --(*(unsigned long *)addr); |
|
65 -#ifdef notdef |
|
66 - if (ref == 0) { |
|
67 - unlink(path); |
|
68 - } |
|
69 -#endif |
|
70 flock(fd, LOCK_UN); |
|
71 #endif |
|
72 munmap(addr,size+RESERVED_OFFSET); |
|
73 @@ -225,6 +242,73 @@ |
|
74 } |
|
75 } |
|
76 |
|
77 +/* |
|
78 + * The cache directory is shared and accessible by anyone, make |
|
79 + * sure the cache file we are opening is really a valid cache file. |
|
80 + */ |
|
81 +int safe_open(char *path, int flags, int mode, int size) |
|
82 +{ |
|
83 + struct stat buf; |
|
84 + int fd, ret; |
|
85 + |
|
86 + fd = open (path, flags|O_NOFOLLOW, mode); |
|
87 + |
|
88 + if (fd < 0) { |
|
89 + return fd; |
|
90 + } |
|
91 + |
|
92 + ret = fstat(fd, &buf); |
|
93 + if (ret < 0) { |
|
94 + close (fd); |
|
95 + return ret; |
|
96 + } |
|
97 + |
|
98 + /* our cache files are pretty specific, make sure we are looking |
|
99 + * at the correct one */ |
|
100 + |
|
101 + /* first, we should own the file ourselves, don't open a file |
|
102 + * that someone else wanted us to see. */ |
|
103 + if (buf.st_uid != getuid()) { |
|
104 + close(fd); |
|
105 + errno = EACCES; |
|
106 + return -1; |
|
107 + } |
|
108 + |
|
109 + /* next, there should only be one link in this file. Don't |
|
110 + * use this code to trash another file */ |
|
111 + if (buf.st_nlink != 1) { |
|
112 + close(fd); |
|
113 + errno = EMLINK; |
|
114 + return -1; |
|
115 + } |
|
116 + |
|
117 + /* next, This better be a regular file */ |
|
118 + if (!S_ISREG(buf.st_mode)) { |
|
119 + close(fd); |
|
120 + errno = EACCES; |
|
121 + return -1; |
|
122 + } |
|
123 + |
|
124 + /* if the permissions don't match, something is wrong */ |
|
125 + if ((buf.st_mode & 03777) != mode) { |
|
126 + close(fd); |
|
127 + errno = EACCES; |
|
128 + return -1; |
|
129 + } |
|
130 + |
|
131 + /* finally the file should be the correct size. This |
|
132 + * check isn't so much to protect from an attack, as it is to |
|
133 + * detect a corrupted cache file */ |
|
134 + if (buf.st_size != size) { |
|
135 + close(fd); |
|
136 + errno = EACCES; |
|
137 + return -1; |
|
138 + } |
|
139 + |
|
140 + /* OK, the file checked out, ok to continue */ |
|
141 + return fd; |
|
142 +} |
|
143 + |
|
144 SHMem::SHMem(): shmemData(0) {} |
|
145 |
|
146 SHMem * |
|
147 @@ -248,7 +332,7 @@ |
|
148 return NULL; |
|
149 } |
|
150 int mask = umask(0); |
|
151 - int ret = mkdir (MEMSEGPATH, 0777); |
|
152 + int ret = mkdir (MEMSEGPATH, 01777); |
|
153 umask(mask); |
|
154 if ((ret == -1) && (errno != EEXIST)) { |
|
155 delete shmemData; |
|
156 @@ -264,21 +348,16 @@ |
|
157 shmemData->path[sizeof(MEMSEGPATH)-1] = '/'; |
|
158 strcpy(&shmemData->path[sizeof(MEMSEGPATH)],name); |
|
159 |
|
160 - int mode = 0777; |
|
161 - if (strcmp(name,"token_names") != 0) { |
|
162 - /* each user gets his own uid array */ |
|
163 - sprintf(uid_str, "-%u",getuid()); |
|
164 - strcat(shmemData->path,uid_str); |
|
165 - mode = 0700; |
|
166 - } |
|
167 + sprintf(uid_str, "-%u",getuid()); |
|
168 + strcat(shmemData->path,uid_str); |
|
169 + int mode = 0600; |
|
170 + |
|
171 shmemData->fd = open(shmemData->path, |
|
172 O_CREAT|O_RDWR|O_EXCL|O_APPEND|O_EXLOCK, mode); |
|
173 - if (shmemData->fd < 0) { |
|
174 - needInit = false; |
|
175 - shmemData->fd = open(shmemData->path,O_RDWR|O_EXLOCK, mode); |
|
176 - } else { |
|
177 + if (shmemData->fd >= 0) { |
|
178 char *buf; |
|
179 int len = size+RESERVED_OFFSET; |
|
180 + int ret; |
|
181 |
|
182 buf = (char *)calloc(1,len); |
|
183 if (!buf) { |
|
184 @@ -289,8 +368,23 @@ |
|
185 delete shmemData; |
|
186 return NULL; |
|
187 } |
|
188 - write(shmemData->fd,buf,len); |
|
189 + ret = write(shmemData->fd,buf,len); |
|
190 + if (ret != len) { |
|
191 + unlink(shmemData->path); |
|
192 +#ifdef FULL_CLEANUP |
|
193 + flock(shmemData->fd, LOCK_UN); |
|
194 +#endif |
|
195 + free(buf); |
|
196 + delete shmemData; |
|
197 + return NULL; |
|
198 + } |
|
199 + |
|
200 free(buf); |
|
201 + } else if (errno == EEXIST) { |
|
202 + needInit = false; |
|
203 + |
|
204 + shmemData->fd = safe_open(shmemData->path,O_RDWR|O_EXLOCK, mode, |
|
205 + size+RESERVED_OFFSET); |
|
206 } |
|
207 if (shmemData->fd < 0) { |
|
208 delete shmemData; |
|
209 @@ -358,6 +452,9 @@ |
|
210 int rc; |
|
211 |
|
212 lockData = NULL; |
|
213 + if (!needThread) { |
|
214 + return; |
|
215 + } |
|
216 #ifdef MAC |
|
217 if (!OSLock_attr_init) { |
|
218 rc = pthread_mutexattr_init(&OSLock_attr); |