@@ -59,9 +59,31 @@ Error DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
59
59
// the segment selectors are omitted from all tuples, including
60
60
// the terminating tuple.
61
61
62
+ constexpr unsigned CommonFieldsLength = 2 + // Version
63
+ 1 + // Address Size
64
+ 1 ; // Segment Selector Size
65
+ constexpr unsigned DWARF32HeaderLength =
66
+ dwarf::getUnitLengthFieldByteSize (dwarf::DWARF32) + CommonFieldsLength +
67
+ dwarf::getDwarfOffsetByteSize (dwarf::DWARF32); // Debug Info Offset
68
+ constexpr unsigned DWARF64HeaderLength =
69
+ dwarf::getUnitLengthFieldByteSize (dwarf::DWARF64) + CommonFieldsLength +
70
+ dwarf::getDwarfOffsetByteSize (dwarf::DWARF64); // Debug Info Offset
71
+
72
+ if (!data.isValidOffsetForDataOfSize (Offset, DWARF32HeaderLength))
73
+ return createStringError (errc::invalid_argument,
74
+ " section is not large enough to contain "
75
+ " an address range table at offset 0x%" PRIx64,
76
+ Offset);
77
+
62
78
dwarf::DwarfFormat format = dwarf::DWARF32;
63
79
HeaderData.Length = data.getU32 (offset_ptr);
64
80
if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) {
81
+ if (!data.isValidOffsetForDataOfSize (Offset, DWARF64HeaderLength))
82
+ return createStringError (
83
+ errc::invalid_argument,
84
+ " section is not large enough to contain a DWARF64 "
85
+ " address range table at offset 0x%" PRIx64,
86
+ Offset);
65
87
HeaderData.Length = data.getU64 (offset_ptr);
66
88
format = dwarf::DWARF64;
67
89
} else if (HeaderData.Length >= dwarf::DW_LENGTH_lo_reserved) {
@@ -91,17 +113,38 @@ Error DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
91
113
" has unsupported address size: %d "
92
114
" (4 and 8 supported)" ,
93
115
Offset, HeaderData.AddrSize );
116
+ if (HeaderData.SegSize != 0 )
117
+ return createStringError (errc::not_supported,
118
+ " non-zero segment selector size in address range "
119
+ " table at offset 0x%" PRIx64 " is not supported" ,
120
+ Offset);
94
121
95
- // The first tuple following the header in each set begins at an offset
96
- // that is a multiple of the size of a single tuple (that is, twice the
97
- // size of an address). The header is padded, if necessary, to the
98
- // appropriate boundary.
99
- const uint32_t header_size = *offset_ptr - Offset;
122
+ // The first tuple following the header in each set begins at an offset that
123
+ // is a multiple of the size of a single tuple (that is, twice the size of
124
+ // an address because we do not support non-zero segment selector sizes).
125
+ // Therefore, the full length should also be a multiple of the tuple size.
100
126
const uint32_t tuple_size = HeaderData.AddrSize * 2 ;
127
+ if (full_length % tuple_size != 0 )
128
+ return createStringError (
129
+ errc::invalid_argument,
130
+ " address range table at offset 0x%" PRIx64
131
+ " has length that is not a multiple of the tuple size" ,
132
+ Offset);
133
+
134
+ // The header is padded, if necessary, to the appropriate boundary.
135
+ const uint32_t header_size = *offset_ptr - Offset;
101
136
uint32_t first_tuple_offset = 0 ;
102
137
while (first_tuple_offset < header_size)
103
138
first_tuple_offset += tuple_size;
104
139
140
+ // There should be space for at least one tuple.
141
+ if (full_length <= first_tuple_offset)
142
+ return createStringError (
143
+ errc::invalid_argument,
144
+ " address range table at offset 0x%" PRIx64
145
+ " has an insufficient length to contain any entries" ,
146
+ Offset);
147
+
105
148
*offset_ptr = Offset + first_tuple_offset;
106
149
107
150
Descriptor arangeDescriptor;
@@ -111,14 +154,23 @@ Error DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
111
154
" Different datatypes for addresses and sizes!" );
112
155
assert (sizeof (arangeDescriptor.Address ) >= HeaderData.AddrSize );
113
156
114
- while (data.isValidOffset (*offset_ptr)) {
157
+ uint64_t end_offset = Offset + full_length;
158
+ while (*offset_ptr < end_offset) {
115
159
arangeDescriptor.Address = data.getUnsigned (offset_ptr, HeaderData.AddrSize );
116
160
arangeDescriptor.Length = data.getUnsigned (offset_ptr, HeaderData.AddrSize );
117
161
118
- // Each set of tuples is terminated by a 0 for the address and 0
119
- // for the length.
120
- if (arangeDescriptor.Address == 0 && arangeDescriptor.Length == 0 )
121
- return ErrorSuccess ();
162
+ if (arangeDescriptor.Length == 0 ) {
163
+ // Each set of tuples is terminated by a 0 for the address and 0
164
+ // for the length.
165
+ if (arangeDescriptor.Address == 0 && *offset_ptr == end_offset)
166
+ return ErrorSuccess ();
167
+ return createStringError (
168
+ errc::invalid_argument,
169
+ " address range table at offset 0x%" PRIx64
170
+ " has an invalid tuple (length = 0) at offset 0x%" PRIx64,
171
+ Offset, *offset_ptr - tuple_size);
172
+ }
173
+
122
174
ArangeDescriptors.push_back (arangeDescriptor);
123
175
}
124
176
0 commit comments