X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libdw%2Fdwarf_formblock.c;h=13f9e72a2a13c6751c00db2160e63117eb29cbe2;hb=82c3b58b54026d061a4d81ad95f3023d5d883ab2;hp=799d8776df8b96095dfb7bea4d649b1915266d7d;hpb=a286dd013ef8d46edf013efc0908822a59d8ac81;p=platform%2Fupstream%2Felfutils.git diff --git a/libdw/dwarf_formblock.c b/libdw/dwarf_formblock.c index 799d877..13f9e72 100644 --- a/libdw/dwarf_formblock.c +++ b/libdw/dwarf_formblock.c @@ -1,5 +1,5 @@ /* Return block represented by attribute. - Copyright (C) 2004-2010 Red Hat, Inc. + Copyright (C) 2004-2010, 2014 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 2004. @@ -36,36 +36,42 @@ int -dwarf_formblock (attr, return_block) - Dwarf_Attribute *attr; - Dwarf_Block *return_block; +dwarf_formblock (Dwarf_Attribute *attr, Dwarf_Block *return_block) { if (attr == NULL) return -1; - const unsigned char *datap; + const unsigned char *datap = attr->valp; + const unsigned char *endp = attr->cu->endp; switch (attr->form) { case DW_FORM_block1: + if (unlikely (endp - datap < 1)) + goto invalid; return_block->length = *(uint8_t *) attr->valp; return_block->data = attr->valp + 1; break; case DW_FORM_block2: + if (unlikely (endp - datap < 2)) + goto invalid; return_block->length = read_2ubyte_unaligned (attr->cu->dbg, attr->valp); return_block->data = attr->valp + 2; break; case DW_FORM_block4: + if (unlikely (endp - datap < 4)) + goto invalid; return_block->length = read_4ubyte_unaligned (attr->cu->dbg, attr->valp); return_block->data = attr->valp + 4; break; case DW_FORM_block: case DW_FORM_exprloc: - datap = attr->valp; - get_uleb128 (return_block->length, datap); + if (unlikely (endp - datap < 1)) + goto invalid; + get_uleb128 (return_block->length, datap, endp); return_block->data = (unsigned char *) datap; break; @@ -74,12 +80,10 @@ dwarf_formblock (attr, return_block) return -1; } - if (unlikely (cu_data (attr->cu)->d_size - - (return_block->data - - (unsigned char *) cu_data (attr->cu)->d_buf) - < return_block->length)) + if (unlikely (return_block->length > (size_t) (endp - return_block->data))) { /* Block does not fit. */ + invalid: __libdw_seterrno (DWARF_E_INVALID_DWARF); return -1; }