Skip to content

Commit 4eaf3a7

Browse files
authored
[readobj][ELF][AArch64] Handle misformed AArch64 build attribute section (#134888)
Report an error when the .ARM.attributes section for AArch64 is malformed or violates expected format.
1 parent 0c21d6b commit 4eaf3a7

6 files changed

+153
-3
lines changed

llvm/lib/Support/ELFAttrParserExtended.cpp

+31-3
Original file line numberDiff line numberDiff line change
@@ -103,26 +103,48 @@ Error ELFExtendedAttrParser::parse(ArrayRef<uint8_t> Section,
103103

104104
// Get format-version
105105
uint8_t FormatVersion = De.getU8(Cursor);
106+
if (!Cursor)
107+
return Cursor.takeError();
106108
if (ELFAttrs::Format_Version != FormatVersion)
107109
return createStringError(errc::invalid_argument,
108110
"unrecognized format-version: 0x" +
109111
utohexstr(FormatVersion));
110112

111113
while (!De.eof(Cursor)) {
112114
uint32_t ExtBASubsectionLength = De.getU32(Cursor);
113-
// Minimal valid Extended Build Attributes subsection header size is at
115+
if (!Cursor)
116+
return Cursor.takeError();
117+
// Minimal valid Extended Build Attributes subsection size is at
114118
// least 8: length(4) name(at least a single char + null) optionality(1) and
115119
// type(1)
116-
if (ExtBASubsectionLength < 8)
120+
// Extended Build Attributes subsection has to fit inside the section.
121+
if (ExtBASubsectionLength < 8 ||
122+
ExtBASubsectionLength > (Section.size() - Cursor.tell() + 4))
117123
return createStringError(
118124
errc::invalid_argument,
119125
"invalid Extended Build Attributes subsection size at offset: " +
120126
utohexstr(Cursor.tell() - 4));
121127

122128
StringRef VendorName = De.getCStrRef(Cursor);
129+
if (!Cursor)
130+
return Cursor.takeError();
123131
uint8_t IsOptional = De.getU8(Cursor);
132+
if (!Cursor)
133+
return Cursor.takeError();
134+
if (!(0 == IsOptional || 1 == IsOptional))
135+
return createStringError(
136+
errc::invalid_argument,
137+
"\ninvalid Optionality at offset " + utohexstr(Cursor.tell() - 4) +
138+
": " + utohexstr(IsOptional) + " (Options are 1|0)");
124139
StringRef IsOptionalStr = IsOptional ? "optional" : "required";
125140
uint8_t Type = De.getU8(Cursor);
141+
if (!Cursor)
142+
return Cursor.takeError();
143+
if (!(0 == Type || 1 == Type))
144+
return createStringError(errc::invalid_argument,
145+
"\ninvalid Type at offset " +
146+
utohexstr(Cursor.tell() - 4) + ": " +
147+
utohexstr(Type) + " (Options are 1|0)");
126148
StringRef TypeStr = Type ? "ntbs" : "uleb128";
127149

128150
BuildAttributeSubSection BASubSection;
@@ -144,23 +166,29 @@ Error ELFExtendedAttrParser::parse(ArrayRef<uint8_t> Section,
144166
// Offset in Section
145167
uint64_t OffsetInSection = Cursor.tell();
146168
// Size: 4 bytes, Vendor Name: VendorName.size() + 1 (null termination),
147-
// optionality: 1, size: 1
169+
// optionality: 1, type: 1
148170
uint32_t BytesAllButAttributes = 4 + (VendorName.size() + 1) + 1 + 1;
149171
while (Cursor.tell() <
150172
(OffsetInSection + ExtBASubsectionLength - BytesAllButAttributes)) {
151173

152174
uint64_t Tag = De.getULEB128(Cursor);
175+
if (!Cursor)
176+
return Cursor.takeError();
153177

154178
StringRef TagName = getTagName(VendorName, Tag);
155179

156180
uint64_t ValueInt = 0;
157181
std::string ValueStr = "";
158182
if (Type) { // type==1 --> ntbs
159183
ValueStr = De.getCStrRef(Cursor);
184+
if (!Cursor)
185+
return Cursor.takeError();
160186
if (Sw)
161187
Sw->printString("" != TagName ? TagName : utostr(Tag), ValueStr);
162188
} else { // type==0 --> uleb128
163189
ValueInt = De.getULEB128(Cursor);
190+
if (!Cursor)
191+
return Cursor.takeError();
164192
if (Sw)
165193
Sw->printNumber("" != TagName ? TagName : utostr(Tag), ValueInt);
166194
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# RUN: yaml2obj %s -o %t.o
2+
# RUN: not llvm-readobj --arch-specific %t.o %null 2>&1 | FileCheck %s
3+
4+
# CHECK: unable to dump attributes from the Unknown section with index 1: invalid Extended Build Attributes subsection size at offset: 1A
5+
6+
# Indicated size is longer than actual size.
7+
# The size is indicated by the '99' in the sequence '...0101020199...' should be 23
8+
--- !ELF
9+
FileHeader:
10+
Class: ELFCLASS64
11+
Data: ELFDATA2LSB
12+
OSABI: ELFOSABI_NONE
13+
Type: ET_REL
14+
Machine: EM_AARCH64
15+
Entry: 0x0
16+
17+
Sections:
18+
- Name: .ARM.attributes
19+
Type: 0x70000003 # SHT_LOPROC + 3
20+
AddressAlign: 1
21+
Offset: 0x40
22+
Size: 0x3d
23+
Content: "411900000061656162695f7061757468616269000000010102019900000061656162695f666561747572655f616e645f62697473000100000101010201"
24+
...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# RUN: yaml2obj %s -o %t.o
2+
# RUN: not llvm-readobj --arch-specific %t.o %null 2>&1 | FileCheck %s
3+
4+
# CHECK: unable to dump attributes from the Unknown section with index 1: invalid Extended Build Attributes subsection size at offset: 3B
5+
6+
# Indicated size is shorter than actual size.
7+
# The size is indicated by the '20' in the sequence '...0101020120...' should be 23
8+
--- !ELF
9+
FileHeader:
10+
Class: ELFCLASS64
11+
Data: ELFDATA2LSB
12+
OSABI: ELFOSABI_NONE
13+
Type: ET_REL
14+
Machine: EM_AARCH64
15+
Entry: 0x0
16+
17+
Sections:
18+
- Name: .ARM.attributes
19+
Type: 0x70000003 # SHT_LOPROC + 3
20+
AddressAlign: 1
21+
Offset: 0x40
22+
Size: 0x41
23+
Content: "411900000061656162695f7061757468616269000000010102012000000061656162695f666561747572655f616e645f6269747300010000010101020000"
24+
...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# RUN: yaml2obj %s -o %t.o
2+
# RUN: not llvm-readobj --arch-specific %t.o %null 2>&1 | FileCheck %s
3+
4+
# CHECK: BuildAttributes {
5+
# CHECK-NEXT: FormatVersion: 0x41
6+
# CHECK-NEXT: unable to dump attributes from the Unknown section with index 1:
7+
# CHECK-NEXT: invalid Type at offset 12: 9 (Options are 1|0)
8+
9+
# Type are not 0 or 1
10+
# Type is indicated by the '09' in the sequence '...69000109...' should be 00 or 01
11+
--- !ELF
12+
FileHeader:
13+
Class: ELFCLASS64
14+
Data: ELFDATA2LSB
15+
OSABI: ELFOSABI_NONE
16+
Type: ET_REL
17+
Machine: EM_AARCH64
18+
Entry: 0x0
19+
20+
Sections:
21+
- Name: .ARM.attributes
22+
Type: 0x70000003 # SHT_LOPROC + 3
23+
AddressAlign: 1
24+
Offset: 0x40
25+
Size: 0x3d
26+
Content: "411900000061656162695f7061757468616269000109010102012300000061656162695f666561747572655f616e645f62697473000100000101010201"
27+
...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# RUN: yaml2obj %s -o %t.o
2+
# RUN: not llvm-readobj --arch-specific %t.o %null 2>&1 | FileCheck %s
3+
4+
# CHECK: unable to dump attributes from the Unknown section with index 1: invalid Extended Build Attributes subsection size at offset: 3D
5+
6+
# ULEB values are overflowing.
7+
# Those are the trailing '000' in the sequence '...00010101020000' should be '...000101010201'
8+
--- !ELF
9+
FileHeader:
10+
Class: ELFCLASS64
11+
Data: ELFDATA2LSB
12+
OSABI: ELFOSABI_NONE
13+
Type: ET_REL
14+
Machine: EM_AARCH64
15+
Entry: 0x0
16+
17+
Sections:
18+
- Name: .ARM.attributes
19+
Type: 0x70000003 # SHT_LOPROC + 3
20+
AddressAlign: 1
21+
Offset: 0x40
22+
Size: 0x41
23+
Content: "411900000061656162695f7061757468616269000000010102012300000061656162695f666561747572655f616e645f6269747300010000010101020000"
24+
...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# RUN: yaml2obj %s -o %t.o
2+
# RUN: not llvm-readobj --arch-specific %t.o %null 2>&1 | FileCheck %s
3+
4+
# CHECK: unable to dump attributes from the Unknown section with index 1: unrecognized format-version: 0x37
5+
6+
# Version is 37 instead of 41, this is the first byte.
7+
--- !ELF
8+
FileHeader:
9+
Class: ELFCLASS64
10+
Data: ELFDATA2LSB
11+
OSABI: ELFOSABI_NONE
12+
Type: ET_REL
13+
Machine: EM_AARCH64
14+
Entry: 0x0
15+
16+
Sections:
17+
- Name: .ARM.attributes
18+
Type: 0x70000003 # SHT_LOPROC + 3
19+
AddressAlign: 1
20+
Offset: 0x40
21+
Size: 0x3d
22+
Content: "371900000061656162695f7061757468616269000000010102012300000061656162695f666561747572655f616e645f62697473000100000101010201"
23+
...

0 commit comments

Comments
 (0)