Skip to content

Commit 4af1522

Browse files
committed
[lld-macho] Rework length check when opening input files
This reverts diff D97610 (commit 0223ab0) and adds a one-line fix to verify that a `MemoryBufferRef` has sufficient length before reading a 4-byte magic number. Differential Revision: https://reviews.llvm.org/D97757
1 parent 8a31604 commit 4af1522

File tree

6 files changed

+14
-54
lines changed

6 files changed

+14
-54
lines changed

lld/MachO/Driver.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ static std::vector<ArchiveMember> getArchiveMembers(MemoryBufferRef mb) {
263263

264264
static InputFile *addFile(StringRef path, bool forceLoadArchive,
265265
bool isBundleLoader = false) {
266-
Optional<MemoryBufferRef> buffer = readLinkableFile(path);
266+
Optional<MemoryBufferRef> buffer = readFile(path);
267267
if (!buffer)
268268
return nullptr;
269269
MemoryBufferRef mbref = *buffer;
@@ -279,7 +279,7 @@ static InputFile *addFile(StringRef path, bool forceLoadArchive,
279279
error(path + ": archive has no index; run ranlib to add one");
280280

281281
if (config->allLoad || forceLoadArchive) {
282-
if (Optional<MemoryBufferRef> buffer = readLinkableFile(path)) {
282+
if (Optional<MemoryBufferRef> buffer = readFile(path)) {
283283
for (const ArchiveMember &member : getArchiveMembers(*buffer)) {
284284
if (Optional<InputFile *> file = loadArchiveMember(
285285
member.mbref, member.modTime, path, /*objCOnly=*/false)) {
@@ -300,7 +300,7 @@ static InputFile *addFile(StringRef path, bool forceLoadArchive,
300300
// we already found that it contains an ObjC symbol. We should also
301301
// consider creating a LazyObjFile class in order to avoid double-loading
302302
// these files here and below (as part of the ArchiveFile).
303-
if (Optional<MemoryBufferRef> buffer = readLinkableFile(path)) {
303+
if (Optional<MemoryBufferRef> buffer = readFile(path)) {
304304
for (const ArchiveMember &member : getArchiveMembers(*buffer)) {
305305
if (Optional<InputFile *> file = loadArchiveMember(
306306
member.mbref, member.modTime, path, /*objCOnly=*/true)) {
@@ -403,7 +403,7 @@ void macho::parseLCLinkerOption(InputFile* f, unsigned argc, StringRef data) {
403403
}
404404

405405
static void addFileList(StringRef path) {
406-
Optional<MemoryBufferRef> buffer = readRawFile(path);
406+
Optional<MemoryBufferRef> buffer = readFile(path);
407407
if (!buffer)
408408
return;
409409
MemoryBufferRef mbref = *buffer;
@@ -426,7 +426,7 @@ static void addFileList(StringRef path) {
426426
//
427427
// The file can also have line comments that start with '#'.
428428
static void parseOrderFile(StringRef path) {
429-
Optional<MemoryBufferRef> buffer = readRawFile(path);
429+
Optional<MemoryBufferRef> buffer = readFile(path);
430430
if (!buffer) {
431431
error("Could not read order file at " + path);
432432
return;
@@ -940,7 +940,7 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
940940
StringRef segName = arg->getValue(0);
941941
StringRef sectName = arg->getValue(1);
942942
StringRef fileName = arg->getValue(2);
943-
Optional<MemoryBufferRef> buffer = readRawFile(fileName);
943+
Optional<MemoryBufferRef> buffer = readFile(fileName);
944944
if (buffer)
945945
inputFiles.insert(make<OpaqueFile>(*buffer, segName, sectName));
946946
}

lld/MachO/DriverUtils.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ std::string macho::createResponseFile(const opt::InputArgList &args) {
132132
os << "-o " << quote(path::filename(arg->getValue())) << "\n";
133133
break;
134134
case OPT_filelist:
135-
if (Optional<MemoryBufferRef> buffer = readRawFile(arg->getValue()))
135+
if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
136136
for (StringRef path : args::getLines(*buffer))
137137
os << quote(rewritePath(path)) << "\n";
138138
break;

lld/MachO/InputFiles.cpp

+4-25
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ std::unique_ptr<TarWriter> macho::tar;
9191
int InputFile::idCount = 0;
9292

9393
// Open a given file path and return it as a memory-mapped file.
94-
// Perform no sanity checks--just open, map & return.
95-
Optional<MemoryBufferRef> macho::readRawFile(StringRef path) {
94+
Optional<MemoryBufferRef> macho::readFile(StringRef path) {
9695
// Open a file.
9796
auto mbOrErr = MemoryBuffer::getFile(path);
9897
if (auto ec = mbOrErr.getError()) {
@@ -103,32 +102,12 @@ Optional<MemoryBufferRef> macho::readRawFile(StringRef path) {
103102
std::unique_ptr<MemoryBuffer> &mb = *mbOrErr;
104103
MemoryBufferRef mbref = mb->getMemBufferRef();
105104
make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); // take mb ownership
106-
return mbref;
107-
}
108-
109-
// Open a given file path and return it as a memory-mapped file.
110-
// Assume the file has one of a variety of linkable formats and
111-
// perform some basic sanity checks, notably minimum length.
112-
Optional<MemoryBufferRef> macho::readLinkableFile(StringRef path) {
113-
Optional<MemoryBufferRef> maybeMbref = readRawFile(path);
114-
if (!maybeMbref) {
115-
return None;
116-
}
117-
MemoryBufferRef mbref = *maybeMbref;
118-
119-
// LD64 hard-codes 20 as minimum header size, which is presumably
120-
// the smallest header among the the various linkable input formats
121-
// LLD are less demanding. We insist on having only enough data for
122-
// a magic number.
123-
if (mbref.getBufferSize() < sizeof(uint32_t)) {
124-
error("file is too small to contain a magic number: " + path);
125-
return None;
126-
}
127105

128106
// If this is a regular non-fat file, return it.
129107
const char *buf = mbref.getBufferStart();
130108
auto *hdr = reinterpret_cast<const MachO::fat_header *>(buf);
131-
if (read32be(&hdr->magic) != MachO::FAT_MAGIC) {
109+
if (mbref.getBufferSize() < sizeof(uint32_t) ||
110+
read32be(&hdr->magic) != MachO::FAT_MAGIC) {
132111
if (tar)
133112
tar->append(relativeToRoot(path), mbref.getBuffer());
134113
return mbref;
@@ -565,7 +544,7 @@ void ObjFile::parseDebugInfo() {
565544

566545
// The path can point to either a dylib or a .tbd file.
567546
static Optional<DylibFile *> loadDylib(StringRef path, DylibFile *umbrella) {
568-
Optional<MemoryBufferRef> mbref = readLinkableFile(path);
547+
Optional<MemoryBufferRef> mbref = readFile(path);
569548
if (!mbref) {
570549
error("could not read dylib file at " + path);
571550
return {};

lld/MachO/InputFiles.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,7 @@ class BitcodeFile : public InputFile {
173173

174174
extern llvm::SetVector<InputFile *> inputFiles;
175175

176-
llvm::Optional<MemoryBufferRef> readRawFile(StringRef path);
177-
llvm::Optional<MemoryBufferRef> readLinkableFile(StringRef path);
176+
llvm::Optional<MemoryBufferRef> readFile(StringRef path);
178177

179178
const llvm::MachO::load_command *
180179
findCommand(const llvm::MachO::mach_header_64 *, uint32_t type);

lld/test/MachO/invalid/tiny-input.s

-18
This file was deleted.

lld/test/MachO/rename.s

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# BAD1-DAG: error: invalid name for segment or section: S/ASHY_SEG
1515
# BAD1-DAG: error: invalid name for segment or section: st*rry_sect
1616
# BAD1-DAG: error: invalid name for segment or section: -o
17-
# BAD1-DAG: error: file is too small to contain a magic number:
17+
# BAD1-DAG: error: {{.*}}: unhandled file type
1818

1919
# RUN: not %lld \
2020
# RUN: -rename_segment H#SHY_SEG PL+SSY_SEG \
@@ -24,7 +24,7 @@
2424
# BAD2-DAG: error: invalid name for segment or section: H#SHY_SEG
2525
# BAD2-DAG: error: invalid name for segment or section: PL+SSY_SEG
2626
# BAD2-DAG: error: invalid name for segment or section: -o
27-
# BAD2-DAG: error: file is too small to contain a magic number:
27+
# BAD2-DAG: error: {{.*}}: unhandled file type
2828

2929
## Check that section and segment renames happen
3030
# RUN: %lld \

0 commit comments

Comments
 (0)