Skip to content

Commit

Permalink
Fix multiple integer overflow bugs reported by @_icewall
Browse files Browse the repository at this point in the history
  • Loading branch information
plusvic committed Oct 30, 2015
1 parent 0d02651 commit 5d6d8b1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 17 deletions.
10 changes: 7 additions & 3 deletions libyara/include/yara/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,25 @@ typedef uint64_t elf64_xword_t;
#define ELF_SHF_ALLOC 0x2 // Section is present during execution
#define ELF_SHF_EXECINSTR 0x4 // Section contains executable instructions

#define ELF_SHN_LORESERVE 0xFF00

#define ELF_PT_NULL 0 // The array element is unused
#define ELF_PT_LOAD 1 // Loadable segment
#define ELF_PT_LOAD 1 // Loadable segment
#define ELF_PT_DYNAMIC 2 // Segment contains dynamic linking info
#define ELF_PT_INTERP 3 // Contains interpreter pathname
#define ELF_PT_NOTE 4 // Location & size of auxiliary info
#define ELF_PT_SHLIB 5 // Reserved, unspecified semantics
#define ELF_PT_PHDR 6 // Location and size of program header table
#define ELF_PT_TLS 7 // Thread-Local Storage
#define ELF_PT_TLS 7 // Thread-Local Storage
#define ELF_PT_GNU_EH_FRAME 0x6474e550
#define ELF_PT_GNU_STACK 0x6474e551

#define ELF_PF_X 0x1 // Segment is executable
#define ELF_PF_W 0x2 // Segment is writable
#define ELF_PF_R 0x4 // Segment is readable

#define ELF_PN_XNUM 0xffff

#pragma pack(push,1)

typedef struct
Expand Down
15 changes: 10 additions & 5 deletions libyara/modules/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ uint64_t elf_rva_to_offset_##bits( \
{ \
if (section->type != ELF_SHT_NULL && \
section->type != ELF_SHT_NOBITS && \
section->size <= elf_size && \
rva >= section->addr && \
rva < section->addr + section->size) \
rva < section->addr + section->size) \
{ \
return section->offset + (rva - section->addr); \
} \
Expand Down Expand Up @@ -127,7 +128,8 @@ void parse_elf_header_##bits( \
elf_obj, "entry_point"); \
} \
\
if (elf->sh_str_table_index < elf->sh_entry_count && \
if (elf->sh_entry_count < ELF_SHN_LORESERVE && \
elf->sh_str_table_index < elf->sh_entry_count && \
elf->sh_offset < elf_size && \
elf->sh_offset + elf->sh_entry_count * \
sizeof(elf##bits##_section_header_t) <= elf_size) \
Expand All @@ -147,7 +149,8 @@ void parse_elf_header_##bits( \
set_integer(section->size, elf_obj, "sections[%i].size", i); \
set_integer(section->offset, elf_obj, "sections[%i].offset", i); \
\
if (str_table != NULL && \
if (section->name < elf_size && \
str_table > (char*) elf && \
str_table + section->name < (char*) elf + elf_size) \
{ \
set_string(str_table + section->name, elf_obj, "sections[%i].name", i);\
Expand All @@ -157,8 +160,10 @@ void parse_elf_header_##bits( \
} \
} \
\
if(elf->ph_entry_count && \
elf->ph_offset + elf->ph_entry_count * \
if (elf->ph_entry_count > 0 && \
elf->ph_entry_count < ELF_PN_XNUM && \
elf->ph_offset < elf_size && \
elf->ph_offset + elf->ph_entry_count * \
sizeof(elf##bits##_program_header_t) <= elf_size) \
{ \
segment = (elf##bits##_program_header_t*) \
Expand Down
24 changes: 15 additions & 9 deletions libyara/modules/pe.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ limitations under the License.


#define fits_in_pe(pe, pointer, size) \
(size <= pe->data_size && \
(uint8_t*)(pointer) >= pe->data && \
(uint8_t*)(pointer) <= pe->data + pe->data_size - size)
((size_t) size <= pe->data_size && \
(uint8_t*) (pointer) >= pe->data && \
(uint8_t*) (pointer) <= pe->data + pe->data_size - size)


#define struct_fits_in_pe(pe, pointer, struct_type) \
Expand Down Expand Up @@ -1097,7 +1097,7 @@ IMPORTED_DLL* pe_parse_imports(
void pe_parse_certificates(
PE* pe)
{
int i, counter = 0;
int i, counter = 0;
uint8_t* eod;

PWIN_CERTIFICATE win_cert;
Expand Down Expand Up @@ -1134,7 +1134,10 @@ void pe_parse_certificates(
//

while (struct_fits_in_pe(pe, win_cert, WIN_CERTIFICATE) &&
fits_in_pe(pe, win_cert->Certificate, win_cert->Length) &&
win_cert->Length >= 8 &&
(uint8_t*) win_cert + sizeof(WIN_CERTIFICATE) <= eod &&
(uint8_t*) win_cert->Certificate < eod &&
(uint8_t*) win_cert->Certificate + win_cert->Length - 8 <= eod)
{
BIO* cert_bio;
Expand Down Expand Up @@ -1207,7 +1210,10 @@ void pe_parse_certificates(

serial = X509_get_serialNumber(cert);

if (serial->length > 0)
// According to X.509 specification the maximum length for the serial
// number is 20 octets.

if (serial->length > 0 && serial->length <= 20)
{
// Convert serial number to "common" string format: 00:01:02:03:04...
// For each byte in the integer to convert to hexlified format we
Expand Down Expand Up @@ -1415,7 +1421,7 @@ define_function(section_index_addr)
int64_t i;
int64_t offset;
int64_t size;

int64_t addr = integer_argument(1);
int64_t n = get_integer(module, "number_of_sections");

Expand Down Expand Up @@ -1451,7 +1457,7 @@ define_function(section_index_name)

int64_t n = get_integer(module, "number_of_sections");
int64_t i;

if (is_undefined(module, "number_of_sections"))
return_integer(UNDEFINED);

Expand Down Expand Up @@ -1566,7 +1572,7 @@ define_function(imphash)
dll = pe->imported_dlls;

while (dll)
{
{
IMPORTED_FUNCTION* func;

size_t dll_name_len;
Expand Down Expand Up @@ -1755,7 +1761,7 @@ define_function(locale)
{
YR_OBJECT* module = module();
PE* pe = (PE*) module->data;

uint64_t locale = integer_argument(1);
int64_t n, i;

Expand Down

0 comments on commit 5d6d8b1

Please sign in to comment.