Blame SOURCES/coolkey-cache-dir-move.patch

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;