|
|
78b7b2 |
Index: src/coolkey/machdep.cpp
|
|
|
78b7b2 |
===================================================================
|
|
|
78b7b2 |
RCS file: /cvs/dirsec/coolkey/src/coolkey/machdep.cpp,v
|
|
|
78b7b2 |
retrieving revision 1.4
|
|
|
78b7b2 |
diff -u -r1.4 machdep.cpp
|
|
|
78b7b2 |
--- src/coolkey/machdep.cpp 14 Feb 2007 00:46:28 -0000 1.4
|
|
|
78b7b2 |
+++ src/coolkey/machdep.cpp 15 Aug 2007 01:41:11 -0000
|
|
|
78b7b2 |
@@ -185,12 +185,20 @@
|
|
|
78b7b2 |
#define MAP_INHERIT 0
|
|
|
78b7b2 |
#endif
|
|
|
78b7b2 |
|
|
|
78b7b2 |
+#ifndef BASEPATH
|
|
|
78b7b2 |
+#ifdef MAC
|
|
|
78b7b2 |
+#define BASEPATH "/var"
|
|
|
78b7b2 |
+#else
|
|
|
78b7b2 |
+#define BASEPATH "/var/cache"
|
|
|
78b7b2 |
+#endif
|
|
|
78b7b2 |
+#endif
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
#ifdef FULL_CLEANUP
|
|
|
78b7b2 |
#define RESERVED_OFFSET 256
|
|
|
78b7b2 |
-#define MEMSEGPATH "/tmp/.pk11ipc"
|
|
|
78b7b2 |
+#define MEMSEGPATH BASEPATH"/coolkey-lock"
|
|
|
78b7b2 |
#else
|
|
|
78b7b2 |
#define RESERVED_OFFSET 0
|
|
|
78b7b2 |
-#define MEMSEGPATH "/tmp/.pk11ipc1"
|
|
|
78b7b2 |
+#define MEMSEGPATH BASEPATH"/coolkey"
|
|
|
78b7b2 |
#endif
|
|
|
78b7b2 |
|
|
|
78b7b2 |
struct SHMemData {
|
|
|
78b7b2 |
@@ -208,11 +216,6 @@
|
|
|
78b7b2 |
#ifdef FULL_CLEANUP
|
|
|
78b7b2 |
flock(fd,LOCK_EX);
|
|
|
78b7b2 |
unsigned long ref = --(*(unsigned long *)addr);
|
|
|
78b7b2 |
-#ifdef notdef
|
|
|
78b7b2 |
- if (ref == 0) {
|
|
|
78b7b2 |
- unlink(path);
|
|
|
78b7b2 |
- }
|
|
|
78b7b2 |
-#endif
|
|
|
78b7b2 |
flock(fd, LOCK_UN);
|
|
|
78b7b2 |
#endif
|
|
|
78b7b2 |
munmap(addr,size+RESERVED_OFFSET);
|
|
|
78b7b2 |
@@ -225,6 +228,73 @@
|
|
|
78b7b2 |
}
|
|
|
78b7b2 |
}
|
|
|
78b7b2 |
|
|
|
78b7b2 |
+/*
|
|
|
78b7b2 |
+ * The cache directory is shared and accessible by anyone, make
|
|
|
78b7b2 |
+ * sure the cache file we are opening is really a valid cache file.
|
|
|
78b7b2 |
+ */
|
|
|
78b7b2 |
+int safe_open(char *path, int flags, int mode, int size)
|
|
|
78b7b2 |
+{
|
|
|
78b7b2 |
+ struct stat buf;
|
|
|
78b7b2 |
+ int fd, ret;
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ fd = open (path, flags|O_NOFOLLOW, mode);
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ if (fd < 0) {
|
|
|
78b7b2 |
+ return fd;
|
|
|
78b7b2 |
+ }
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ ret = fstat(fd, &buf;;
|
|
|
78b7b2 |
+ if (ret < 0) {
|
|
|
78b7b2 |
+ close (fd);
|
|
|
78b7b2 |
+ return ret;
|
|
|
78b7b2 |
+ }
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ /* our cache files are pretty specific, make sure we are looking
|
|
|
78b7b2 |
+ * at the correct one */
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ /* first, we should own the file ourselves, don't open a file
|
|
|
78b7b2 |
+ * that someone else wanted us to see. */
|
|
|
78b7b2 |
+ if (buf.st_uid != getuid()) {
|
|
|
78b7b2 |
+ close(fd);
|
|
|
78b7b2 |
+ errno = EACCES;
|
|
|
78b7b2 |
+ return -1;
|
|
|
78b7b2 |
+ }
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ /* next, there should only be one link in this file. Don't
|
|
|
78b7b2 |
+ * use this code to trash another file */
|
|
|
78b7b2 |
+ if (buf.st_nlink != 1) {
|
|
|
78b7b2 |
+ close(fd);
|
|
|
78b7b2 |
+ errno = EMLINK;
|
|
|
78b7b2 |
+ return -1;
|
|
|
78b7b2 |
+ }
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ /* next, This better be a regular file */
|
|
|
78b7b2 |
+ if (!S_ISREG(buf.st_mode)) {
|
|
|
78b7b2 |
+ close(fd);
|
|
|
78b7b2 |
+ errno = EACCES;
|
|
|
78b7b2 |
+ return -1;
|
|
|
78b7b2 |
+ }
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ /* if the permissions don't match, something is wrong */
|
|
|
78b7b2 |
+ if ((buf.st_mode & 03777) != mode) {
|
|
|
78b7b2 |
+ close(fd);
|
|
|
78b7b2 |
+ errno = EACCES;
|
|
|
78b7b2 |
+ return -1;
|
|
|
78b7b2 |
+ }
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ /* finally the file should be the correct size. This
|
|
|
78b7b2 |
+ * check isn't so much to protect from an attack, as it is to
|
|
|
78b7b2 |
+ * detect a corrupted cache file */
|
|
|
78b7b2 |
+ if (buf.st_size != size) {
|
|
|
78b7b2 |
+ close(fd);
|
|
|
78b7b2 |
+ errno = EACCES;
|
|
|
78b7b2 |
+ return -1;
|
|
|
78b7b2 |
+ }
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ /* OK, the file checked out, ok to continue */
|
|
|
78b7b2 |
+ return fd;
|
|
|
78b7b2 |
+}
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
SHMem::SHMem(): shmemData(0) {}
|
|
|
78b7b2 |
|
|
|
78b7b2 |
SHMem *
|
|
|
78b7b2 |
@@ -248,7 +318,7 @@
|
|
|
78b7b2 |
return NULL;
|
|
|
78b7b2 |
}
|
|
|
78b7b2 |
int mask = umask(0);
|
|
|
78b7b2 |
- int ret = mkdir (MEMSEGPATH, 0777);
|
|
|
78b7b2 |
+ int ret = mkdir (MEMSEGPATH, 01777);
|
|
|
78b7b2 |
umask(mask);
|
|
|
78b7b2 |
if ((ret == -1) && (errno != EEXIST)) {
|
|
|
78b7b2 |
delete shmemData;
|
|
|
78b7b2 |
@@ -264,21 +334,16 @@
|
|
|
78b7b2 |
shmemData->path[sizeof(MEMSEGPATH)-1] = '/';
|
|
|
78b7b2 |
strcpy(&shmemData->path[sizeof(MEMSEGPATH)],name);
|
|
|
78b7b2 |
|
|
|
78b7b2 |
- int mode = 0777;
|
|
|
78b7b2 |
- if (strcmp(name,"token_names") != 0) {
|
|
|
78b7b2 |
- /* each user gets his own uid array */
|
|
|
78b7b2 |
- sprintf(uid_str, "-%u",getuid());
|
|
|
78b7b2 |
- strcat(shmemData->path,uid_str);
|
|
|
78b7b2 |
- mode = 0700;
|
|
|
78b7b2 |
- }
|
|
|
78b7b2 |
+ sprintf(uid_str, "-%u",getuid());
|
|
|
78b7b2 |
+ strcat(shmemData->path,uid_str);
|
|
|
78b7b2 |
+ int mode = 0600;
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
shmemData->fd = open(shmemData->path,
|
|
|
78b7b2 |
O_CREAT|O_RDWR|O_EXCL|O_APPEND|O_EXLOCK, mode);
|
|
|
78b7b2 |
- if (shmemData->fd < 0) {
|
|
|
78b7b2 |
- needInit = false;
|
|
|
78b7b2 |
- shmemData->fd = open(shmemData->path,O_RDWR|O_EXLOCK, mode);
|
|
|
78b7b2 |
- } else {
|
|
|
78b7b2 |
+ if (shmemData->fd >= 0) {
|
|
|
78b7b2 |
char *buf;
|
|
|
78b7b2 |
int len = size+RESERVED_OFFSET;
|
|
|
78b7b2 |
+ int ret;
|
|
|
78b7b2 |
|
|
|
78b7b2 |
buf = (char *)calloc(1,len);
|
|
|
78b7b2 |
if (!buf) {
|
|
|
78b7b2 |
@@ -289,8 +354,22 @@
|
|
|
78b7b2 |
delete shmemData;
|
|
|
78b7b2 |
return NULL;
|
|
|
78b7b2 |
}
|
|
|
78b7b2 |
- write(shmemData->fd,buf,len);
|
|
|
78b7b2 |
+ ret = write(shmemData->fd,buf,len);
|
|
|
78b7b2 |
+ if (ret != len) {
|
|
|
78b7b2 |
+ unlink(shmemData->path);
|
|
|
78b7b2 |
+#ifdef FULL_CLEANUP
|
|
|
78b7b2 |
+ flock(shmemData->fd, LOCK_UN);
|
|
|
78b7b2 |
+#endif
|
|
|
78b7b2 |
+ delete shmemData;
|
|
|
78b7b2 |
+ return NULL;
|
|
|
78b7b2 |
+ }
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
free(buf);
|
|
|
78b7b2 |
+ } else if (errno == EEXIST) {
|
|
|
78b7b2 |
+ needInit = false;
|
|
|
78b7b2 |
+
|
|
|
78b7b2 |
+ shmemData->fd = safe_open(shmemData->path,O_RDWR|O_EXLOCK, mode,
|
|
|
78b7b2 |
+ size+RESERVED_OFFSET);
|
|
|
78b7b2 |
}
|
|
|
78b7b2 |
if (shmemData->fd < 0) {
|
|
|
78b7b2 |
delete shmemData;
|