From: Yu Watanabe Date: Tue, 16 Oct 2018 20:37:34 +0000 (+0900) Subject: udev: use Hashmap for storing SECLABEL X-Git-Tag: v240~534^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d838e14515c82b05a07f2bf393cce057b45b2b53;p=platform%2Fupstream%2Fsystemd.git udev: use Hashmap for storing SECLABEL --- diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index f732913..e015ecf 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -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 */ diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 6b06591..9cccef1 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -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; diff --git a/src/udev/udev-node.h b/src/udev/udev-node.h index 868549e..223c8f0 100644 --- a/src/udev/udev-node.h +++ b/src/udev/udev-node.h @@ -4,13 +4,12 @@ #include #include -#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); diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index d315685..601b958 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -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) { diff --git a/src/udev/udev.h b/src/udev/udev.h index 09bd54e..afdd876 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -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 */