Skip to content

Commit 141572a

Browse files
lyakhlgirdwood
authored andcommitted
llext: check number of module entries in libraries
Validate module entry number to avoid out of boundary memory access. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent 65ba963 commit 141572a

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

src/library_manager/llext_manager.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <zephyr/llext/llext.h>
3333
#include <zephyr/logging/log_ctrl.h>
3434
#include <zephyr/llext/inspect.h>
35+
#include <zephyr/sys/math_extras.h>
3536
#include <kernel_arch_interface.h>
3637

3738
#include <rimage/sof/user/manifest.h>
@@ -457,9 +458,22 @@ static int llext_manager_mod_init(struct lib_manager_mod_ctx *ctx,
457458
{
458459
struct sof_man_module *mod_array = (struct sof_man_module *)((uint8_t *)desc +
459460
SOF_MAN_MODULE_OFFSET(0));
461+
/* preload_page_count was checked when library was loaded */
462+
size_t lib_size = desc->header.preload_page_count * PAGE_SZ;
460463
unsigned int i, n_mod;
461464
size_t offs;
462465

466+
/* We'll check overflows below */
467+
uintptr_t mod_end_addr = (uintptr_t)(mod_array + desc->header.num_module_entries);
468+
uintptr_t img_end_addr = (uintptr_t)desc - SOF_MAN_ELF_TEXT_OFFSET + lib_size;
469+
470+
if (mod_end_addr < (uintptr_t)mod_array || img_end_addr < (uintptr_t)desc ||
471+
mod_end_addr >= img_end_addr) {
472+
tr_err(&lib_manager_tr, "invalid module entry count: %u",
473+
desc->header.num_module_entries);
474+
return -EOVERFLOW;
475+
}
476+
463477
/* count modules */
464478
for (i = 0, n_mod = 0, offs = ~0; i < desc->header.num_module_entries; i++)
465479
if (mod_array[i].segment[LIB_MANAGER_TEXT].file_offset != offs) {
@@ -1055,19 +1069,23 @@ int llext_manager_add_library(uint32_t module_id)
10551069

10561070
const struct sof_man_fw_desc *desc = lib_manager_get_library_manifest(module_id);
10571071
unsigned int i;
1072+
int ret;
10581073

1059-
if (!ctx->mod)
1060-
llext_manager_mod_init(ctx, desc);
1074+
if (!ctx->mod) {
1075+
ret = llext_manager_mod_init(ctx, desc);
1076+
if (ret < 0)
1077+
return ret;
1078+
}
10611079

10621080
for (i = 0; i < ctx->n_mod; i++) {
10631081
const struct sof_man_module *mod = lib_manager_get_module_manifest(module_id + i);
10641082

10651083
if (mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT_AUX) {
10661084
const struct sof_man_module_manifest *mod_manifest;
10671085
const struct sof_module_api_build_info *buildinfo;
1068-
int ret = llext_manager_link_single(module_id + i, desc, ctx,
1069-
(const void **)&buildinfo, &mod_manifest);
10701086

1087+
ret = llext_manager_link_single(module_id + i, desc, ctx,
1088+
(const void **)&buildinfo, &mod_manifest);
10711089
if (ret < 0)
10721090
return ret;
10731091
}

0 commit comments

Comments
 (0)