|
|
4eda52 |
From a4fba2d79634d660ed2014e18cb85eea090b6413 Mon Sep 17 00:00:00 2001
|
|
|
4295f9 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
4295f9 |
Date: Wed, 1 Sep 2021 09:24:15 +0900
|
|
|
4295f9 |
Subject: [PATCH] udev-node: split out permission handling from udev_node_add()
|
|
|
4295f9 |
|
|
|
4295f9 |
And then merge udev_node_add() and udev_node_update_old_links().
|
|
|
4295f9 |
|
|
|
4295f9 |
(cherry picked from commit 2f48561e0db3cd63f65e9311b4d69282b4ac605d)
|
|
|
4295f9 |
|
|
|
4eda52 |
Related: #2005024
|
|
|
4295f9 |
---
|
|
|
4295f9 |
src/udev/udev-event.c | 9 +-
|
|
|
4295f9 |
src/udev/udev-node.c | 204 +++++++++++++++++++-----------------------
|
|
|
4295f9 |
src/udev/udev-node.h | 12 ++-
|
|
|
4295f9 |
3 files changed, 106 insertions(+), 119 deletions(-)
|
|
|
4295f9 |
|
|
|
4295f9 |
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
|
|
|
4295f9 |
index b28089be71..8b9f8aecfe 100644
|
|
|
4295f9 |
--- a/src/udev/udev-event.c
|
|
|
4295f9 |
+++ b/src/udev/udev-event.c
|
|
|
4295f9 |
@@ -895,9 +895,6 @@ static int update_devnode(UdevEvent *event) {
|
|
|
4295f9 |
if (r < 0)
|
|
|
4295f9 |
return log_device_error_errno(dev, r, "Failed to get devnum: %m");
|
|
|
4295f9 |
|
|
|
4295f9 |
- /* remove/update possible left-over symlinks from old database entry */
|
|
|
4295f9 |
- (void) udev_node_update_old_links(dev, event->dev_db_clone);
|
|
|
4295f9 |
-
|
|
|
4295f9 |
if (!uid_is_valid(event->uid)) {
|
|
|
4295f9 |
r = device_get_devnode_uid(dev, &event->uid);
|
|
|
4295f9 |
if (r < 0 && r != -ENOENT)
|
|
|
4295f9 |
@@ -921,7 +918,11 @@ static int update_devnode(UdevEvent *event) {
|
|
|
4295f9 |
|
|
|
4295f9 |
bool apply_mac = device_for_action(dev, SD_DEVICE_ADD);
|
|
|
4295f9 |
|
|
|
4295f9 |
- return udev_node_add(dev, apply_mac, event->mode, event->uid, event->gid, event->seclabel_list);
|
|
|
4295f9 |
+ r = udev_node_apply_permissions(dev, apply_mac, event->mode, event->uid, event->gid, event->seclabel_list);
|
|
|
4295f9 |
+ if (r < 0)
|
|
|
4295f9 |
+ return log_device_error_errno(dev, r, "Failed to apply devnode permissions: %m");
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ return udev_node_update(dev, event->dev_db_clone);
|
|
|
4295f9 |
}
|
|
|
4295f9 |
|
|
|
4295f9 |
static int event_execute_rules_on_remove(
|
|
|
4295f9 |
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
|
|
|
4295f9 |
index 9e52906571..7cc9ee3670 100644
|
|
|
4295f9 |
--- a/src/udev/udev-node.c
|
|
|
4295f9 |
+++ b/src/udev/udev-node.c
|
|
|
4295f9 |
@@ -356,45 +356,117 @@ static int link_update(sd_device *dev, const char *slink_in, bool add) {
|
|
|
4295f9 |
return i < LINK_UPDATE_MAX_RETRIES ? 0 : -ELOOP;
|
|
|
4295f9 |
}
|
|
|
4295f9 |
|
|
|
4295f9 |
-int udev_node_update_old_links(sd_device *dev, sd_device *dev_old) {
|
|
|
4295f9 |
- const char *name;
|
|
|
4295f9 |
+static int device_get_devpath_by_devnum(sd_device *dev, char **ret) {
|
|
|
4295f9 |
+ const char *subsystem;
|
|
|
4295f9 |
+ dev_t devnum;
|
|
|
4295f9 |
+ int r;
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ assert(dev);
|
|
|
4295f9 |
+ assert(ret);
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ r = sd_device_get_subsystem(dev, &subsystem);
|
|
|
4295f9 |
+ if (r < 0)
|
|
|
4295f9 |
+ return r;
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ r = sd_device_get_devnum(dev, &devnum);
|
|
|
4295f9 |
+ if (r < 0)
|
|
|
4295f9 |
+ return r;
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ return device_path_make_major_minor(streq(subsystem, "block") ? S_IFBLK : S_IFCHR, devnum, ret);
|
|
|
4295f9 |
+}
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+int udev_node_update(sd_device *dev, sd_device *dev_old) {
|
|
|
4295f9 |
+ _cleanup_free_ char *filename = NULL;
|
|
|
4295f9 |
+ const char *devnode, *devlink;
|
|
|
4295f9 |
int r;
|
|
|
4295f9 |
|
|
|
4295f9 |
assert(dev);
|
|
|
4295f9 |
assert(dev_old);
|
|
|
4295f9 |
|
|
|
4295f9 |
- /* update possible left-over symlinks */
|
|
|
4295f9 |
- FOREACH_DEVICE_DEVLINK(dev_old, name) {
|
|
|
4295f9 |
- const char *name_current;
|
|
|
4295f9 |
- bool found = false;
|
|
|
4295f9 |
+ r = sd_device_get_devname(dev, &devnode);
|
|
|
4295f9 |
+ if (r < 0)
|
|
|
4295f9 |
+ return log_device_debug_errno(dev, r, "Failed to get devnode: %m");
|
|
|
4295f9 |
|
|
|
4295f9 |
- /* check if old link name still belongs to this device */
|
|
|
4295f9 |
- FOREACH_DEVICE_DEVLINK(dev, name_current)
|
|
|
4295f9 |
- if (streq(name, name_current)) {
|
|
|
4295f9 |
- found = true;
|
|
|
4295f9 |
- break;
|
|
|
4295f9 |
- }
|
|
|
4295f9 |
+ if (DEBUG_LOGGING) {
|
|
|
4295f9 |
+ const char *id = NULL;
|
|
|
4295f9 |
|
|
|
4295f9 |
- if (found)
|
|
|
4295f9 |
+ (void) device_get_device_id(dev, &id;;
|
|
|
4295f9 |
+ log_device_debug(dev, "Handling device node '%s', devnum=%s", devnode, strna(id));
|
|
|
4295f9 |
+ }
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ /* update possible left-over symlinks */
|
|
|
4295f9 |
+ FOREACH_DEVICE_DEVLINK(dev_old, devlink) {
|
|
|
4295f9 |
+ /* check if old link name still belongs to this device */
|
|
|
4295f9 |
+ if (device_has_devlink(dev, devlink))
|
|
|
4295f9 |
continue;
|
|
|
4295f9 |
|
|
|
4295f9 |
log_device_debug(dev,
|
|
|
4295f9 |
- "Updating old device symlink '%s', which is no longer belonging to this device.",
|
|
|
4295f9 |
- name);
|
|
|
4295f9 |
+ "Removing/updating old device symlink '%s', which is no longer belonging to this device.",
|
|
|
4295f9 |
+ devlink);
|
|
|
4295f9 |
|
|
|
4295f9 |
- r = link_update(dev, name, false);
|
|
|
4295f9 |
+ r = link_update(dev, devlink, /* add = */ false);
|
|
|
4295f9 |
if (r < 0)
|
|
|
4295f9 |
log_device_warning_errno(dev, r,
|
|
|
4295f9 |
- "Failed to update device symlink '%s', ignoring: %m",
|
|
|
4295f9 |
- name);
|
|
|
4295f9 |
+ "Failed to remove/update device symlink '%s', ignoring: %m",
|
|
|
4295f9 |
+ devlink);
|
|
|
4295f9 |
}
|
|
|
4295f9 |
|
|
|
4295f9 |
+ /* create/update symlinks, add symlinks to name index */
|
|
|
4295f9 |
+ FOREACH_DEVICE_DEVLINK(dev, devlink) {
|
|
|
4295f9 |
+ r = link_update(dev, devlink, /* add = */ true);
|
|
|
4295f9 |
+ if (r < 0)
|
|
|
4295f9 |
+ log_device_warning_errno(dev, r,
|
|
|
4295f9 |
+ "Failed to create/update device symlink '%s', ignoring: %m",
|
|
|
4295f9 |
+ devlink);
|
|
|
4295f9 |
+ }
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ r = device_get_devpath_by_devnum(dev, &filename);
|
|
|
4295f9 |
+ if (r < 0)
|
|
|
4295f9 |
+ return log_device_debug_errno(dev, r, "Failed to get device path: %m");
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ /* always add /dev/{block,char}/$major:$minor */
|
|
|
4295f9 |
+ r = node_symlink(dev, devnode, filename);
|
|
|
4295f9 |
+ if (r < 0)
|
|
|
4295f9 |
+ return log_device_warning_errno(dev, r, "Failed to create device symlink '%s': %m", filename);
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ return 0;
|
|
|
4295f9 |
+}
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+int udev_node_remove(sd_device *dev) {
|
|
|
4295f9 |
+ _cleanup_free_ char *filename = NULL;
|
|
|
4295f9 |
+ const char *devlink;
|
|
|
4295f9 |
+ int r;
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ assert(dev);
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ /* remove/update symlinks, remove symlinks from name index */
|
|
|
4295f9 |
+ FOREACH_DEVICE_DEVLINK(dev, devlink) {
|
|
|
4295f9 |
+ r = link_update(dev, devlink, /* add = */ false);
|
|
|
4295f9 |
+ if (r < 0)
|
|
|
4295f9 |
+ log_device_warning_errno(dev, r,
|
|
|
4295f9 |
+ "Failed to remove/update device symlink '%s', ignoring: %m",
|
|
|
4295f9 |
+ devlink);
|
|
|
4295f9 |
+ }
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ r = device_get_devpath_by_devnum(dev, &filename);
|
|
|
4295f9 |
+ if (r < 0)
|
|
|
4295f9 |
+ return log_device_debug_errno(dev, r, "Failed to get device path: %m");
|
|
|
4295f9 |
+
|
|
|
4295f9 |
+ /* remove /dev/{block,char}/$major:$minor */
|
|
|
4295f9 |
+ if (unlink(filename) < 0 && errno != ENOENT)
|
|
|
4295f9 |
+ return log_device_debug_errno(dev, errno, "Failed to remove '%s': %m", filename);
|
|
|
4295f9 |
+
|
|
|
4295f9 |
return 0;
|
|
|
4295f9 |
}
|
|
|
4295f9 |
|
|
|
4295f9 |
-static int node_permissions_apply(sd_device *dev, bool apply_mac,
|
|
|
4295f9 |
- mode_t mode, uid_t uid, gid_t gid,
|
|
|
4295f9 |
- OrderedHashmap *seclabel_list) {
|
|
|
4295f9 |
+int udev_node_apply_permissions(
|
|
|
4295f9 |
+ sd_device *dev,
|
|
|
4295f9 |
+ bool apply_mac,
|
|
|
4295f9 |
+ mode_t mode,
|
|
|
4295f9 |
+ uid_t uid,
|
|
|
4295f9 |
+ gid_t gid,
|
|
|
4295f9 |
+ OrderedHashmap *seclabel_list) {
|
|
|
4295f9 |
+
|
|
|
4295f9 |
const char *devnode, *subsystem, *id = NULL;
|
|
|
4295f9 |
bool apply_mode, apply_uid, apply_gid;
|
|
|
4295f9 |
_cleanup_close_ int node_fd = -1;
|
|
|
4295f9 |
@@ -511,95 +583,5 @@ static int node_permissions_apply(sd_device *dev, bool apply_mac,
|
|
|
4295f9 |
if (r < 0)
|
|
|
4295f9 |
log_device_debug_errno(dev, r, "Failed to adjust timestamp of node %s: %m", devnode);
|
|
|
4295f9 |
|
|
|
4295f9 |
- return r;
|
|
|
4295f9 |
-}
|
|
|
4295f9 |
-
|
|
|
4295f9 |
-static int xsprintf_dev_num_path_from_sd_device(sd_device *dev, char **ret) {
|
|
|
4295f9 |
- const char *subsystem;
|
|
|
4295f9 |
- dev_t devnum;
|
|
|
4295f9 |
- int r;
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- assert(ret);
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- r = sd_device_get_subsystem(dev, &subsystem);
|
|
|
4295f9 |
- if (r < 0)
|
|
|
4295f9 |
- return r;
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- r = sd_device_get_devnum(dev, &devnum);
|
|
|
4295f9 |
- if (r < 0)
|
|
|
4295f9 |
- return r;
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- return device_path_make_major_minor(streq(subsystem, "block") ? S_IFBLK : S_IFCHR, devnum, ret);
|
|
|
4295f9 |
-}
|
|
|
4295f9 |
-
|
|
|
4295f9 |
-int udev_node_add(sd_device *dev, bool apply,
|
|
|
4295f9 |
- mode_t mode, uid_t uid, gid_t gid,
|
|
|
4295f9 |
- OrderedHashmap *seclabel_list) {
|
|
|
4295f9 |
- const char *devnode, *devlink;
|
|
|
4295f9 |
- _cleanup_free_ char *filename = NULL;
|
|
|
4295f9 |
- int r;
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- assert(dev);
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- r = sd_device_get_devname(dev, &devnode);
|
|
|
4295f9 |
- if (r < 0)
|
|
|
4295f9 |
- return log_device_debug_errno(dev, r, "Failed to get devnode: %m");
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- if (DEBUG_LOGGING) {
|
|
|
4295f9 |
- const char *id = NULL;
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- (void) device_get_device_id(dev, &id;;
|
|
|
4295f9 |
- log_device_debug(dev, "Handling device node '%s', devnum=%s", devnode, strna(id));
|
|
|
4295f9 |
- }
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- r = node_permissions_apply(dev, apply, mode, uid, gid, seclabel_list);
|
|
|
4295f9 |
- if (r < 0)
|
|
|
4295f9 |
- return r;
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- /* create/update symlinks, add symlinks to name index */
|
|
|
4295f9 |
- FOREACH_DEVICE_DEVLINK(dev, devlink) {
|
|
|
4295f9 |
- r = link_update(dev, devlink, true);
|
|
|
4295f9 |
- if (r < 0)
|
|
|
4295f9 |
- log_device_warning_errno(dev, r,
|
|
|
4295f9 |
- "Failed to update device symlink '%s', ignoring: %m",
|
|
|
4295f9 |
- devlink);
|
|
|
4295f9 |
- }
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- r = xsprintf_dev_num_path_from_sd_device(dev, &filename);
|
|
|
4295f9 |
- if (r < 0)
|
|
|
4295f9 |
- return log_device_debug_errno(dev, r, "Failed to get device path: %m");
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- /* always add /dev/{block,char}/$major:$minor */
|
|
|
4295f9 |
- r = node_symlink(dev, devnode, filename);
|
|
|
4295f9 |
- if (r < 0)
|
|
|
4295f9 |
- return log_device_warning_errno(dev, r, "Failed to create device symlink '%s': %m", filename);
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- return 0;
|
|
|
4295f9 |
-}
|
|
|
4295f9 |
-
|
|
|
4295f9 |
-int udev_node_remove(sd_device *dev) {
|
|
|
4295f9 |
- _cleanup_free_ char *filename = NULL;
|
|
|
4295f9 |
- const char *devlink;
|
|
|
4295f9 |
- int r;
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- assert(dev);
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- /* remove/update symlinks, remove symlinks from name index */
|
|
|
4295f9 |
- FOREACH_DEVICE_DEVLINK(dev, devlink) {
|
|
|
4295f9 |
- r = link_update(dev, devlink, false);
|
|
|
4295f9 |
- if (r < 0)
|
|
|
4295f9 |
- log_device_warning_errno(dev, r,
|
|
|
4295f9 |
- "Failed to update device symlink '%s', ignoring: %m",
|
|
|
4295f9 |
- devlink);
|
|
|
4295f9 |
- }
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- r = xsprintf_dev_num_path_from_sd_device(dev, &filename);
|
|
|
4295f9 |
- if (r < 0)
|
|
|
4295f9 |
- return log_device_debug_errno(dev, r, "Failed to get device path: %m");
|
|
|
4295f9 |
-
|
|
|
4295f9 |
- /* remove /dev/{block,char}/$major:$minor */
|
|
|
4295f9 |
- if (unlink(filename) < 0 && errno != ENOENT)
|
|
|
4295f9 |
- return log_device_debug_errno(dev, errno, "Failed to remove '%s': %m", filename);
|
|
|
4295f9 |
-
|
|
|
4295f9 |
return 0;
|
|
|
4295f9 |
}
|
|
|
4295f9 |
diff --git a/src/udev/udev-node.h b/src/udev/udev-node.h
|
|
|
4295f9 |
index 2349f9c471..a34af77146 100644
|
|
|
4295f9 |
--- a/src/udev/udev-node.h
|
|
|
4295f9 |
+++ b/src/udev/udev-node.h
|
|
|
4295f9 |
@@ -8,10 +8,14 @@
|
|
|
4295f9 |
|
|
|
4295f9 |
#include "hashmap.h"
|
|
|
4295f9 |
|
|
|
4295f9 |
-int udev_node_add(sd_device *dev, bool apply,
|
|
|
4295f9 |
- mode_t mode, uid_t uid, gid_t gid,
|
|
|
4295f9 |
- OrderedHashmap *seclabel_list);
|
|
|
4295f9 |
+int udev_node_apply_permissions(
|
|
|
4295f9 |
+ sd_device *dev,
|
|
|
4295f9 |
+ bool apply_mac,
|
|
|
4295f9 |
+ mode_t mode,
|
|
|
4295f9 |
+ uid_t uid,
|
|
|
4295f9 |
+ gid_t gid,
|
|
|
4295f9 |
+ OrderedHashmap *seclabel_list);
|
|
|
4295f9 |
int udev_node_remove(sd_device *dev);
|
|
|
4295f9 |
-int udev_node_update_old_links(sd_device *dev, sd_device *dev_old);
|
|
|
4295f9 |
+int udev_node_update(sd_device *dev, sd_device *dev_old);
|
|
|
4295f9 |
|
|
|
4295f9 |
size_t udev_node_escape_path(const char *src, char *dest, size_t size);
|