]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
fix(dracut-install): prevent possible infinite recursion with suppliers
authorAdrien Thierry <athierry@redhat.com>
Wed, 15 Feb 2023 19:13:56 +0000 (14:13 -0500)
committerJóhann B. Guðmundsson <johannbg@gmail.com>
Tue, 21 Feb 2023 20:05:44 +0000 (20:05 +0000)
During search for fw_devlink suppliers, it's possible to encounter a
situation where supplier A depends on supplier B, and supplier B has a
parent node that depends on supplier A. This leads to an infinite
recursion.

To fix this, make sure suppliers are only processed once.

Signed-off-by: Adrien Thierry <athierry@redhat.com>
src/install/dracut-install.c

index 5af3534556caefaab1bc17d697de82ce4fac4d37..6bf5ce1fd70a1300fcb4a5f5562a0d7c6e5e0360 100644 (file)
@@ -83,6 +83,7 @@ static Hashmap *items = NULL;
 static Hashmap *items_failed = NULL;
 static Hashmap *modules_loaded = NULL;
 static Hashmap *modules_suppliers = NULL;
+static Hashmap *processed_suppliers = NULL;
 static regex_t mod_filter_path;
 static regex_t mod_filter_nopath;
 static regex_t mod_filter_symbol;
@@ -1667,6 +1668,12 @@ static int install_dependent_modules(struct kmod_ctx *ctx, struct kmod_list *mod
         const char *supplier_path;
         Iterator i;
         HASHMAP_FOREACH(supplier_path, suppliers_paths, i) {
+                if (check_hashmap(processed_suppliers, supplier_path))
+                        continue;
+
+                char *path = strdup(supplier_path);
+                hashmap_put(processed_suppliers, path, path);
+
                 _cleanup_destroy_hashmap_ Hashmap *modules = hashmap_new(string_hash_func, string_compare_func);
                 find_modules_from_sysfs_node(ctx, supplier_path, modules);
 
@@ -2182,8 +2189,9 @@ int main(int argc, char **argv)
 
         items = hashmap_new(string_hash_func, string_compare_func);
         items_failed = hashmap_new(string_hash_func, string_compare_func);
+        processed_suppliers = hashmap_new(string_hash_func, string_compare_func);
 
-        if (!items || !items_failed || !modules_loaded) {
+        if (!items || !items_failed || !processed_suppliers || !modules_loaded) {
                 log_error("Out of memory");
                 r = EXIT_FAILURE;
                 goto finish1;
@@ -2252,10 +2260,14 @@ finish2:
                 hashmap_free(h);
         }
 
+        while ((i = hashmap_steal_first(processed_suppliers)))
+                item_free(i);
+
         hashmap_free(items);
         hashmap_free(items_failed);
         hashmap_free(modules_loaded);
         hashmap_free(modules_suppliers);
+        hashmap_free(processed_suppliers);
 
         strv_free(firmwaredirs);
         strv_free(pathdirs);