Skip to content

Commit 2a2f3cc

Browse files
committed
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 901c0ce commit 2a2f3cc

1 file changed

Lines changed: 21 additions & 4 deletions

File tree

src/library_manager/llext_manager.c

Lines changed: 21 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>
@@ -458,8 +459,20 @@ static int llext_manager_mod_init(struct lib_manager_mod_ctx *ctx,
458459
struct sof_man_module *mod_array = (struct sof_man_module *)((uint8_t *)desc +
459460
SOF_MAN_MODULE_OFFSET(0));
460461
unsigned int i, n_mod;
462+
size_t lib_size;
461463
size_t offs;
462464

465+
if (size_mul_overflow(desc->header.preload_page_count, PAGE_SZ, &lib_size))
466+
return -EOVERFLOW;
467+
468+
/* We'll check overflows below */
469+
uintptr_t mod_end_addr = (uintptr_t)(mod_array + desc->header.num_module_entries);
470+
uintptr_t img_end_addr = (uintptr_t)desc - SOF_MAN_ELF_TEXT_OFFSET + lib_size;
471+
472+
if (mod_end_addr < (uintptr_t)mod_array || img_end_addr < (uintptr_t)desc ||
473+
mod_end_addr >= img_end_addr)
474+
return -EOVERFLOW;
475+
463476
/* count modules */
464477
for (i = 0, n_mod = 0, offs = ~0; i < desc->header.num_module_entries; i++)
465478
if (mod_array[i].segment[LIB_MANAGER_TEXT].file_offset != offs) {
@@ -1055,19 +1068,23 @@ int llext_manager_add_library(uint32_t module_id)
10551068

10561069
const struct sof_man_fw_desc *desc = lib_manager_get_library_manifest(module_id);
10571070
unsigned int i;
1071+
int ret;
10581072

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

10621079
for (i = 0; i < ctx->n_mod; i++) {
10631080
const struct sof_man_module *mod = lib_manager_get_module_manifest(module_id + i);
10641081

10651082
if (mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT_AUX) {
10661083
const struct sof_man_module_manifest *mod_manifest;
10671084
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);
10701085

1086+
ret = llext_manager_link_single(module_id + i, desc, ctx,
1087+
(const void **)&buildinfo, &mod_manifest);
10711088
if (ret < 0)
10721089
return ret;
10731090
}

0 commit comments

Comments
 (0)