unsigned int nameoff;
unsigned int namelen;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
nameoff = bfd_h_get_32 (abfd, raw.str);
+ if (nameoff > command->len)
+ return FALSE;
cmd->name_offset = nameoff;
namelen = command->len - nameoff;
unsigned int nameoff;
unsigned int namelen;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
switch (command->type)
{
case BFD_MACH_O_LC_LOAD_DYLIB:
return FALSE;
nameoff = bfd_h_get_32 (abfd, raw.name);
+ if (nameoff > command->len)
+ return FALSE;
cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
unsigned int str_len;
unsigned char *str;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
bfd_mach_o_prebind_cksum_command *cmd = &command->command.prebind_cksum;
struct mach_o_prebind_cksum_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
bfd_mach_o_twolevel_hints_command *cmd = &command->command.twolevel_hints;
struct mach_o_twolevel_hints_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
unsigned int nameoff;
unsigned int namelen;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
nameoff = bfd_h_get_32 (abfd, raw.name);
+ if (nameoff > command->len)
+ return FALSE;
fvm->minor_version = bfd_h_get_32 (abfd, raw.minor_version);
fvm->header_addr = bfd_h_get_32 (abfd, raw.header_addr);
unsigned int offset;
unsigned int nflavours;
unsigned int i;
+ struct mach_o_thread_command_external raw;
BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
|| (command->type == BFD_MACH_O_LC_UNIXTHREAD));
/* Count the number of threads. */
offset = 8;
nflavours = 0;
- while (offset != command->len)
+ while (offset + sizeof (raw) <= command->len)
{
- struct mach_o_thread_command_external raw;
-
- if (offset >= command->len)
- return FALSE;
+ unsigned int count;
if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
- offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
+ count = bfd_h_get_32 (abfd, raw.count);
+ if (count > (unsigned) -1 / 4
+ || command->len - (offset + sizeof (raw)) < count * 4)
+ return FALSE;
+ offset += sizeof (raw) + count * 4;
nflavours++;
}
+ if (nflavours == 0 || offset != command->len)
+ return FALSE;
/* Allocate threads. */
- cmd->flavours = bfd_alloc2
- (abfd, nflavours, sizeof (bfd_mach_o_thread_flavour));
+ cmd->flavours = bfd_alloc2 (abfd, nflavours,
+ sizeof (bfd_mach_o_thread_flavour));
if (cmd->flavours == NULL)
return FALSE;
cmd->nflavours = nflavours;
nflavours = 0;
while (offset != command->len)
{
- struct mach_o_thread_command_external raw;
-
- if (offset >= command->len)
- return FALSE;
-
- if (nflavours >= cmd->nflavours)
- return FALSE;
-
if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
{
struct mach_o_dysymtab_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
+ if (command->len < 16 + 8)
+ return FALSE;
if (bfd_bread (cmd->uuid, 16, abfd) != 16)
return FALSE;
bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
struct mach_o_linkedit_data_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
struct mach_o_str_command_external raw;
unsigned long off;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
off = bfd_get_32 (abfd, raw.str);
+ if (off > command->len)
+ return FALSE;
+
cmd->stroff = command->offset + off;
cmd->str_len = command->len - off;
cmd->str = bfd_alloc (abfd, cmd->str_len);
bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
struct mach_o_dyld_info_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
bfd_mach_o_version_min_command *cmd = &command->command.version_min;
struct mach_o_version_min_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
bfd_mach_o_encryption_info_command *cmd = &command->command.encryption_info;
struct mach_o_encryption_info_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
bfd_mach_o_encryption_info_command *cmd = &command->command.encryption_info;
struct mach_o_encryption_info_64_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
bfd_mach_o_main_command *cmd = &command->command.main;
struct mach_o_entry_point_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
struct mach_o_source_version_command_external raw;
bfd_uint64_t ver;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
bfd_mach_o_note_command *cmd = &command->command.note;
struct mach_o_note_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
bfd_mach_o_build_version_command *cmd = &command->command.build_version;
struct mach_o_build_version_command_external raw;
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
+ if (command->len < sizeof (raw) + 8)
+ return FALSE;
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
return FALSE;
cmd = bfd_h_get_32 (abfd, raw.cmd);
- command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
+ command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
command->len = bfd_h_get_32 (abfd, raw.cmdsize);
+ if (command->len < 8 || command->len % 4 != 0)
+ return FALSE;
switch (command->type)
{