Browse Source

[SECURITY] fix buffer overflow in readelf.c

Michael Stone 22 years ago
parent
commit
72a4c71afa
2 changed files with 21 additions and 6 deletions
  1. 16 3
      readelf.c
  2. 5 3
      softmagic.c

+ 16 - 3
readelf.c

@@ -104,12 +104,18 @@ getu64(swap, value)
 #define sh_addr		(class == ELFCLASS32		\
 			 ? (void *) &sh32		\
 			 : (void *) &sh64)
+#define sh_size		(class == ELFCLASS32		\
+			 ? sizeof sh32			\
+			 : sizeof sh64)
 #define shs_type	(class == ELFCLASS32		\
 			 ? getu32(swap, sh32.sh_type)	\
 			 : getu32(swap, sh64.sh_type))
 #define ph_addr		(class == ELFCLASS32		\
 			 ? (void *) &ph32		\
 			 : (void *) &ph64)
+#define ph_size		(class == ELFCLASS32		\
+			 ? sizeof ph32			\
+			 : sizeof ph64)
 #define ph_type		(class == ELFCLASS32		\
 			 ? getu32(swap, ph32.p_type)	\
 			 : getu32(swap, ph64.p_type))
@@ -144,11 +150,14 @@ doshn(class, swap, fd, off, num, size)
 	Elf32_Shdr sh32;
 	Elf64_Shdr sh64;
 
+	if (size != sh_size)
+		error("corrupted section header size.\n");
+
 	if (lseek(fd, off, SEEK_SET) == -1)
 		error("lseek failed (%s).\n", strerror(errno));
 
 	for ( ; num; num--) {
-		if (read(fd, sh_addr, size) == -1)
+		if (read(fd, sh_addr, sh_size) == -1)
 			error("read failed (%s).\n", strerror(errno));
 		if (shs_type == SHT_SYMTAB /* || shs_type == SHT_DYNSYM */) {
 			(void) printf (", not stripped");
@@ -177,11 +186,13 @@ dophn_exec(class, swap, fd, off, num, size)
 	char *linking_style = "statically";
 	char *shared_libraries = "";
 
+	if (size != ph_size)
+		error("corrupted program header size.\n");
 	if (lseek(fd, off, SEEK_SET) == -1)
 		error("lseek failed (%s).\n", strerror(errno));
 
   	for ( ; num; num--) {
-  		if (read(fd, ph_addr, size) == -1)
+  		if (read(fd, ph_addr, ph_size) == -1)
   			error("read failed (%s).\n", strerror(errno));
 
 		switch (ph_type) {
@@ -253,13 +264,15 @@ dophn_core(class, swap, fd, off, num, size)
 	int bufsize;
 	int is_freebsd;
 
+	if (size != ph_size)
+		error("corrupted program header size.\n");
 	/*
 	 * Loop through all the program headers.
 	 */
 	for ( ; num; num--) {
 		if (lseek(fd, off, SEEK_SET) == -1)
 			error("lseek failed (%s).\n", strerror(errno));
-		if (read(fd, ph_addr, size) == -1)
+		if (read(fd, ph_addr, ph_size) == -1)
 			error("read failed (%s).\n", strerror(errno));
 		off += size;
 		if (ph_type != PT_NOTE)

+ 5 - 3
softmagic.c

@@ -115,7 +115,8 @@ match(magic, nmagic, s, nbytes)
 	int firstline = 1; /* a flag to print X\n  X\n- X */
 
 	if (tmpoff == NULL)
-		if ((tmpoff = (int32 *) malloc(tmplen = 20)) == NULL)
+		if ((tmpoff = (int32 *) malloc(
+		    (tmplen = 20) * sizeof(*tmpoff))) == NULL)
 			error("out of memory\n");
 
 	for (magindex = 0; magindex < nmagic; magindex++) {
@@ -147,7 +148,7 @@ match(magic, nmagic, s, nbytes)
 		/* and any continuations that match */
 		if (++cont_level >= tmplen)
 			if ((tmpoff = (int32 *) realloc(tmpoff,
-						       tmplen += 20)) == NULL)
+			    (tmplen += 20) * sizeof(*tmpoff))) == NULL)
 				error("out of memory\n");
 		while (magic[magindex+1].cont_level != 0 && 
 		       ++magindex < nmagic) {
@@ -194,7 +195,8 @@ match(magic, nmagic, s, nbytes)
 					if (++cont_level >= tmplen)
 						if ((tmpoff = 
 						    (int32 *) realloc(tmpoff,
-						    tmplen += 20)) == NULL)
+						    (tmplen += 20)
+						    * sizeof(*tmpoff))) == NULL)
 							error("out of memory\n");
 				}
 				if (magic[magindex].flag & OFFADD) {