diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 025a37bc26..dbdb9065dc 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -819,7 +819,6 @@ static int rename_netif(UdevEvent *event) { static int update_devnode(UdevEvent *event) { sd_device *dev = event->dev; - bool apply; int r; r = sd_device_get_devnum(dev, NULL); @@ -834,17 +833,13 @@ static int update_devnode(UdevEvent *event) { if (!uid_is_valid(event->uid)) { r = device_get_devnode_uid(dev, &event->uid); - if (r == -ENOENT) - event->uid = 0; - else if (r < 0) + if (r < 0 && r != -ENOENT) return log_device_error_errno(dev, r, "Failed to get devnode UID: %m"); } if (!gid_is_valid(event->gid)) { r = device_get_devnode_gid(dev, &event->gid); - if (r == -ENOENT) - event->gid = 0; - else if (r < 0) + if (r < 0 && r != -ENOENT) return log_device_error_errno(dev, r, "Failed to get devnode GID: %m"); } @@ -852,21 +847,14 @@ static int update_devnode(UdevEvent *event) { r = device_get_devnode_mode(dev, &event->mode); if (r < 0 && r != -ENOENT) return log_device_error_errno(dev, r, "Failed to get devnode mode: %m"); - if (r == -ENOENT) { - if (event->gid > 0) - /* default 0660 if a group is assigned */ - event->mode = 0660; - else - /* default 0600 */ - event->mode = 0600; - } } + if (event->mode == MODE_INVALID && gid_is_valid(event->gid) && event->gid > 0) + /* If group is set, but mode is not set, "upgrade" mode for the group. */ + event->mode = 0660; - apply = device_for_action(dev, DEVICE_ACTION_ADD) || - uid_is_valid(event->uid) || - gid_is_valid(event->gid) || - event->mode != MODE_INVALID; - return udev_node_add(dev, apply, event->mode, event->uid, event->gid, event->seclabel_list); + bool apply_mac = device_for_action(dev, DEVICE_ACTION_ADD); + + return udev_node_add(dev, apply_mac, event->mode, event->uid, event->gid, event->seclabel_list); } static void event_execute_rules_on_remove( diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 7d25478577..7e3447f7fa 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -26,6 +26,7 @@ #include "string-util.h" #include "strxcpyx.h" #include "udev-node.h" +#include "user-util.h" static int node_symlink(sd_device *dev, const char *node, const char *slink) { _cleanup_free_ char *slink_dirname = NULL, *target = NULL; @@ -270,13 +271,14 @@ int udev_node_update_old_links(sd_device *dev, sd_device *dev_old) { return 0; } -static int node_permissions_apply(sd_device *dev, bool apply, +static int node_permissions_apply(sd_device *dev, bool apply_mac, mode_t mode, uid_t uid, gid_t gid, OrderedHashmap *seclabel_list) { const char *devnode, *subsystem, *id_filename = NULL; struct stat stats; dev_t devnum; - int r = 0; + bool apply_mode, apply_uid, apply_gid; + int r; assert(dev); @@ -297,23 +299,29 @@ static int node_permissions_apply(sd_device *dev, bool apply, mode |= S_IFCHR; if (lstat(devnode, &stats) < 0) - return log_device_debug_errno(dev, errno, "cannot stat() node '%s' (%m)", devnode); + return log_device_debug_errno(dev, errno, "cannot stat() node %s: %m", devnode); - if (((stats.st_mode & S_IFMT) != (mode & S_IFMT)) || (stats.st_rdev != devnum)) - return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EEXIST), "Found node '%s' with non-matching devnum %s, skip handling", + if ((mode != MODE_INVALID && (stats.st_mode & S_IFMT) != (mode & S_IFMT)) || stats.st_rdev != devnum) + return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EEXIST), + "Found node '%s' with non-matching devnum %s, skip handling", devnode, id_filename); - if (apply) { + apply_mode = mode != MODE_INVALID && (stats.st_mode & 0777) != (mode & 0777); + apply_uid = uid_is_valid(uid) && stats.st_uid != uid; + apply_gid = gid_is_valid(gid) && stats.st_gid != gid; + + if (apply_mode || apply_uid || apply_gid || apply_mac) { bool selinux = false, smack = false; const char *name, *label; Iterator i; - if ((stats.st_mode & 0777) != (mode & 0777) || stats.st_uid != uid || stats.st_gid != gid) { + if (apply_mode || apply_uid || apply_gid) { log_device_debug(dev, "Setting permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid); r = chmod_and_chown(devnode, mode, uid, gid); if (r < 0) - log_device_warning_errno(dev, r, "Failed to set owner/mode of %s to uid=" UID_FMT ", gid=" GID_FMT ", mode=%#o: %m", devnode, uid, gid, mode); + log_device_warning_errno(dev, r, "Failed to set owner/mode of %s to uid=" UID_FMT ", gid=" GID_FMT ", mode=%#o: %m", + devnode, uid, gid, mode); } else log_device_debug(dev, "Preserve permissions of %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);