Skip to content

Commit 44bcda0

Browse files
committed
Add bundle id check such as it should not crash when given a malformat bundle id
1 parent da7c8b1 commit 44bcda0

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

clang/include/clang/Driver/OffloadBundler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ class CompressedOffloadBundle {
158158
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
159159
decompress(const llvm::MemoryBuffer &Input, bool Verbose = false);
160160
};
161+
162+
/// Check whether the bundle id is in the following format:
163+
/// <kind>-<triple>[-<target id>[:target features]]
164+
/// <triple> := <arch>-<vendor>-<os>-<env>
165+
bool checkOffloadBundleID(const llvm::StringRef Str);
161166
} // namespace clang
162167

163168
#endif // LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H

clang/lib/Driver/OffloadBundler.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ OffloadTargetInfo::OffloadTargetInfo(const StringRef Target,
8383
const OffloadBundlerConfig &BC)
8484
: BundlerConfig(BC) {
8585

86-
// TODO: Add error checking from ClangOffloadBundler.cpp
8786
// <kind>-<triple>[-<target id>[:target features]]
8887
// <triple> := <arch>-<vendor>-<os>-<env>
8988
SmallVector<StringRef, 6> Components;
@@ -1514,6 +1513,9 @@ Error OffloadBundler::UnbundleFiles() {
15141513
StringMap<StringRef> Worklist;
15151514
auto Output = BundlerConfig.OutputFileNames.begin();
15161515
for (auto &Triple : BundlerConfig.TargetNames) {
1516+
if (!checkOffloadBundleID(Triple))
1517+
return createStringError(errc::invalid_argument,
1518+
"invalid bundle id from bundle config");
15171519
Worklist[Triple] = *Output;
15181520
++Output;
15191521
}
@@ -1533,6 +1535,9 @@ Error OffloadBundler::UnbundleFiles() {
15331535

15341536
StringRef CurTriple = **CurTripleOrErr;
15351537
assert(!CurTriple.empty());
1538+
if (!checkOffloadBundleID(CurTriple))
1539+
return createStringError(errc::invalid_argument,
1540+
"invalid bundle id read from the bundle");
15361541

15371542
auto Output = Worklist.begin();
15381543
for (auto E = Worklist.end(); Output != E; Output++) {
@@ -1591,6 +1596,8 @@ Error OffloadBundler::UnbundleFiles() {
15911596
return createFileError(E.second, EC);
15921597

15931598
// If this entry has a host kind, copy the input file to the output file.
1599+
// We don't need to check E.getKey() here through checkOffloadBundleID
1600+
// because the entire WorkList has been checked above.
15941601
auto OffloadInfo = OffloadTargetInfo(E.getKey(), BundlerConfig);
15951602
if (OffloadInfo.hasHostKind())
15961603
OutputFile.write(Input.getBufferStart(), Input.getBufferSize());
@@ -1820,6 +1827,10 @@ Error OffloadBundler::UnbundleArchive() {
18201827
// archive.
18211828
while (!CodeObject.empty()) {
18221829
SmallVector<StringRef> CompatibleTargets;
1830+
if (!checkOffloadBundleID(CodeObject)) {
1831+
return createStringError(errc::invalid_argument,
1832+
"Invalid bundle id read from code object");
1833+
}
18231834
auto CodeObjectInfo = OffloadTargetInfo(CodeObject, BundlerConfig);
18241835
if (getCompatibleOffloadTargets(CodeObjectInfo, CompatibleTargets,
18251836
BundlerConfig)) {
@@ -1901,3 +1912,11 @@ Error OffloadBundler::UnbundleArchive() {
19011912

19021913
return Error::success();
19031914
}
1915+
1916+
bool clang::checkOffloadBundleID(const llvm::StringRef Str) {
1917+
// <kind>-<triple>[-<target id>[:target features]]
1918+
// <triple> := <arch>-<vendor>-<os>-<env>
1919+
SmallVector<StringRef, 6> Components;
1920+
Str.split(Components, '-', /*MaxSplit=*/5);
1921+
return Components.size() == 5 || Components.size() == 6;
1922+
}

clang/test/Driver/clang-offload-bundler.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,12 @@
557557
// RUN: llvm-ar t %T/hip-openmp_906.a | FileCheck -check-prefix=OPENMPHIPCOMPAT %s
558558
// OPENMPHIPCOMPAT: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906
559559

560+
// Check if a malformat bundle id can be detected and an error can be emitted.
561+
// RUN: not clang-offload-bundler -unbundle -type=a -targets=openmp-amdgcn-amd-amdhsa -output=%T/hip-openmp_906.a -input=%T/hip_archive.a -hip-openmp-compatible 2>&1 | FileCheck %s -check-prefix=ERROR
562+
// ERROR: error: Targets need to follow the format '<offload kind>-<target triple>', where '<target triple>' follows the format '<kind>-<arch>-<vendor>-<os>-<env>[-<target id>[:target features]]'.
563+
// RUN: not clang-offload-bundler -unbundle -type=a -targets=openmp-amdgcn-amd-amdhsa-gfx906 -output=%T/hip-openmp_906.a -input=%T/hip_archive.a -hip-openmp-compatible 2>&1 | FileCheck %s -check-prefix=ERROR
564+
// ERROR: error: no compatible code object found for the target 'openmp-amdgcn-amd-amdhsa--'
565+
560566
// Some code so that we can create a binary out of this file.
561567
int A = 0;
562568
void test_func(void) {

clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,15 @@ int main(int argc, const char **argv) {
355355
errc::invalid_argument, "Duplicate targets are not allowed"));
356356
}
357357

358+
if (!checkOffloadBundleID(Target)) {
359+
return reportError(createStringError(
360+
errc::invalid_argument,
361+
"Targets need to follow the format '<offload kind>-<target triple>', "
362+
"where '<target triple>' follows the format "
363+
"'<kind>-<arch>-<vendor>-<os>-<env>[-<target id>[:target "
364+
"features]]'."));
365+
}
366+
358367
auto OffloadInfo = OffloadTargetInfo(Target, BundlerConfig);
359368
bool KindIsValid = OffloadInfo.isOffloadKindValid();
360369
bool TripleIsValid = OffloadInfo.isTripleValid();

0 commit comments

Comments
 (0)