]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
list: make LIST_FOREACH() and LIST_FOREACH_BACKWARDS() safer
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 15 Mar 2022 07:47:01 +0000 (16:47 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 18 Mar 2022 23:10:29 +0000 (08:10 +0900)
16 files changed:
src/basic/list.h
src/core/device.c
src/core/service.c
src/libsystemd-network/sd-dhcp6-lease.c
src/libudev/libudev-list.c
src/network/netdev/wireguard.c
src/partition/repart.c
src/resolve/resolved-dns-cache.c
src/resolve/resolved-dns-transaction.c
src/rfkill/rfkill.c
src/shared/condition.c
src/shutdown/umount.c
src/timesync/timesyncd-manager.c
src/udev/net/link-config.c
src/udev/udev-rules.c
src/udev/udevd.c

index 14bf6b5e9b1826db8b8dfe64d6db2a30466003d4..58e83a6cb2bfab17259e15428422528f4be662e6 100644 (file)
 /* The type of the iterator 'i' is automatically determined by the type of 'head', and declared in the
  * loop. Hence, do not declare the same variable in the outer scope. Sometimes, we set 'head' through
  * hashmap_get(). In that case, you need to explicitly cast the result. */
+#define LIST_FOREACH_WITH_NEXT(name,i,n,head)                           \
+        for (typeof(*(head)) *n, *i = (head); i && (n = i->name##_next, true); i = n)
+
 #define LIST_FOREACH(name,i,head)                                       \
-        for (typeof(*(head)) *i = (head); i; i = i->name##_next)
+        LIST_FOREACH_WITH_NEXT(name, i, UNIQ_T(n, UNIQ), head)
 
-#define LIST_FOREACH_SAFE(name,i,n,head)                                \
-        for (typeof(*(head)) *n, *i = (head); i && ((n = i->name##_next), 1); i = n)
+#define _LIST_FOREACH_WITH_PREV(name,i,p,start)                         \
+        for (typeof(*(start)) *p, *i = (start); i && (p = i->name##_prev, true); i = p)
 
-#define LIST_FOREACH_BACKWARDS(name,i,p)                                \
-        for (typeof(*(p)) *i = (p); i; i = i->name##_prev)
+#define LIST_FOREACH_BACKWARDS(name,i,start)                            \
+        _LIST_FOREACH_WITH_PREV(name, i, UNIQ_T(p, UNIQ), start)
 
 /* Iterate through all the members of the list p is included in, but skip over p */
 #define LIST_FOREACH_OTHERS(name,i,p)                                   \
index e1cef86a1b0e1e62e54581eec0b6614ef6f79213..f9a7fa449a1244d6bf49a4175b5734d12ec62e1b 100644 (file)
@@ -719,7 +719,7 @@ static void device_update_found_by_sysfs(Manager *m, const char *sysfs, DeviceFo
                 return;
 
         l = hashmap_get(m->devices_by_sysfs, sysfs);
-        LIST_FOREACH_SAFE(same_sysfs, d, n, l)
+        LIST_FOREACH(same_sysfs, d, l)
                 device_update_found_one(d, found, mask);
 }
 
@@ -905,7 +905,7 @@ static void device_propagate_reload_by_sysfs(Manager *m, const char *sysfs) {
         assert(sysfs);
 
         l = hashmap_get(m->devices_by_sysfs, sysfs);
-        LIST_FOREACH_SAFE(same_sysfs, d, n, l) {
+        LIST_FOREACH(same_sysfs, d, l) {
                 if (d->state == DEVICE_DEAD)
                         continue;
 
index 65aed4c06b53891d2a7b28513536446fdfc2f473..d7a86bac5d721e52034163dd9b589fd7e6bf51ff 100644 (file)
@@ -507,7 +507,7 @@ static void service_remove_fd_store(Service *s, const char *name) {
         assert(s);
         assert(name);
 
-        LIST_FOREACH_SAFE(fd_store, fs, n, s->fd_store) {
+        LIST_FOREACH(fd_store, fs, s->fd_store) {
                 if (!streq(fs->fdname, name))
                         continue;
 
index 138316f6c23af300cc0478af946c4705d4d674d3..8734e5a824b88aec2cd3251b2fe554d6796ff157 100644 (file)
@@ -108,7 +108,7 @@ int sd_dhcp6_lease_get_server_address(sd_dhcp6_lease *lease, struct in6_addr *re
 void dhcp6_ia_clear_addresses(DHCP6IA *ia) {
         assert(ia);
 
-        LIST_FOREACH_SAFE(addresses, a, n, ia->addresses)
+        LIST_FOREACH(addresses, a, ia->addresses)
                 free(a);
 
         ia->addresses = NULL;
index 9b6625c436449c2b36db48733409f4a34f26a456..d3b63b1f8fba31dfb66e9ae6e8cd870c34ee2a67 100644 (file)
@@ -117,7 +117,7 @@ void udev_list_cleanup(struct udev_list *list) {
                 list->uptodate = false;
                 hashmap_clear_with_destructor(list->unique_entries, udev_list_entry_free);
         } else
-                LIST_FOREACH_SAFE(entries, i, n, list->entries)
+                LIST_FOREACH(entries, i, list->entries)
                         udev_list_entry_free(i);
 }
 
index 21510282e8a0e6735f0e633452f4b37080b71719..9e98b93a5cf890cd7fe2b4d50175509999c6de4c 100644 (file)
@@ -1146,7 +1146,7 @@ static int wireguard_verify(NetDev *netdev, const char *filename) {
                                               "%s: Missing PrivateKey= or PrivateKeyFile=, "
                                               "Ignoring network device.", filename);
 
-        LIST_FOREACH_SAFE(peers, peer, peer_next, w->peers) {
+        LIST_FOREACH(peers, peer, w->peers) {
                 if (wireguard_peer_verify(peer) < 0) {
                         wireguard_peer_free(peer);
                         continue;
index 82271166ae68862b2a1e108d41b1af4a0534a855..8afc4c5423cc1edc747f77ff599f50141335f7a3 100644 (file)
@@ -1902,7 +1902,7 @@ add_initial_free_area:
 static void context_unload_partition_table(Context *context) {
         assert(context);
 
-        LIST_FOREACH_SAFE(partitions, p, next, context->partitions) {
+        LIST_FOREACH(partitions, p, context->partitions) {
 
                 /* Entirely remove partitions that have no configuration */
                 if (PARTITION_IS_FOREIGN(p)) {
index a2f4321e1d61d5b5196980cc167c6f5cdf0e4908..3dce32ed387953b67d477ce5b55a17ec9971cfc9 100644 (file)
@@ -144,7 +144,7 @@ static bool dns_cache_remove_by_key(DnsCache *c, DnsResourceKey *key) {
         if (!first)
                 return false;
 
-        LIST_FOREACH_SAFE(by_key, i, n, first) {
+        LIST_FOREACH(by_key, i, first) {
                 prioq_remove(c->by_expiry, i, &i->prioq_idx);
                 dns_cache_item_free(i);
         }
index 678ece4fc0127cb279a5fad27b4414c3ebc01f5a..52897649d159f0a783a114341ce2160681c0df38 100644 (file)
@@ -635,7 +635,7 @@ static int on_stream_complete(DnsStream *s, int error) {
         }
 
         if (error != 0)
-                LIST_FOREACH_SAFE(transactions_by_stream, t, n, s->transactions)
+                LIST_FOREACH(transactions_by_stream, t, s->transactions)
                         on_transaction_stream_error(t, error);
 
         return 0;
index 7e8b8a27ef33a6308ddad64c0692dec56ce41963..656afa06ac8b4b551dba25271bc104b89cca6933 100644 (file)
@@ -190,7 +190,7 @@ static int load_state(Context *c, const struct rfkill_event *event) {
 static void save_state_queue_remove(Context *c, int idx, const char *state_file) {
         assert(c);
 
-        LIST_FOREACH_SAFE(queue, item, tmp, c->write_queue)
+        LIST_FOREACH(queue, item, c->write_queue)
                 if ((state_file && streq(item->file, state_file)) || idx == item->rfkill_idx) {
                         log_debug("Canceled previous save state of '%s' to %s.", one_zero(item->state), item->file);
                         LIST_REMOVE(queue, c->write_queue, item);
index 6f31abe06df55be76ae40ebbf68d76fc752012a5..204f2a1a8d31ef6b51c5c11d587f9ebd7c75aec8 100644 (file)
@@ -89,7 +89,7 @@ Condition* condition_free(Condition *c) {
 }
 
 Condition* condition_free_list_type(Condition *head, ConditionType type) {
-        LIST_FOREACH_SAFE(conditions, c, n, head)
+        LIST_FOREACH(conditions, c, head)
                 if (type < 0 || c->type == type) {
                         LIST_REMOVE(conditions, head, c);
                         condition_free(c);
index 4f14dfb3dfabf9be483c0df2fccc6b621c4a402a..3e9e241499a5f0a552b3321e31e5d92198653f28 100644 (file)
@@ -639,7 +639,7 @@ static int swap_points_list_off(MountPoint **head, bool *changed) {
         assert(head);
         assert(changed);
 
-        LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+        LIST_FOREACH(mount_point, m, *head) {
                 log_info("Deactivating swap %s.", m->path);
                 if (swapoff(m->path) < 0) {
                         log_warning_errno(errno, "Could not deactivate swap %s: %m", m->path);
@@ -663,7 +663,7 @@ static int loopback_points_list_detach(MountPoint **head, bool *changed, int umo
 
         (void) get_block_device("/", &rootdev);
 
-        LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+        LIST_FOREACH(mount_point, m, *head) {
                 if (major(rootdev) != 0 && rootdev == m->devnum) {
                         n_failed++;
                         continue;
@@ -694,7 +694,7 @@ static int dm_points_list_detach(MountPoint **head, bool *changed, int umount_lo
 
         (void) get_block_device("/", &rootdev);
 
-        LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+        LIST_FOREACH(mount_point, m, *head) {
                 if (major(rootdev) != 0 && rootdev == m->devnum) {
                         n_failed ++;
                         continue;
@@ -724,7 +724,7 @@ static int md_points_list_detach(MountPoint **head, bool *changed, int umount_lo
 
         (void) get_block_device("/", &rootdev);
 
-        LIST_FOREACH_SAFE(mount_point, m, n, *head) {
+        LIST_FOREACH(mount_point, m, *head) {
                 if (major(rootdev) != 0 && rootdev == m->devnum) {
                         n_failed ++;
                         continue;
index e7193bf41cdcdfcbde11a4617e2be150b36739fb..5f757ffb4f4590f5a30e216d1e31394a6867cb78 100644 (file)
@@ -1008,7 +1008,7 @@ static int manager_network_read_link_servers(Manager *m) {
                 }
         }
 
-        LIST_FOREACH_SAFE(names, n, nx, m->link_servers)
+        LIST_FOREACH(names, n, m->link_servers)
                 if (n->marked) {
                         server_name_free(n);
                         changed = true;
index bb6d1b7b3e48268d0b99013db736f797f57d7edc..67e3b621308d762f2c56cb1689558ccfdca693bc 100644 (file)
@@ -72,7 +72,7 @@ static void link_configs_free(LinkConfigContext *ctx) {
         if (!ctx)
                 return;
 
-        LIST_FOREACH_SAFE(configs, config, config_next, ctx->configs)
+        LIST_FOREACH(configs, config, ctx->configs)
                 link_config_free(config);
 }
 
index 43de3c6d7f09eb45ae3c9fe23bbd05641f8f54aa..79e75c374ecd7dac0ecfae031206013a8af70945 100644 (file)
@@ -270,7 +270,7 @@ static void udev_rule_token_free(UdevRuleToken *token) {
 static void udev_rule_line_clear_tokens(UdevRuleLine *rule_line) {
         assert(rule_line);
 
-        LIST_FOREACH_SAFE(tokens, i, next, rule_line->tokens)
+        LIST_FOREACH(tokens, i, rule_line->tokens)
                 udev_rule_token_free(i);
 
         rule_line->tokens = NULL;
@@ -299,7 +299,7 @@ static void udev_rule_file_free(UdevRuleFile *rule_file) {
         if (!rule_file)
                 return;
 
-        LIST_FOREACH_SAFE(rule_lines, i, next, rule_file->rule_lines)
+        LIST_FOREACH(rule_lines, i, rule_file->rule_lines)
                 udev_rule_line_free(i);
 
         free(rule_file->filename);
@@ -310,7 +310,7 @@ UdevRules *udev_rules_free(UdevRules *rules) {
         if (!rules)
                 return NULL;
 
-        LIST_FOREACH_SAFE(rule_files, i, next, rules->rule_files)
+        LIST_FOREACH(rule_files, i, rules->rule_files)
                 udev_rule_file_free(i);
 
         hashmap_free_free_key(rules->known_users);
@@ -1143,7 +1143,7 @@ static void rule_resolve_goto(UdevRuleFile *rule_file) {
         assert(rule_file);
 
         /* link GOTOs to LABEL rules in this file to be able to fast-forward */
-        LIST_FOREACH_SAFE(rule_lines, line, line_next, rule_file->rule_lines) {
+        LIST_FOREACH(rule_lines, line, rule_file->rule_lines) {
                 if (!FLAGS_SET(line->type, LINE_HAS_GOTO))
                         continue;
 
@@ -2486,7 +2486,7 @@ static int udev_rule_apply_line_to_event(
 
         DEVICE_TRACE_POINT(rules_apply_line, event->dev, line->rule_file->filename, line->line_number);
 
-        LIST_FOREACH_SAFE(tokens, token, next_token, line->tokens) {
+        LIST_FOREACH(tokens, token, line->tokens) {
                 line->current_token = token;
 
                 if (token_is_for_parents(token)) {
@@ -2526,7 +2526,7 @@ int udev_rules_apply_to_event(
 
         LIST_FOREACH(rule_files, file, rules->rule_files) {
                 rules->current_file = file;
-                LIST_FOREACH_SAFE(rule_lines, line, next_line, file->rule_lines) {
+                LIST_FOREACH_WITH_NEXT(rule_lines, line, next_line, file->rule_lines) {
                         file->current_line = line;
                         r = udev_rule_apply_line_to_event(rules, event, timeout_usec, timeout_signal, properties_list, &next_line);
                         if (r < 0)
index 601f82a43d31456944b1b988d9fa70ab61dd9921..41d0ec1e137c192a4089d2e238c7834f543c8841 100644 (file)
@@ -181,7 +181,7 @@ static Event *event_free(Event *event) {
 }
 
 static void event_queue_cleanup(Manager *manager, EventState match_state) {
-        LIST_FOREACH_SAFE(event, event, tmp, manager->events) {
+        LIST_FOREACH(event, event, manager->events) {
                 if (match_state != EVENT_UNDEF && match_state != event->state)
                         continue;
 
@@ -949,7 +949,7 @@ static int event_queue_start(Manager *manager) {
                         return log_warning_errno(r, "Failed to read udev rules: %m");
         }
 
-        LIST_FOREACH_SAFE(event, event, event_next, manager->events) {
+        LIST_FOREACH(event, event, manager->events) {
                 if (event->state != EVENT_QUEUED)
                         continue;