Re: [security] Race condition in udev

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

> More to the point, you haven't explained how to work around the fact
> that simply inverting the chmod/chown (or any variation of that) doesn't
> remove the race condition - just moves it between the user or group.

below you find a patch that should fix the specific issue - I just am
not sure that it interacts nicely with the rest of udev. Also, I haven't
tried it, not even compiled it.

Florian

diff --git a/udev/udev-node.c b/udev/udev-node.c
index 03ab0ea..d73bc6c 100644
--- a/udev/udev-node.c
+++ b/udev/udev-node.c
@@ -88,11 +88,11 @@ int udev_node_mknod(struct udev_device *dev, const char *file, dev_t devnum, mod
 			util_strscpyl(file_tmp, sizeof(file_tmp), file, TMP_FILE_EXT, NULL);
 			unlink(file_tmp);
 			udev_selinux_setfscreatecon(udev, file_tmp, mode);
-			err = mknod(file_tmp, mode, devnum);
+			err = mknod(file_tmp, 0, devnum);
 			udev_selinux_resetfscreatecon(udev);
 			if (err != 0) {
 				err(udev, "mknod(%s, %#o, %u, %u) failed: %m\n",
-				    file_tmp, mode, major(devnum), minor(devnum));
+				    file_tmp, 0, major(devnum), minor(devnum));
 				goto exit;
 			}
 			err = rename(file_tmp, file);
@@ -102,17 +102,33 @@ int udev_node_mknod(struct udev_device *dev, const char *file, dev_t devnum, mod
 			}
 		}
 	} else {
-		info(udev, "mknod(%s, %#o, (%u,%u))\n", file, mode, major(devnum), minor(devnum));
+		info(udev, "mknod(%s, %#o, (%u,%u))\n", file, 0, major(devnum), minor(devnum));
 		udev_selinux_setfscreatecon(udev, file, mode);
-		err = mknod(file, mode, devnum);
+		err = mknod(file, 0, devnum);
 		udev_selinux_resetfscreatecon(udev);
 		if (err != 0) {
-			err(udev, "mknod(%s, %#o, (%u,%u) failed: %m\n", file, mode, major(devnum), minor(devnum));
+			err(udev, "mknod(%s, %#o, (%u,%u)) failed: %m\n", file, 0, major(devnum), minor(devnum));
 			goto exit;
 		}
 	}
 
-	if (!preserve || stats.st_mode != mode) {
+	if (!preserve || stats.st_mode != mode || stats.st_uid != uid || stats.st_gid != gid) {
+		if (!preserve || stats.st_uid != uid || stats.st_gid != gid) {
+			info(udev, "chmod(%s, %#o)\n", file, 0);
+			err = chmod(file, 0);
+			if (err != 0) {
+				err(udev, "chmod(%s, %#o) failed: %m\n", file, 0);
+				goto exit;
+			}
+
+			info(udev, "chown(%s, %u, %u)\n", file, uid, gid);
+			err = chown(file, uid, gid);
+			if (err != 0) {
+				err(udev, "chown(%s, %u, %u) failed: %m\n", file, uid, gid);
+				goto exit;
+			}
+		}
+
 		info(udev, "chmod(%s, %#o)\n", file, mode);
 		err = chmod(file, mode);
 		if (err != 0) {
@@ -120,15 +136,6 @@ int udev_node_mknod(struct udev_device *dev, const char *file, dev_t devnum, mod
 			goto exit;
 		}
 	}
-
-	if (!preserve || stats.st_uid != uid || stats.st_gid != gid) {
-		info(udev, "chown(%s, %u, %u)\n", file, uid, gid);
-		err = chown(file, uid, gid);
-		if (err != 0) {
-			err(udev, "chown(%s, %u, %u) failed: %m\n", file, uid, gid);
-			goto exit;
-		}
-	}
 exit:
 	return err;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [Linux DVB]     [Asterisk Internet PBX]     [DCCP]     [Netdev]     [X.org]     [Util Linux NG]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux