Skip to content

Commit c7ee8ae

Browse files
committed
module: add stop-grap sanity check on module memcpy()
The integrity of the struct module we load is important, and although our ELF validator already checks that the module section must match struct module, add a stop-gap check before we memcpy() the final minted module. This also makes those inspecting the code what the goal is. While at it, clarify the goal behind updating the sh_addr address. The current comment is pretty misleading. Signed-off-by: Luis Chamberlain <[email protected]>
1 parent 4675282 commit c7ee8ae

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

kernel/module/main.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,7 +2213,8 @@ static int move_module(struct module *mod, struct load_info *info)
22132213
{
22142214
int i;
22152215
void *ptr;
2216-
enum mod_mem_type t;
2216+
enum mod_mem_type t = 0;
2217+
int ret = -ENOMEM;
22172218

22182219
for_each_mod_mem_type(type) {
22192220
if (!mod->mem[type].size) {
@@ -2249,9 +2250,26 @@ static int move_module(struct module *mod, struct load_info *info)
22492250

22502251
dest = mod->mem[type].base + (shdr->sh_entsize & SH_ENTSIZE_OFFSET_MASK);
22512252

2252-
if (shdr->sh_type != SHT_NOBITS)
2253+
if (shdr->sh_type != SHT_NOBITS) {
2254+
/*
2255+
* Our ELF checker already validated this, but let's
2256+
* be pedantic and make the goal clearer. We actually
2257+
* end up copying over all modifications made to the
2258+
* userspace copy of the entire struct module.
2259+
*/
2260+
if (i == info->index.mod &&
2261+
(WARN_ON_ONCE(shdr->sh_size != sizeof(struct module)))) {
2262+
ret = -ENOEXEC;
2263+
goto out_enomem;
2264+
}
22532265
memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
2254-
/* Update sh_addr to point to copy in image. */
2266+
}
2267+
/*
2268+
* Update the userspace copy's ELF section address to point to
2269+
* our newly allocated memory as a pure convenience so that
2270+
* users of info can keep taking advantage and using the newly
2271+
* minted official memory area.
2272+
*/
22552273
shdr->sh_addr = (unsigned long)dest;
22562274
pr_debug("\t0x%lx %s\n",
22572275
(long)shdr->sh_addr, info->secstrings + shdr->sh_name);
@@ -2261,7 +2279,7 @@ static int move_module(struct module *mod, struct load_info *info)
22612279
out_enomem:
22622280
for (t--; t >= 0; t--)
22632281
module_memory_free(mod->mem[t].base, t);
2264-
return -ENOMEM;
2282+
return ret;
22652283
}
22662284

22672285
static int check_export_symbol_versions(struct module *mod)

0 commit comments

Comments
 (0)