Skip to content

Commit 158518d

Browse files
committed
llext: userspace: clear cold segment descriptors when sections are absent
llext_manager_rm_mod_domain() removes the .cold and .coldrodata memory partitions of a module from its domain if the corresponding mctx->segment[] descriptor has a non-zero address. Those descriptors are only ever populated by llext_manager_add_mod_domain() when the module actually contains a .cold / .coldrodata section. The module context array is allocated with rmalloc() (non-zeroing) and llext_manager_mod_init() initialises every field except the segment[] array. The LIB_MANAGER_TEXT/RODATA/DATA/BSS descriptors are filled in during linking, but LIB_MANAGER_COLD / LIB_MANAGER_COLDRODATA are left holding uninitialised heap data for any module that has no such section. As a result, when such a module is freed, rm_mod_domain() sees a garbage non-zero address and tries to remove a partition that was never added: <err> os.k_mem_domain_remove_partition: no matching partition found <err> lib_manager.llext_manager_rm_mod_domain: failed to remove .coldrodata memory partition: -2 Reproduced at end-of-stream of a DMIC capture (arecord -Dhw:0,4), whose EQIIR / TDFB / DRC modules carry no .coldrodata section. Make add_mod_domain() the sole owner of these descriptors: explicitly zero them when the section is absent, so rm_mod_domain() only ever removes partitions that were really added. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent 90687ac commit 158518d

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

src/library_manager/llext_manager.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,16 @@ static int llext_manager_add_mod_domain(struct lib_manager_module *mctx, struct
952952
goto e_data;
953953
mctx->segment[LIB_MANAGER_COLD].addr = (uintptr_t)text_addr + text_offset;
954954
mctx->segment[LIB_MANAGER_COLD].size = shdr_cold.sh_size;
955+
} else {
956+
/*
957+
* No .cold section: make sure the descriptor is empty so that
958+
* llext_manager_rm_mod_domain() doesn't later try to remove a
959+
* partition that was never added. The module context is
960+
* allocated with rmalloc() and these fields are otherwise left
961+
* uninitialised.
962+
*/
963+
mctx->segment[LIB_MANAGER_COLD].addr = 0;
964+
mctx->segment[LIB_MANAGER_COLD].size = 0;
955965
}
956966

957967
if (rodata) {
@@ -964,6 +974,10 @@ static int llext_manager_add_mod_domain(struct lib_manager_module *mctx, struct
964974
goto e_cold;
965975
mctx->segment[LIB_MANAGER_COLDRODATA].addr = (uintptr_t)rodata_addr + rodata_offset;
966976
mctx->segment[LIB_MANAGER_COLDRODATA].size = shdr_coldrodata.sh_size;
977+
} else {
978+
/* No .coldrodata section, see the comment above */
979+
mctx->segment[LIB_MANAGER_COLDRODATA].addr = 0;
980+
mctx->segment[LIB_MANAGER_COLDRODATA].size = 0;
967981
}
968982

969983
return 0;

0 commit comments

Comments
 (0)