From: Adrien Thierry Date: Wed, 15 Feb 2023 19:13:56 +0000 (-0500) Subject: fix(dracut-install): prevent possible infinite recursion with suppliers X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=131822e26d76a3ce2028e9a545be2af066805629;p=thirdparty%2Fdracut.git fix(dracut-install): prevent possible infinite recursion with suppliers 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 --- diff --git a/src/install/dracut-install.c b/src/install/dracut-install.c index 5af353455..6bf5ce1fd 100644 --- a/src/install/dracut-install.c +++ b/src/install/dracut-install.c @@ -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);