@@ -64,17 +64,25 @@ void MachHeader::Parse(void *offset,NodeContextPtr& ctx) {
6464 throw NodeException (" Malformed Mach-O: load commands exceed file size" );
6565 }
6666
67+ const uint32_t cmd_align = is64_ ? 8 : 4 ;
6768 qv_load_command *first_cmd = reinterpret_cast <qv_load_command*>((char *)offset + cur_datasize);
6869 qv_load_command *cur_cmd = first_cmd;
6970 uint64_t parsed_size = 0 ;
7071 for (uint32_t index = 0 ; index < cmd_count; ++index){
7172 if (parsed_size + sizeof (qv_load_command) > sizeofcmds) {
7273 throw NodeException (" Malformed Mach-O: truncated load command" );
7374 }
74- if (cur_cmd->cmdsize < sizeof (qv_load_command)) {
75+ // Load commands may sit at a misaligned address in a crafted file, so
76+ // read the header through an aligned copy instead of dereferencing.
77+ qv_load_command lc_head{};
78+ memcpy (&lc_head, cur_cmd, sizeof (qv_load_command));
79+ if (lc_head.cmdsize < sizeof (qv_load_command)) {
7580 throw NodeException (" Malformed Mach-O: invalid load command size" );
7681 }
77- if (parsed_size + cur_cmd->cmdsize > sizeofcmds) {
82+ if (lc_head.cmdsize % cmd_align != 0 ) {
83+ throw NodeException (" Malformed Mach-O: misaligned load command size" );
84+ }
85+ if (parsed_size + lc_head.cmdsize > sizeofcmds) {
7886 throw NodeException (" Malformed Mach-O: load command size overflow" );
7987 }
8088
@@ -83,8 +91,8 @@ void MachHeader::Parse(void *offset,NodeContextPtr& ctx) {
8391 loadcmds_.push_back (cmd);
8492
8593 // next
86- parsed_size += cur_cmd-> cmdsize ;
87- cur_cmd = reinterpret_cast <qv_load_command*>((char *)cur_cmd + cur_cmd-> cmdsize );
94+ parsed_size += lc_head. cmdsize ;
95+ cur_cmd = reinterpret_cast <qv_load_command*>((char *)cur_cmd + lc_head. cmdsize );
8896 }
8997}
9098
0 commit comments