From 4b4f7c5075d26ae17196706a8e7885772758df62 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Fri, 27 Sep 2024 21:32:43 +0200 Subject: [PATCH 1/6] depmod: Fix typo in comment Signed-off-by: Tobias Stoeckmann --- tools/depmod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/depmod.c b/tools/depmod.c index 91bd1911..e736cac4 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -2661,7 +2661,7 @@ static int depmod_output(struct depmod *depmod, FILE *out) static void depmod_add_fake_syms(struct depmod *depmod) { - /* __this_module is magic inserted by kernel loader. */ + /* __this_module is magically inserted by kernel loader. */ depmod_symbol_add(depmod, "__this_module", true, 0, NULL); /* On S390, this is faked up too */ depmod_symbol_add(depmod, "_GLOBAL_OFFSET_TABLE_", true, 0, NULL); From 72ce75c3d3ddb1fb3b7fac783667494975c47448 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Fri, 27 Sep 2024 22:15:59 +0200 Subject: [PATCH 2/6] depmod: Use memdup No need to clear newly allocated memory if source is copied into destination directly. Simplify code by using memdup from shared. Signed-off-by: Tobias Stoeckmann --- tools/depmod.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/depmod.c b/tools/depmod.c index e736cac4..61999730 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -265,10 +265,9 @@ static int index_insert(struct index_node *node, const char *key, const char *va struct index_node *n; /* New child is copy of node with prefix[j+1..N] */ - n = calloc(1, sizeof(struct index_node)); + n = memdup(node, sizeof(struct index_node)); if (n == NULL) fatal_oom(); - memcpy(n, node, sizeof(struct index_node)); n->prefix = strdup(&prefix[j + 1]); if (n->prefix == NULL) fatal_oom(); From 785e8f670f17f2cb5e37e5ea9144d8188f794e45 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Fri, 27 Sep 2024 22:17:11 +0200 Subject: [PATCH 3/6] depmod: Check memdup return value If memdup fails, handle out of memory condition. Signed-off-by: Tobias Stoeckmann --- tools/depmod.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/depmod.c b/tools/depmod.c index 61999730..7d1f3feb 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -1066,6 +1066,11 @@ static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod) size_t uncrelpathlen = lastslash - mod->relpath + modnamesz + strlen(KMOD_EXTENSION_UNCOMPRESSED); mod->uncrelpath = memdup(mod->relpath, uncrelpathlen + 1); + if (mod->uncrelpath == NULL) { + err = -ENOMEM; + hash_del(depmod->modules_by_name, mod->modname); + goto fail; + } mod->uncrelpath[uncrelpathlen] = '\0'; err = hash_add_unique(depmod->modules_by_uncrelpath, mod->uncrelpath, mod); if (err < 0) { From 859e4f668c3e40de80cceaaafac4d988f9834a09 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Fri, 27 Sep 2024 22:17:36 +0200 Subject: [PATCH 4/6] depmod: Read modules.order only once The current code iterates through modules.order twice. First, it figures out how many lines exist. Then it iterates again to make sure that the first line has the lowest sort index, then ascending. Negative values make sure that the previously assigned positive values will be larger, i.e. modules in modules.order take precedence, then modules found in file system which were not listed in modules.order. This can be simplified by setting the initial sort index value to the lowest possible value needed, i.e. -depmod->modules.count. With this value, it is possible to iterate only once. Signed-off-by: Tobias Stoeckmann --- tools/depmod.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/tools/depmod.c b/tools/depmod.c index 7d1f3feb..02a89046 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -1463,39 +1463,30 @@ static void depmod_modules_sort(struct depmod *depmod) char line[PATH_MAX]; const char *order_file = "modules.order"; FILE *fp; - unsigned idx = 0, total = 0; + size_t idx = 0; + // all sorted modules shall have precedence + int i = -(int)depmod->modules.count; fp = dfdopen(depmod->cfg->dirname, order_file, O_RDONLY, "r"); if (fp == NULL) return; while (fgets(line, sizeof(line), fp) != NULL) { + struct mod *mod; size_t len = strlen(line); idx++; if (len == 0) continue; if (line[len - 1] != '\n') { - ERR("%s/%s:%u corrupted line misses '\\n'\n", + ERR("%s/%s:%zu corrupted line misses '\\n'\n", depmod->cfg->dirname, order_file, idx); goto corrupted; } - } - total = idx + 1; - idx = 0; - fseek(fp, 0, SEEK_SET); - while (fgets(line, sizeof(line), fp) != NULL) { - size_t len = strlen(line); - struct mod *mod; - - idx++; - if (len == 0) - continue; line[len - 1] = '\0'; - mod = hash_find(depmod->modules_by_uncrelpath, line); if (mod == NULL) continue; - mod->sort_idx = idx - total; + mod->sort_idx = i++; } array_sort(&depmod->modules, mod_cmp); From 0b18e476309d67db90732075cd549de349c3f48a Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sun, 29 Sep 2024 21:29:56 +0200 Subject: [PATCH 5/6] depmod: Support modules.sort with duplicate lines If the same line exists multiple times in modules.sort, consider only the first, since this is the earliest position requested. This also makes sure that index iterator never turns positive or would ever trigger a signed integer overflow. Signed-off-by: Tobias Stoeckmann --- tools/depmod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/depmod.c b/tools/depmod.c index 02a89046..876c46d3 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -1484,7 +1484,7 @@ static void depmod_modules_sort(struct depmod *depmod) } line[len - 1] = '\0'; mod = hash_find(depmod->modules_by_uncrelpath, line); - if (mod == NULL) + if (mod == NULL || mod->sort_idx < 0) continue; mod->sort_idx = i++; } From a431787f949b34fe6ce3d8cbec3170b63bea0122 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Mon, 30 Sep 2024 17:05:23 +0200 Subject: [PATCH 6/6] depmod: Check amount of memories The code does not support 65535 or more modules. Since this value is probably never reached, add a proper check after array building and do not rely solely on an assert later in code path. Signed-off-by: Tobias Stoeckmann --- tools/depmod.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/depmod.c b/tools/depmod.c index 876c46d3..4718f4d1 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -1428,6 +1428,8 @@ static int depmod_modules_build_array(struct depmod *depmod) if (err < 0) return err; } + if (depmod->modules.count >= UINT16_MAX) + return -ERANGE; return 0; }