In MemoryBuffer::getOpenFile() make sure that the buffer is null-terminated if
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 5 Apr 2012 04:23:56 +0000 (04:23 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 5 Apr 2012 04:23:56 +0000 (04:23 +0000)
the caller requested a null-terminated one.

When mapping the file there could be a racing issue that resulted in the file being larger
than the FileSize passed by the caller. We already have an assertion
for this in MemoryBuffer::init() but have a runtime guarantee that
the buffer will be null-terminated, so do a copy that adds a null-terminator.

Protects against crash of rdar://11161822.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154082 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/MemoryBuffer.cpp

index 911a03f8088bd70f97352b36352f254e68c47d2b..16e5c7a9f72bd7d4271aadbc50b33a12207e8f8f 100644 (file)
@@ -304,6 +304,16 @@ error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
                                                       RealMapOffset)) {
       result.reset(GetNamedBuffer<MemoryBufferMMapFile>(
           StringRef(Pages + Delta, MapSize), Filename, RequiresNullTerminator));
+
+      if (RequiresNullTerminator && result->getBufferEnd()[0] != '\0') {
+        // There could be a racing issue that resulted in the file being larger
+        // than the FileSize passed by the caller. We already have an assertion
+        // for this in MemoryBuffer::init() but have a runtime guarantee that
+        // the buffer will be null-terminated here, so do a copy that adds a
+        // null-terminator.
+        result.reset(MemoryBuffer::getMemBufferCopy(result->getBuffer(),
+                                                    Filename));
+      }
       return error_code::success();
     }
   }
@@ -339,6 +349,7 @@ error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
     if (NumRead == 0) {
       assert(0 && "We got inaccurate FileSize value or fstat reported an "
                    "invalid file size.");
+      *BufPtr = '\0'; // null-terminate at the actual size.
       break;
     }
     BytesLeft -= NumRead;