udev: use Hashmap for storing SECLABEL
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 16 Oct 2018 20:37:34 +0000 (05:37 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 16 Oct 2018 21:48:53 +0000 (06:48 +0900)
src/udev/udev-event.c
src/udev/udev-node.c
src/udev/udev-node.h
src/udev/udev-rules.c
src/udev/udev.h

index f732913..e015ecf 100644 (file)
@@ -45,7 +45,6 @@ struct udev_event *udev_event_new(struct udev_device *dev) {
                 return NULL;
         event->dev = dev;
         udev_list_init(NULL, &event->run_list, false);
-        udev_list_init(NULL, &event->seclabel_list, false);
         event->birth_usec = now(CLOCK_MONOTONIC);
         return event;
 }
@@ -55,7 +54,7 @@ void udev_event_unref(struct udev_event *event) {
                 return;
         sd_netlink_unref(event->rtnl);
         udev_list_cleanup(&event->run_list);
-        udev_list_cleanup(&event->seclabel_list);
+        hashmap_free_free_free(event->seclabel_list);
         free(event->program_result);
         free(event->name);
         free(event);
@@ -873,7 +872,7 @@ void udev_event_execute_rules(struct udev_event *event,
                         }
 
                         apply = streq(udev_device_get_action(dev), "add") || event->owner_set || event->group_set || event->mode_set;
-                        udev_node_add(dev->device, apply, event->mode, event->uid, event->gid, &event->seclabel_list);
+                        udev_node_add(dev->device, apply, event->mode, event->uid, event->gid, event->seclabel_list);
                 }
 
                 /* preserve old, or get new initialization timestamp */
index 6b06591..9cccef1 100644 (file)
@@ -17,6 +17,7 @@
 #include "fd-util.h"
 #include "format-util.h"
 #include "fs-util.h"
+#include "libudev-private.h"
 #include "path-util.h"
 #include "selinux-util.h"
 #include "smack-util.h"
@@ -271,9 +272,8 @@ int udev_node_update_old_links(sd_device *dev, sd_device *dev_old) {
 
 static int node_permissions_apply(sd_device *dev, bool apply,
                                   mode_t mode, uid_t uid, gid_t gid,
-                                  struct udev_list *seclabel_list) {
+                                  Hashmap *seclabel_list) {
         const char *devnode, *subsystem, *id_filename = NULL;
-        struct udev_list_entry *entry;
         struct stat stats;
         dev_t devnum;
         int r = 0;
@@ -305,6 +305,8 @@ static int node_permissions_apply(sd_device *dev, bool apply,
 
         if (apply) {
                 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) {
                         log_debug("Setting permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
@@ -316,13 +318,9 @@ static int node_permissions_apply(sd_device *dev, bool apply,
                         log_debug("Preserve permissions of %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
 
                 /* apply SECLABEL{$module}=$label */
-                udev_list_entry_foreach(entry, udev_list_get_entry(seclabel_list)) {
-                        const char *name, *label;
+                HASHMAP_FOREACH_KEY(label, name, seclabel_list, i) {
                         int q;
 
-                        name = udev_list_entry_get_name(entry);
-                        label = udev_list_entry_get_value(entry);
-
                         if (streq(name, "selinux")) {
                                 selinux = true;
 
@@ -388,7 +386,7 @@ static int xsprintf_dev_num_path_from_sd_device(sd_device *dev, char **ret) {
 
 int udev_node_add(sd_device *dev, bool apply,
                   mode_t mode, uid_t uid, gid_t gid,
-                  struct udev_list *seclabel_list) {
+                  Hashmap *seclabel_list) {
         const char *devnode, *devlink;
         _cleanup_free_ char *filename = NULL;
         int r;
index 868549e..223c8f0 100644 (file)
@@ -4,13 +4,12 @@
 #include <stdbool.h>
 #include <sys/types.h>
 
-#include "libudev.h"
 #include "sd-device.h"
 
-#include "libudev-private.h"
+#include "hashmap.h"
 
 int udev_node_add(sd_device *dev, bool apply,
                   mode_t mode, uid_t uid, gid_t gid,
-                  struct udev_list *seclabel_list);
+                  Hashmap *seclabel_list);
 int udev_node_remove(sd_device *dev);
 int udev_node_update_old_links(sd_device *dev, sd_device *dev_old);
index d315685..601b958 100644 (file)
@@ -1711,19 +1711,20 @@ enum escape_type {
         ESCAPE_REPLACE,
 };
 
-void udev_rules_apply_to_event(struct udev_rules *rules,
-                               struct udev_event *event,
-                               usec_t timeout_usec,
-                               usec_t timeout_warn_usec,
-                               struct udev_list *properties_list) {
+int udev_rules_apply_to_event(
+                struct udev_rules *rules,
+                struct udev_event *event,
+                usec_t timeout_usec,
+                usec_t timeout_warn_usec,
+                struct udev_list *properties_list) {
         struct token *cur;
         struct token *rule;
         enum escape_type esc = ESCAPE_UNSET;
         bool can_set_name;
         int r;
 
-        if (rules->tokens == NULL)
-                return;
+        if (!rules->tokens)
+                return 0;
 
         can_set_name = ((!streq(udev_device_get_action(event->dev), "remove")) &&
                         (major(udev_device_get_devnum(event->dev)) > 0 ||
@@ -2188,19 +2189,34 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
                                   rule->rule.filename_line);
                         break;
                 case TK_A_SECLABEL: {
+                        _cleanup_free_ char *name = NULL, *label = NULL;
                         char label_str[UTIL_LINE_SIZE] = {};
-                        const char *name, *label;
 
-                        name = rules_str(rules, cur->key.attr_off);
+                        name = strdup(rules_str(rules, cur->key.attr_off));
+                        if (!name)
+                                return log_oom();
+
                         udev_event_apply_format(event, rules_str(rules, cur->key.value_off), label_str, sizeof(label_str), false);
-                        if (label_str[0] != '\0')
-                                label = label_str;
+                        if (!isempty(label_str))
+                                label = strdup(label_str);
                         else
-                                label = rules_str(rules, cur->key.value_off);
+                                label = strdup(rules_str(rules, cur->key.value_off));
+                        if (!label)
+                                return log_oom();
 
                         if (IN_SET(cur->key.op, OP_ASSIGN, OP_ASSIGN_FINAL))
-                                udev_list_cleanup(&event->seclabel_list);
-                        udev_list_entry_add(&event->seclabel_list, name, label);
+                                hashmap_clear_free_free(event->seclabel_list);
+
+                        r = hashmap_ensure_allocated(&event->seclabel_list, NULL);
+                        if (r < 0)
+                                return log_oom();
+
+                        r = hashmap_put(event->seclabel_list, name, label);
+                        if (r < 0)
+                                return log_oom();
+
+                        name = label = NULL;
+
                         log_debug("SECLABEL{%s}='%s' %s:%u",
                                   name, label,
                                   rules_str(rules, rule->rule.filename_off),
@@ -2280,10 +2296,9 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
                                           rule->rule.filename_line);
                                 break;
                         }
-                        if (free_and_strdup(&event->name, name_str) < 0) {
-                                log_oom();
-                                return;
-                        }
+                        if (free_and_strdup(&event->name, name_str) < 0)
+                                return log_oom();
+
                         log_debug("NAME '%s' %s:%u",
                                   event->name,
                                   rules_str(rules, rule->rule.filename_off),
@@ -2391,7 +2406,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
                         cur = &rules->tokens[cur->key.rule_goto];
                         continue;
                 case TK_END:
-                        return;
+                        return 0;
 
                 case TK_M_PARENTS_MIN:
                 case TK_M_PARENTS_MAX:
@@ -2407,6 +2422,8 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
                 /* fast-forward to next rule */
                 cur = rule + rule->rule.token_count;
         }
+
+        return 0;
 }
 
 int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
index 09bd54e..afdd876 100644 (file)
@@ -13,6 +13,7 @@
 #include "sd-device.h"
 #include "sd-netlink.h"
 
+#include "hashmap.h"
 #include "label.h"
 #include "libudev-private.h"
 #include "macro.h"
@@ -28,7 +29,7 @@ struct udev_event {
         mode_t mode;
         uid_t uid;
         gid_t gid;
-        struct udev_list seclabel_list;
+        Hashmap *seclabel_list;
         struct udev_list run_list;
         int exec_delay;
         usec_t birth_usec;
@@ -53,9 +54,9 @@ struct udev_rules;
 struct udev_rules *udev_rules_new(int resolve_names);
 struct udev_rules *udev_rules_unref(struct udev_rules *rules);
 bool udev_rules_check_timestamp(struct udev_rules *rules);
-void udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event,
-                               usec_t timeout_usec, usec_t timeout_warn_usec,
-                               struct udev_list *properties_list);
+int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event,
+                              usec_t timeout_usec, usec_t timeout_warn_usec,
+                              struct udev_list *properties_list);
 int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
 
 /* udev-event.c */