[llvm] c0d9e5a - Reland [AIX][BigArchive] Treat the archive is empty if the first child member offset is zero
Kai Luo via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 6 00:33:45 PST 2023
Author: Kai Luo
Date: 2023-03-06T16:33:27+08:00
New Revision: c0d9e5a0a4b80b0740282649ea32b0422e45e9ee
URL: https://github.com/llvm/llvm-project/commit/c0d9e5a0a4b80b0740282649ea32b0422e45e9ee
DIFF: https://github.com/llvm/llvm-project/commit/c0d9e5a0a4b80b0740282649ea32b0422e45e9ee.diff
LOG: Reland [AIX][BigArchive] Treat the archive is empty if the first child member offset is zero
If the archive contains free list and contains no member file, the buffer length doesn't equal to length of the header.
Reviewed By: Esme, DiggerLin, #powerpc
Differential Revision: https://reviews.llvm.org/D138986
Added:
llvm/test/Object/archive-big-malformed-first-member.test
Modified:
llvm/include/llvm/Object/Archive.h
llvm/lib/Object/Archive.cpp
llvm/test/Object/archive-big-read-empty-with-freelist.test
Removed:
################################################################################
diff --git a/llvm/include/llvm/Object/Archive.h b/llvm/include/llvm/Object/Archive.h
index fbacee964aa88..b77c8537eeaa0 100644
--- a/llvm/include/llvm/Object/Archive.h
+++ b/llvm/include/llvm/Object/Archive.h
@@ -410,9 +410,7 @@ class BigArchive : public Archive {
BigArchive(MemoryBufferRef Source, Error &Err);
uint64_t getFirstChildOffset() const override { return FirstChildOffset; }
uint64_t getLastChildOffset() const { return LastChildOffset; }
- bool isEmpty() const override {
- return Data.getBufferSize() == sizeof(FixLenHdr);
- };
+ bool isEmpty() const override { return getFirstChildOffset() == 0; }
};
} // end namespace object
diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp
index f4d2ff2e625fe..52d0dafd07e4c 100644
--- a/llvm/lib/Object/Archive.cpp
+++ b/llvm/lib/Object/Archive.cpp
@@ -135,6 +135,13 @@ BigArchiveMemberHeader::BigArchiveMemberHeader(const Archive *Parent,
return;
ErrorAsOutParameter ErrAsOutParam(Err);
+ if (RawHeaderPtr + getSizeOf() >= Parent->getData().end()) {
+ if (Err)
+ *Err = malformedError("malformed AIX big archive: remaining buffer is "
+ "unable to contain next archive member");
+ return;
+ }
+
if (Size < getSizeOf()) {
Error SubErr = createMemberHeaderParseError(this, RawHeaderPtr, Size);
if (Err)
@@ -1172,6 +1179,14 @@ BigArchive::BigArchive(MemoryBufferRef Source, Error &Err)
ErrorAsOutParameter ErrAsOutParam(&Err);
StringRef Buffer = Data.getBuffer();
ArFixLenHdr = reinterpret_cast<const FixLenHdr *>(Buffer.data());
+ uint64_t BufferSize = Data.getBufferSize();
+
+ if (BufferSize < sizeof(FixLenHdr)) {
+ Err = malformedError("malformed AIX big archive: incomplete fixed length "
+ "header, the archive is only" +
+ Twine(BufferSize) + " byte(s)");
+ return;
+ }
StringRef RawOffset = getFieldRawString(ArFixLenHdr->FirstChildOffset);
if (RawOffset.getAsInteger(10, FirstChildOffset))
@@ -1198,7 +1213,6 @@ BigArchive::BigArchive(MemoryBufferRef Source, Error &Err)
return;
if (GlobSymOffset > 0) {
- uint64_t BufferSize = Data.getBufferSize();
uint64_t GlobalSymTblContentOffset =
GlobSymOffset + sizeof(BigArMemHdrType);
if (GlobalSymTblContentOffset > BufferSize) {
diff --git a/llvm/test/Object/archive-big-malformed-first-member.test b/llvm/test/Object/archive-big-malformed-first-member.test
new file mode 100644
index 0000000000000..e38edc699d9db
--- /dev/null
+++ b/llvm/test/Object/archive-big-malformed-first-member.test
@@ -0,0 +1,15 @@
+## Test reading an archive with malformed header.
+# RUN: echo "<bigaf>" > %t.a
+# RUN: not llvm-ar tv %t.a 2>&1 | FileCheck --check-prefix=CHECK-HEADER %s
+# CHECK-HEADER: truncated or malformed archive{{.*}}malformed AIX big archive: incomplete fixed length header
+
+## Test reading an empty archive with first member's offset is not zero.
+# RUN: echo "<bigaf>" > %t.a
+# RUN: echo -n "0 0 0 128 0 0 " >> %t.a
+# RUN: not llvm-ar tv %t.a 2>&1 | FileCheck %s
+
+# RUN: echo "<bigaf>" > %t.a
+# RUN: echo -n "0 0 0 28 0 0 " >> %t.a
+# RUN: not llvm-ar tv %t.a 2>&1 | FileCheck %s
+
+# CHECK: truncated or malformed archive{{.*}}malformed AIX big archive: remaining buffer is unable to contain next archive member
diff --git a/llvm/test/Object/archive-big-read-empty-with-freelist.test b/llvm/test/Object/archive-big-read-empty-with-freelist.test
index 2ac3253446597..e9af7e0f81425 100644
--- a/llvm/test/Object/archive-big-read-empty-with-freelist.test
+++ b/llvm/test/Object/archive-big-read-empty-with-freelist.test
@@ -1,3 +1,3 @@
-# Test reading an empty archive with free list in it.
-# RUN: not llvm-ar tv %p/Inputs/aix-empty-big-archive-with-freelist.a 2>&1 \
-# RUN: | grep 'truncated or malformed archive'
+## Test reading an empty archive with free list in it, should exit normally.
+# RUN: llvm-ar tv %p/Inputs/aix-empty-big-archive-with-freelist.a 2>&1 \
+# RUN: | count 0
More information about the llvm-commits
mailing list