From acede72e9bae3a133baf19cee1e6ed252754f9d4 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sat, 9 May 2015 06:49:45 -0700 Subject: [PATCH] Check ph.c_len. CERT-FI 829767 id:000002,sig:06,src:000000,op:havoc,rep:1 --- src/p_mach.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 6523154a..a143c801 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -1253,6 +1253,12 @@ void PackMachBase::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e #define WANT_MACH_HEADER_ENUM 1 #include "p_mach_enum.h" +static unsigned +umin(unsigned a, unsigned b) +{ + return (a <= b) ? a : b; +} + template void PackMachBase::unpack(OutputFile *fo) { @@ -1287,6 +1293,8 @@ void PackMachBase::unpack(OutputFile *fo) fi->readx(&bhdr, sizeof(bhdr)); ph.u_len = get_te32(&bhdr.sz_unc); ph.c_len = get_te32(&bhdr.sz_cpr); + if (file_size < ph.c_len) + throwCantUnpack("file header corrupted"); ph.method = bhdr.b_method; ph.filter = bhdr.b_ftid; ph.filter_cto = bhdr.b_cto8; @@ -1300,9 +1308,10 @@ void PackMachBase::unpack(OutputFile *fo) msegcmd = new Mach_segment_command[ncmds]; unsigned char const *ptr = (unsigned char const *)(1+mhdr); for (unsigned j= 0; j < ncmds; ++j) { - msegcmd[j] = *(Mach_segment_command const *)ptr; + memcpy(&msegcmd[j], ptr, umin(sizeof(Mach_segment_command), + ((Mach_segment_command const *)ptr)->cmdsize)); ptr += (unsigned) ((Mach_segment_command const *)ptr)->cmdsize; - if ((ptr - (unsigned char const *)(1+mhdr)) > fi->st_size()) { + if ((ptr - (unsigned char const *)mhdr) > ph.u_len) { throwCantUnpack("cmdsize"); } }