[PATCH] D144708: [clangd] Fix UB in scanPreamble

Kadir Cetinkaya via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 24 00:53:45 PST 2023


kadircet created this revision.
kadircet added a reviewer: hokein.
Herald added a subscriber: arphaman.
Herald added a project: All.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

getMemBufferCopy triggers an UB when it receives a default constructed
StringRef. Make sure that we're always passing the null-terminated string
created in ParseInputs throughout the scanPreamble.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D144708

Files:
  clang-tools-extra/clangd/Preamble.cpp


Index: clang-tools-extra/clangd/Preamble.cpp
===================================================================
--- clang-tools-extra/clangd/Preamble.cpp
+++ clang-tools-extra/clangd/Preamble.cpp
@@ -332,6 +332,8 @@
   EmptyFS FS;
   // Build and run Preprocessor over the preamble.
   ParseInputs PI;
+  // Memory buffers below expect null-terminated && non-null strings. So make
+  // sure to always use PI.Contents!
   PI.Contents = Contents.str();
   PI.TFS = &FS;
   PI.CompileCommand = Cmd;
@@ -346,7 +348,7 @@
   // elsewhere.
   auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), *ContentsBuffer, 0);
   auto PreambleContents =
-      llvm::MemoryBuffer::getMemBufferCopy(Contents.substr(0, Bounds.Size));
+      llvm::MemoryBuffer::getMemBufferCopy(PI.Contents.substr(0, Bounds.Size));
   auto Clang = prepareCompilerInstance(
       std::move(CI), nullptr, std::move(PreambleContents),
       // Provide an empty FS to prevent preprocessor from performing IO. This
@@ -371,7 +373,7 @@
     return std::move(Err);
   Action.EndSourceFile();
   SP.Includes = std::move(Includes.MainFileIncludes);
-  llvm::append_range(SP.Lines, llvm::split(Contents, "\n"));
+  llvm::append_range(SP.Lines, llvm::split(PI.Contents, "\n"));
   return SP;
 }
 
@@ -739,9 +741,8 @@
   //   whole preamble, which is terribly slow.
   // - If scanning for Modified fails, cannot figure out newly added ones so
   //   there's nothing to do but generate an empty patch.
-  auto BaselineScan = scanPreamble(
-      // Contents needs to be null-terminated.
-      Baseline.Preamble.getContents(), Modified.CompileCommand);
+  auto BaselineScan =
+      scanPreamble(Baseline.Preamble.getContents(), Modified.CompileCommand);
   if (!BaselineScan) {
     elog("Failed to scan baseline of {0}: {1}", FileName,
          BaselineScan.takeError());


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D144708.500101.patch
Type: text/x-patch
Size: 1835 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230224/7b11ce4f/attachment.bin>


More information about the cfe-commits mailing list