From: Rusty Russell I *do* want to add a check for a truncated module, since that's probably the most common case (^C on "make modules_install"). But I don't want to double the size of module.c with every check I can think of. tested with: # bs=0; while [ $bs -lt 3764 ]; do dd if=dummy.ko bs=$bs count=1 2>/dev/null | insmod -; bs=`expr $bs + 1`; done --- kernel/module.c | 12 ++++++++++++ 1 files changed, 12 insertions(+) diff -puN kernel/module.c~truncated-module-check-2 kernel/module.c --- 25/kernel/module.c~truncated-module-check-2 2004-01-19 22:53:50.000000000 -0800 +++ 25-akpm/kernel/module.c 2004-01-19 22:53:50.000000000 -0800 @@ -1421,6 +1421,9 @@ static struct module *load_module(void _ goto free_hdr; } + if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) + goto truncated; + /* Convenience variables */ sechdrs = (void *)hdr + hdr->e_shoff; secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; @@ -1430,6 +1433,10 @@ static struct module *load_module(void _ symindex = strindex = 0; for (i = 1; i < hdr->e_shnum; i++) { + if (sechdrs[i].sh_type != SHT_NOBITS + && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) + goto truncated; + /* Mark all sections sh_addr with their address in the temporary image. */ sechdrs[i].sh_addr = (size_t)hdr + sechdrs[i].sh_offset; @@ -1694,6 +1701,11 @@ static struct module *load_module(void _ vfree(hdr); if (err < 0) return ERR_PTR(err); else return ptr; + + truncated: + printk(KERN_ERR "Module len %lu truncated\n", len); + err = -ENOEXEC; + goto free_hdr; } /* This is where the real work happens */ _