[syslinux] [PATCH] isohybrid: fix overflow on 32 bit system

Kai Kang kai.kang at windriver.com
Sun May 11 18:56:03 PDT 2014


When call isohybrid with option '-u', it overflows on a 32 bits host. It
seeks to 512 bytes before the end of the image to install gpt header. If
the size of image is larger than LONG_MAX, it overflows fseek() and
cause error:

isohybrid: wrlinux-image-x86-64-20140505110100.iso: seek error - 8: Invalid argument

Check the offset and call fseek() multi-times if offset is too large.

Signed-off-by: Kai Kang <kai.kang at windriver.com>
---
 utils/isohybrid.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/utils/isohybrid.c b/utils/isohybrid.c
index 410bb60..4047287 100644
--- a/utils/isohybrid.c
+++ b/utils/isohybrid.c
@@ -34,6 +34,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <limits.h>
 #include <sys/stat.h>
 #include <inttypes.h>
 #include <uuid/uuid.h>
@@ -888,7 +889,7 @@ main(int argc, char *argv[])
     FILE *fp = NULL;
     uint8_t *buf = NULL, *bufz = NULL;
     int cylsize = 0, frac = 0;
-    size_t orig_gpt_size, free_space, gpt_size;
+    size_t orig_gpt_size, free_space, gpt_size, real_offset;
     struct iso_primary_descriptor descriptor;
 
     prog = strcpy(alloca(strlen(argv[0]) + 1), argv[0]);
@@ -1125,9 +1126,16 @@ main(int argc, char *argv[])
 	 * Seek far enough back that the gpt header is 512 bytes before the
 	 * end of the image
 	 */
+	real_offset = (isostat.st_size + padding) - orig_gpt_size - 512;
 
-	if (fseek(fp, (isostat.st_size + padding) - orig_gpt_size - 512,
-		  SEEK_SET))
+	fseek(fp, 0, SEEK_SET);
+	while (real_offset > LONG_MAX) {
+		if (fseek(fp, LONG_MAX, SEEK_CUR))
+			err(1, "%s: seek error - 8", argv[0]);
+		real_offset -= LONG_MAX;
+	}
+
+	if (fseek(fp, real_offset, SEEK_CUR))
 	    err(1, "%s: seek error - 8", argv[0]);
 
 	if (fwrite(buf, sizeof(char), orig_gpt_size, fp) != orig_gpt_size)
-- 
1.9.1



More information about the Syslinux mailing list