From 2161cff511c87cdeb395ce85209e7d0df6696c05 Mon Sep 17 00:00:00 2001 From: -TOSH- Date: Sun, 5 Apr 2015 18:01:11 +0200 Subject: [PATCH] Fix segfault in Mach-O parser --- api/binfmt/bin_macho32.c | 7 +++++-- api/binfmt/bin_macho64.c | 11 +++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/api/binfmt/bin_macho32.c b/api/binfmt/bin_macho32.c index 724c82c..1a470cf 100644 --- a/api/binfmt/bin_macho32.c +++ b/api/binfmt/bin_macho32.c @@ -154,7 +154,7 @@ static int r_binfmt_macho32_check_segment(r_binfmt_s *bin, r_binfmt_macho32_segm static int r_binfmt_macho32_check(r_binfmt_s *bin) { r_binfmt_macho32_header_s *hdr; r_binfmt_macho_cmd_s *cmd; - u32 tmp, i, cmd_num, off, type; + u32 tmp, i, cmd_num, cmd_size, off, type; /* Already checked in r_binfmt_machoXX_is(), but if the check is removed in the future, the @@ -186,7 +186,10 @@ static int r_binfmt_macho32_check(r_binfmt_s *bin) { return 0; } - if(!r_utils_add32(&off, off, r_binfmt_get_int32((byte_t*)&cmd->size, bin->endian))) + cmd_size = r_binfmt_get_int32((byte_t*)&cmd->size, bin->endian); + if(!cmd_size) + return 0; + if(!r_utils_add32(&off, off, cmd_size)) return 0; } diff --git a/api/binfmt/bin_macho64.c b/api/binfmt/bin_macho64.c index 0921399..a3d31c0 100644 --- a/api/binfmt/bin_macho64.c +++ b/api/binfmt/bin_macho64.c @@ -127,7 +127,7 @@ static void r_binfmt_macho64_load_mlist(r_binfmt_s *bin) { /* Check the fields of the machoXX segment */ static int r_binfmt_macho64_check_segment(r_binfmt_s *bin, r_binfmt_macho64_segment_s *seg) { - u32 filesz, fileoff; + u64 filesz, fileoff; u64 off; off = ((byte_t*)seg) - bin->mapped; @@ -154,7 +154,7 @@ static int r_binfmt_macho64_check_segment(r_binfmt_s *bin, r_binfmt_macho64_segm static int r_binfmt_macho64_check(r_binfmt_s *bin) { r_binfmt_macho64_header_s *hdr; r_binfmt_macho_cmd_s *cmd; - u32 tmp, i, cmd_num, off, type; + u32 tmp, i, cmd_num, cmd_size, off, type; /* Already checked in r_binfmt_machoXX_is(), but if the check is removed in the future, the @@ -181,12 +181,15 @@ static int r_binfmt_macho64_check(r_binfmt_s *bin) { /* Now check command */ type = r_binfmt_get_int32((byte_t*)&cmd->type, bin->endian); - if(type == R_BINFMT_MACHO_CMD_TYPE_SEGMENT) { + if(type == R_BINFMT_MACHO_CMD_TYPE_SEGMENT64) { if(!r_binfmt_macho64_check_segment(bin, (r_binfmt_macho64_segment_s*)cmd)) return 0; } - if(!r_utils_add32(&off, off, r_binfmt_get_int32((byte_t*)&cmd->size, bin->endian))) + cmd_size = r_binfmt_get_int32((byte_t*)&cmd->size, bin->endian); + if(!cmd_size) + return 0; + if(!r_utils_add32(&off, off, cmd_size)) return 0; }