1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-23 21:35:11 +03:00

udev-node: split out permission handling from udev_node_add()

And then merge udev_node_add() and udev_node_update_old_links().
This commit is contained in:
Yu Watanabe 2021-09-01 09:24:15 +09:00
parent b881ce16b9
commit 2f48561e0d
3 changed files with 106 additions and 119 deletions

View File

@ -893,9 +893,6 @@ static int update_devnode(UdevEvent *event) {
if (r < 0)
return log_device_error_errno(dev, r, "Failed to get devnum: %m");
/* remove/update possible left-over symlinks from old database entry */
(void) udev_node_update_old_links(dev, event->dev_db_clone);
if (!uid_is_valid(event->uid)) {
r = device_get_devnode_uid(dev, &event->uid);
if (r < 0 && r != -ENOENT)
@ -919,7 +916,11 @@ static int update_devnode(UdevEvent *event) {
bool apply_mac = device_for_action(dev, SD_DEVICE_ADD);
return udev_node_add(dev, apply_mac, event->mode, event->uid, event->gid, event->seclabel_list);
r = udev_node_apply_permissions(dev, apply_mac, event->mode, event->uid, event->gid, event->seclabel_list);
if (r < 0)
return log_device_error_errno(dev, r, "Failed to apply devnode permissions: %m");
return udev_node_update(dev, event->dev_db_clone);
}
static int event_execute_rules_on_remove(

View File

@ -356,45 +356,117 @@ static int link_update(sd_device *dev, const char *slink_in, bool add) {
return i < LINK_UPDATE_MAX_RETRIES ? 0 : -ELOOP;
}
int udev_node_update_old_links(sd_device *dev, sd_device *dev_old) {
const char *name;
static int device_get_devpath_by_devnum(sd_device *dev, char **ret) {
const char *subsystem;
dev_t devnum;
int r;
assert(dev);
assert(ret);
r = sd_device_get_subsystem(dev, &subsystem);
if (r < 0)
return r;
r = sd_device_get_devnum(dev, &devnum);
if (r < 0)
return r;
return device_path_make_major_minor(streq(subsystem, "block") ? S_IFBLK : S_IFCHR, devnum, ret);
}
int udev_node_update(sd_device *dev, sd_device *dev_old) {
_cleanup_free_ char *filename = NULL;
const char *devnode, *devlink;
int r;
assert(dev);
assert(dev_old);
r = sd_device_get_devname(dev, &devnode);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get devnode: %m");
if (DEBUG_LOGGING) {
const char *id = NULL;
(void) device_get_device_id(dev, &id);
log_device_debug(dev, "Handling device node '%s', devnum=%s", devnode, strna(id));
}
/* update possible left-over symlinks */
FOREACH_DEVICE_DEVLINK(dev_old, name) {
const char *name_current;
bool found = false;
FOREACH_DEVICE_DEVLINK(dev_old, devlink) {
/* check if old link name still belongs to this device */
FOREACH_DEVICE_DEVLINK(dev, name_current)
if (streq(name, name_current)) {
found = true;
break;
}
if (found)
if (device_has_devlink(dev, devlink))
continue;
log_device_debug(dev,
"Updating old device symlink '%s', which is no longer belonging to this device.",
name);
"Removing/updating old device symlink '%s', which is no longer belonging to this device.",
devlink);
r = link_update(dev, name, false);
r = link_update(dev, devlink, /* add = */ false);
if (r < 0)
log_device_warning_errno(dev, r,
"Failed to update device symlink '%s', ignoring: %m",
name);
"Failed to remove/update device symlink '%s', ignoring: %m",
devlink);
}
/* create/update symlinks, add symlinks to name index */
FOREACH_DEVICE_DEVLINK(dev, devlink) {
r = link_update(dev, devlink, /* add = */ true);
if (r < 0)
log_device_warning_errno(dev, r,
"Failed to create/update device symlink '%s', ignoring: %m",
devlink);
}
r = device_get_devpath_by_devnum(dev, &filename);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get device path: %m");
/* always add /dev/{block,char}/$major:$minor */
r = node_symlink(dev, devnode, filename);
if (r < 0)
return log_device_warning_errno(dev, r, "Failed to create device symlink '%s': %m", filename);
return 0;
}
static int node_permissions_apply(sd_device *dev, bool apply_mac,
mode_t mode, uid_t uid, gid_t gid,
OrderedHashmap *seclabel_list) {
int udev_node_remove(sd_device *dev) {
_cleanup_free_ char *filename = NULL;
const char *devlink;
int r;
assert(dev);
/* remove/update symlinks, remove symlinks from name index */
FOREACH_DEVICE_DEVLINK(dev, devlink) {
r = link_update(dev, devlink, /* add = */ false);
if (r < 0)
log_device_warning_errno(dev, r,
"Failed to remove/update device symlink '%s', ignoring: %m",
devlink);
}
r = device_get_devpath_by_devnum(dev, &filename);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get device path: %m");
/* remove /dev/{block,char}/$major:$minor */
if (unlink(filename) < 0 && errno != ENOENT)
return log_device_debug_errno(dev, errno, "Failed to remove '%s': %m", filename);
return 0;
}
int udev_node_apply_permissions(
sd_device *dev,
bool apply_mac,
mode_t mode,
uid_t uid,
gid_t gid,
OrderedHashmap *seclabel_list) {
const char *devnode, *subsystem, *id = NULL;
bool apply_mode, apply_uid, apply_gid;
_cleanup_close_ int node_fd = -1;
@ -511,95 +583,5 @@ static int node_permissions_apply(sd_device *dev, bool apply_mac,
if (r < 0)
log_device_debug_errno(dev, r, "Failed to adjust timestamp of node %s: %m", devnode);
return r;
}
static int xsprintf_dev_num_path_from_sd_device(sd_device *dev, char **ret) {
const char *subsystem;
dev_t devnum;
int r;
assert(ret);
r = sd_device_get_subsystem(dev, &subsystem);
if (r < 0)
return r;
r = sd_device_get_devnum(dev, &devnum);
if (r < 0)
return r;
return device_path_make_major_minor(streq(subsystem, "block") ? S_IFBLK : S_IFCHR, devnum, ret);
}
int udev_node_add(sd_device *dev, bool apply,
mode_t mode, uid_t uid, gid_t gid,
OrderedHashmap *seclabel_list) {
const char *devnode, *devlink;
_cleanup_free_ char *filename = NULL;
int r;
assert(dev);
r = sd_device_get_devname(dev, &devnode);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get devnode: %m");
if (DEBUG_LOGGING) {
const char *id = NULL;
(void) device_get_device_id(dev, &id);
log_device_debug(dev, "Handling device node '%s', devnum=%s", devnode, strna(id));
}
r = node_permissions_apply(dev, apply, mode, uid, gid, seclabel_list);
if (r < 0)
return r;
/* create/update symlinks, add symlinks to name index */
FOREACH_DEVICE_DEVLINK(dev, devlink) {
r = link_update(dev, devlink, true);
if (r < 0)
log_device_warning_errno(dev, r,
"Failed to update device symlink '%s', ignoring: %m",
devlink);
}
r = xsprintf_dev_num_path_from_sd_device(dev, &filename);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get device path: %m");
/* always add /dev/{block,char}/$major:$minor */
r = node_symlink(dev, devnode, filename);
if (r < 0)
return log_device_warning_errno(dev, r, "Failed to create device symlink '%s': %m", filename);
return 0;
}
int udev_node_remove(sd_device *dev) {
_cleanup_free_ char *filename = NULL;
const char *devlink;
int r;
assert(dev);
/* remove/update symlinks, remove symlinks from name index */
FOREACH_DEVICE_DEVLINK(dev, devlink) {
r = link_update(dev, devlink, false);
if (r < 0)
log_device_warning_errno(dev, r,
"Failed to update device symlink '%s', ignoring: %m",
devlink);
}
r = xsprintf_dev_num_path_from_sd_device(dev, &filename);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get device path: %m");
/* remove /dev/{block,char}/$major:$minor */
if (unlink(filename) < 0 && errno != ENOENT)
return log_device_debug_errno(dev, errno, "Failed to remove '%s': %m", filename);
return 0;
}

View File

@ -8,10 +8,14 @@
#include "hashmap.h"
int udev_node_add(sd_device *dev, bool apply,
mode_t mode, uid_t uid, gid_t gid,
OrderedHashmap *seclabel_list);
int udev_node_apply_permissions(
sd_device *dev,
bool apply_mac,
mode_t mode,
uid_t uid,
gid_t gid,
OrderedHashmap *seclabel_list);
int udev_node_remove(sd_device *dev);
int udev_node_update_old_links(sd_device *dev, sd_device *dev_old);
int udev_node_update(sd_device *dev, sd_device *dev_old);
size_t udev_node_escape_path(const char *src, char *dest, size_t size);