svn rev #21770: trunk/src/lib/krb5/rcache/

ghudson@MIT.EDU ghudson at MIT.EDU
Wed Jan 21 14:38:19 EST 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=21770
Commit By: ghudson
Log Message:
Patch from Love: when opening an existing replay cache, check more
thoroughly to prevent symlink attacks.



Changed Files:
U   trunk/src/lib/krb5/rcache/rc_io.c
Modified: trunk/src/lib/krb5/rcache/rc_io.c
===================================================================
--- trunk/src/lib/krb5/rcache/rc_io.c	2009-01-21 19:16:22 UTC (rev 21769)
+++ trunk/src/lib/krb5/rcache/rc_io.c	2009-01-21 19:38:12 UTC (rev 21770)
@@ -223,7 +223,7 @@
     krb5_error_code retval = 0;
     int do_not_unlink = 1;
 #ifndef NO_USERID
-    struct stat statb;
+    struct stat sb1, sb2;
 #endif
     char *dir;
     size_t dirlen;
@@ -239,24 +239,50 @@
 
 #ifdef NO_USERID
     d->fd = THREEPARAMOPEN(d->fn, O_RDWR | O_BINARY, 0600);
+    if (d->fd == -1) {
+        retval = rc_map_errno(context, errno, d->fn, "open");
+        goto cleanup;
+    }
 #else
-    if ((d->fd = stat(d->fn, &statb)) != -1) {
-        uid_t me;
-
-        me = geteuid();
-        /* must be owned by this user, to prevent some security problems with
-         * other users modifying replay cache stufff */
-        if ((statb.st_uid != me) || ((statb.st_mode & S_IFMT) != S_IFREG)) {
-            FREE(d->fn);
-            return KRB5_RC_IO_PERM;
-        }
-        d->fd = THREEPARAMOPEN(d->fn, O_RDWR | O_BINARY, 0600);
+    d->fd = -1;
+    retval = lstat(d->fn, &sb1);
+    if (retval != 0) {
+        retval = rc_map_errno(context, errno, d->fn, "lstat");
+        goto cleanup;
     }
-#endif
-    if (d->fd == -1) {
+    d->fd = THREEPARAMOPEN(d->fn, O_RDWR | O_BINARY, 0600);
+    if (d->fd < 0) {
         retval = rc_map_errno(context, errno, d->fn, "open");
         goto cleanup;
     }
+    retval = fstat(d->fd, &sb2);
+    if (retval < 0) {
+        retval = rc_map_errno(context, errno, d->fn, "fstat");
+        goto cleanup;
+    }
+    /* check if someone was playing with symlinks */
+    if ((sb1.st_dev != sb2.st_dev || sb1.st_ino != sb2.st_ino)
+        || (sb1.st_mode & S_IFMT) != S_IFREG)
+        {
+            retval = KRB5_RC_IO_PERM;
+            krb5_set_error_message(context, retval,
+                                   "rcache not a file %s", d->fn);
+            goto cleanup;
+        }
+    /* check that non other can read/write/execute the file */
+    if (sb1.st_mode & 077) {
+        krb5_set_error_message(context, retval, "Insecure file mode "
+                               "for replay cache file %s", d->fn);
+        return KRB5_RC_IO_UNKNOWN;
+    }
+    /* owned by me */
+    if (sb1.st_uid != geteuid()) {
+        retval = KRB5_RC_IO_PERM;
+        krb5_set_error_message(context, retval, "rcache not owned by %d",
+                               (int)geteuid());
+        goto cleanup;
+    }
+#endif
     set_cloexec_fd(d->fd);
 
     do_not_unlink = 0;




More information about the cvs-krb5 mailing list