From: Rusty Russell <rusty@rustcorp.com.au>

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-10 23:32:45.000000000 -0800
+++ 25-akpm/kernel/module.c	2004-01-10 23:32:45.000000000 -0800
@@ -1420,6 +1420,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;
@@ -1429,6 +1432,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;
@@ -1692,6 +1699,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 */

_