X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=udev%2Fudev-node.c;h=44d3686db61a75f37d6994c2f98377644b5db039;hb=c2e63452dda721bb7f127adefdfe444153a9bdca;hp=ab4e932288979f0cbd718d20603944edd0c25fd1;hpb=4ec9c3e79771aa95586390cecff4218cc8938160;p=elogind.git diff --git a/udev/udev-node.c b/udev/udev-node.c index ab4e93228..44d3686db 100644 --- a/udev/udev-node.c +++ b/udev/udev-node.c @@ -52,7 +52,9 @@ int udev_node_mknod(struct udev_device *dev, const char *file, mode_t mode, uid_ if (lstat(file, &stats) == 0) { if (((stats.st_mode & S_IFMT) == (mode & S_IFMT)) && (stats.st_rdev == devnum)) { info(udev, "preserve file '%s', because it has correct dev_t\n", file); - if (stats.st_mode != mode || stats.st_uid != uid || stats.st_gid != gid) { + if ((stats.st_mode & 0777) != (mode & 0777) || stats.st_uid != uid || stats.st_gid != gid) { + /* preserve 'sticky' bit, if already set */ + mode |= stats.st_mode & 01000; info(udev, "set permissions %s, %#o, uid=%u, gid=%u\n", file, mode, uid, gid); chmod(file, mode); chown(file, uid, gid); @@ -96,7 +98,7 @@ int udev_node_mknod(struct udev_device *dev, const char *file, mode_t mode, uid_ } else { info(udev, "mknod '%s' %u:%u %#o\n", file, major(devnum), minor(devnum), mode); do { - err = util_create_path(udev, file); + err = util_create_path_selinux(udev, file); if (err != 0 && err != -ENOENT) break; udev_selinux_setfscreatecon(udev, file, mode); @@ -105,7 +107,7 @@ int udev_node_mknod(struct udev_device *dev, const char *file, mode_t mode, uid_ err = -errno; udev_selinux_resetfscreatecon(udev); } while (err == -ENOENT); - if (err != 0) + if (err != 0 && err != -EEXIST) err(udev, "mknod '%s' %u:%u %#o' failed: %m\n", file, major(devnum), minor(devnum), mode); info(udev, "set permissions '%s' %#o uid=%u gid=%u\n", file, mode, uid, gid); chmod(file, mode); @@ -184,7 +186,7 @@ static int node_symlink(struct udev *udev, const char *node, const char *slink) } else { info(udev, "creating symlink '%s' to '%s'\n", slink, target); do { - err = util_create_path(udev, slink); + err = util_create_path_selinux(udev, slink); if (err != 0 && err != -ENOENT) break; udev_selinux_setfscreatecon(udev, slink, S_IFLNK); @@ -201,7 +203,7 @@ static int node_symlink(struct udev *udev, const char *node, const char *slink) util_strscpyl(slink_tmp, sizeof(slink_tmp), slink, TMP_FILE_EXT, NULL); unlink(slink_tmp); do { - err = util_create_path(udev, slink_tmp); + err = util_create_path_selinux(udev, slink_tmp); if (err != 0 && err != -ENOENT) break; udev_selinux_setfscreatecon(udev, slink_tmp, S_IFLNK); @@ -386,7 +388,7 @@ int udev_node_add(struct udev_device *dev, mode_t mode, uid_t uid, gid_t gid) /* create/update symlinks, add symlinks to name index */ udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) { - if (udev_list_entry_get_flags(list_entry)) + if (udev_list_entry_get_num(list_entry)) /* simple unmanaged link name */ node_symlink(udev, udev_device_get_devnode(dev), udev_list_entry_get_name(list_entry)); else @@ -414,15 +416,19 @@ int udev_node_remove(struct udev_device *dev) if (devnode == NULL) goto out; - if (stat(devnode, &stats) != 0) { - info(udev, "device node '%s' not found\n", devnode); - goto out; - } + if (stat(devnode, &stats) == 0) { + if (stats.st_rdev != udev_device_get_devnum(dev)) { + info(udev, "device node '%s' points to a different device, skip removal\n", devnode); + err = -1; + goto out; + } - if (stats.st_rdev != udev_device_get_devnum(dev)) { - info(udev, "device node '%s' points to a different device, skip removal\n", devnode); - err = -1; - goto out; + if (stats.st_mode & 01000) { + info(udev, "device node '%s' has sticky bit set, skip removal\n", devnode); + goto out; + } + } else { + info(udev, "device node '%s' not found\n", devnode); } dev_check = udev_device_new_from_syspath(udev, udev_device_get_syspath(dev));