[scudo] Remove static error info functions. (#204483)

Android was the only platform using the static error info functions. The
latest Android no longer uses them, so delete these unused functions.

These functions were implicitly exporting implementation details and
made it difficult to implement the multi-region code. This is the final
step to submit the multi-region code and modify how the region code
works.

Remove the error info fuzzer since that was only necessary since so many
values were passed in to the function.

GitOrigin-RevId: 4a86da464e16b8f18d105e620268db3ef808da97
diff --git a/combined.h b/combined.h
index 409c0ab..47f35a2 100644
--- a/combined.h
+++ b/combined.h
@@ -332,10 +332,10 @@
 #ifdef HAVE_ANDROID_UNSAFE_FRAME_POINTER_CHASE
     // Discard collectStackTrace() frame and allocator function frame.
     constexpr uptr DiscardFrames = 2;
-    uptr Stack[MaxTraceSize + DiscardFrames];
-    uptr Size =
-        android_unsafe_frame_pointer_chase(Stack, MaxTraceSize + DiscardFrames);
-    Size = Min<uptr>(Size, MaxTraceSize + DiscardFrames);
+    uptr Stack[ScudoTraceSize + DiscardFrames];
+    uptr Size = android_unsafe_frame_pointer_chase(Stack, ScudoTraceSize +
+                                                              DiscardFrames);
+    Size = Min<uptr>(Size, ScudoTraceSize + DiscardFrames);
     return Depot->insert(Stack + Min<uptr>(DiscardFrames, Size), Stack + Size);
 #else
     return 0;
@@ -1000,7 +1000,7 @@
       return;
 
     // No more room for any more error reports.
-    if (ReportIndex == NumErrorReports)
+    if (ReportIndex == ScudoNumErrorReports)
       return;
 
     uptr UntaggedFaultAddr = untagPointer(FaultAddr);
@@ -1048,7 +1048,7 @@
       const u32 *TidPtr = reinterpret_cast<const u32 *>(loadTagUnaligned(
           reinterpret_cast<uptr>(&ChunkData[MemTagAllocationTidIndex])));
       Report->allocation_tid = *TidPtr;
-      return ReportIndex == NumErrorReports;
+      return ReportIndex == ScudoNumErrorReports;
     };
 
     if (MinDistance == 0 && CheckOOB(Info.BlockBegin))
@@ -1067,7 +1067,7 @@
       return;
 
     // No more room for any more error reports.
-    if (ReportIndex == NumErrorReports)
+    if (ReportIndex == ScudoNumErrorReports)
       return;
 
     uptr Pos = atomic_load_relaxed(&RingBuffer->Pos);
@@ -1142,7 +1142,7 @@
       collectTraceMaybe(RingBuffer->Depot, Report->deallocation_trace,
                         DeallocationTrace);
       Report->deallocation_tid = DeallocationTid;
-      if (ReportIndex == NumErrorReports) {
+      if (ReportIndex == ScudoNumErrorReports) {
         // No more report entries.
         return;
       }
@@ -1173,65 +1173,15 @@
     }
   }
 
-  static const uptr MaxTraceSize = 64;
-
   static void collectTraceMaybe(const StackDepot *Depot,
-                                uintptr_t (&Trace)[MaxTraceSize], u32 Hash) {
+                                uintptr_t (&Trace)[ScudoTraceSize], u32 Hash) {
     uptr RingPos, Size;
     if (!Depot->find(Hash, &RingPos, &Size))
       return;
-    for (unsigned I = 0; I != Size && I != MaxTraceSize; ++I)
+    for (unsigned I = 0; I != Size && I != ScudoTraceSize; ++I)
       Trace[I] = static_cast<uintptr_t>(Depot->at(RingPos + I));
   }
 
-  static void getErrorInfo(struct scudo_error_info *ErrorInfo,
-                           uintptr_t FaultAddr, const char *DepotPtr,
-                           size_t DepotSize, const char *RegionInfoPtr,
-                           const char *RingBufferPtr, size_t RingBufferSize,
-                           const char *Memory, const char *MemoryTags,
-                           uintptr_t MemoryAddr, size_t MemorySize) {
-    // N.B. we need to support corrupted data in any of the buffers here. We get
-    // this information from an external process (the crashing process) that
-    // should not be able to crash the crash dumper (crash_dump on Android).
-    // See also the get_error_info_fuzzer.
-    *ErrorInfo = {};
-    if (!allocatorSupportsMemoryTagging<AllocatorConfig>() ||
-        MemoryAddr + MemorySize < MemoryAddr)
-      return;
-
-    const StackDepot *Depot = nullptr;
-    if (DepotPtr) {
-      // check for corrupted StackDepot. First we need to check whether we can
-      // read the metadata, then whether the metadata matches the size.
-      if (DepotSize < sizeof(*Depot))
-        return;
-      Depot = reinterpret_cast<const StackDepot *>(DepotPtr);
-      if (!Depot->isValid(DepotSize))
-        return;
-    }
-
-    size_t NextErrorReport = 0;
-
-    // Check for OOB in the current block and the two surrounding blocks. Beyond
-    // that, UAF is more likely.
-    if (extractTag(FaultAddr) != 0)
-      getInlineErrorInfo(ErrorInfo, NextErrorReport, FaultAddr, Depot,
-                         RegionInfoPtr, Memory, MemoryTags, MemoryAddr,
-                         MemorySize, 0, 2);
-
-    // Check the ring buffer. For primary allocations this will only find UAF;
-    // for secondary allocations we can find either UAF or OOB.
-    getRingBufferErrorInfo(ErrorInfo, NextErrorReport, FaultAddr, Depot,
-                           RingBufferPtr, RingBufferSize);
-
-    // Check for OOB in the 28 blocks surrounding the 3 we checked earlier.
-    // Beyond that we are likely to hit false positives.
-    if (extractTag(FaultAddr) != 0)
-      getInlineErrorInfo(ErrorInfo, NextErrorReport, FaultAddr, Depot,
-                         RegionInfoPtr, Memory, MemoryTags, MemoryAddr,
-                         MemorySize, 2, 16);
-  }
-
   uptr getBlockBeginTestOnly(const void *Ptr) {
     Chunk::UnpackedHeader Header;
     Chunk::loadHeader(Cookie, Ptr, &Header);
@@ -1805,169 +1755,6 @@
                          DeallocationTrace, DeallocationTid);
   }
 
-  static const size_t NumErrorReports =
-      sizeof(((scudo_error_info *)nullptr)->reports) /
-      sizeof(((scudo_error_info *)nullptr)->reports[0]);
-
-  static void getInlineErrorInfo(struct scudo_error_info *ErrorInfo,
-                                 size_t &NextErrorReport, uintptr_t FaultAddr,
-                                 const StackDepot *Depot,
-                                 const char *RegionInfoPtr, const char *Memory,
-                                 const char *MemoryTags, uintptr_t MemoryAddr,
-                                 size_t MemorySize, size_t MinDistance,
-                                 size_t MaxDistance) {
-    uptr UntaggedFaultAddr = untagPointer(FaultAddr);
-    u8 FaultAddrTag = extractTag(FaultAddr);
-    BlockInfo Info =
-        PrimaryT::findNearestBlock(RegionInfoPtr, UntaggedFaultAddr);
-
-    auto GetGranule = [&](uptr Addr, const char **Data, uint8_t *Tag) -> bool {
-      if (Addr < MemoryAddr || Addr + archMemoryTagGranuleSize() < Addr ||
-          Addr + archMemoryTagGranuleSize() > MemoryAddr + MemorySize)
-        return false;
-      *Data = &Memory[Addr - MemoryAddr];
-      *Tag = static_cast<u8>(
-          MemoryTags[(Addr - MemoryAddr) / archMemoryTagGranuleSize()]);
-      return true;
-    };
-
-    auto ReadBlock = [&](uptr Addr, uptr *ChunkAddr,
-                         Chunk::UnpackedHeader *Header, const u32 **Data,
-                         u8 *Tag) {
-      const char *BlockBegin;
-      u8 BlockBeginTag;
-      if (!GetGranule(Addr, &BlockBegin, &BlockBeginTag))
-        return false;
-      uptr ChunkOffset = getChunkOffsetFromBlock(BlockBegin);
-      *ChunkAddr = Addr + ChunkOffset;
-
-      const char *ChunkBegin;
-      if (!GetGranule(*ChunkAddr, &ChunkBegin, Tag))
-        return false;
-      *Header = *reinterpret_cast<const Chunk::UnpackedHeader *>(
-          ChunkBegin - Chunk::getHeaderSize());
-      *Data = reinterpret_cast<const u32 *>(ChunkBegin);
-
-      // Allocations of size 0 will have stashed the tag in the first byte of
-      // the chunk, see storeEndMarker().
-      if (Header->SizeOrUnusedBytes == 0)
-        *Tag = static_cast<u8>(*ChunkBegin);
-
-      return true;
-    };
-
-    if (NextErrorReport == NumErrorReports)
-      return;
-
-    auto CheckOOB = [&](uptr BlockAddr) {
-      if (BlockAddr < Info.RegionBegin || BlockAddr >= Info.RegionEnd)
-        return false;
-
-      uptr ChunkAddr;
-      Chunk::UnpackedHeader Header;
-      const u32 *Data;
-      uint8_t Tag;
-      if (!ReadBlock(BlockAddr, &ChunkAddr, &Header, &Data, &Tag) ||
-          Header.State != Chunk::State::Allocated || Tag != FaultAddrTag)
-        return false;
-
-      auto *R = &ErrorInfo->reports[NextErrorReport++];
-      R->error_type =
-          UntaggedFaultAddr < ChunkAddr ? BUFFER_UNDERFLOW : BUFFER_OVERFLOW;
-      R->allocation_address = ChunkAddr;
-      R->allocation_size = Header.SizeOrUnusedBytes;
-      if (Depot) {
-        collectTraceMaybe(Depot, R->allocation_trace,
-                          Data[MemTagAllocationTraceIndex]);
-      }
-      R->allocation_tid = Data[MemTagAllocationTidIndex];
-      return NextErrorReport == NumErrorReports;
-    };
-
-    if (MinDistance == 0 && CheckOOB(Info.BlockBegin))
-      return;
-
-    for (size_t I = Max<size_t>(MinDistance, 1); I != MaxDistance; ++I)
-      if (CheckOOB(Info.BlockBegin + I * Info.BlockSize) ||
-          CheckOOB(Info.BlockBegin - I * Info.BlockSize))
-        return;
-  }
-
-  static void getRingBufferErrorInfo(struct scudo_error_info *ErrorInfo,
-                                     size_t &NextErrorReport,
-                                     uintptr_t FaultAddr,
-                                     const StackDepot *Depot,
-                                     const char *RingBufferPtr,
-                                     size_t RingBufferSize) {
-    auto *RingBuffer =
-        reinterpret_cast<const AllocationRingBuffer *>(RingBufferPtr);
-    size_t RingBufferElements = ringBufferElementsFromBytes(RingBufferSize);
-    if (!RingBuffer || RingBufferElements == 0 || !Depot)
-      return;
-    uptr Pos = atomic_load_relaxed(&RingBuffer->Pos);
-
-    for (uptr I = Pos - 1; I != Pos - 1 - RingBufferElements &&
-                           NextErrorReport != NumErrorReports;
-         --I) {
-      auto *Entry = getRingBufferEntry(RingBuffer, I % RingBufferElements);
-      uptr EntryPtr = atomic_load_relaxed(&Entry->Ptr);
-      if (!EntryPtr)
-        continue;
-
-      uptr UntaggedEntryPtr = untagPointer(EntryPtr);
-      uptr EntrySize = atomic_load_relaxed(&Entry->AllocationSize);
-      u32 AllocationTrace = atomic_load_relaxed(&Entry->AllocationTrace);
-      u32 AllocationTid = atomic_load_relaxed(&Entry->AllocationTid);
-      u32 DeallocationTrace = atomic_load_relaxed(&Entry->DeallocationTrace);
-      u32 DeallocationTid = atomic_load_relaxed(&Entry->DeallocationTid);
-
-      if (DeallocationTid) {
-        // For UAF we only consider in-bounds fault addresses because
-        // out-of-bounds UAF is rare and attempting to detect it is very likely
-        // to result in false positives.
-        if (FaultAddr < EntryPtr || FaultAddr >= EntryPtr + EntrySize)
-          continue;
-      } else {
-        // Ring buffer OOB is only possible with secondary allocations. In this
-        // case we are guaranteed a guard region of at least a page on either
-        // side of the allocation (guard page on the right, guard page + tagged
-        // region on the left), so ignore any faults outside of that range.
-        if (FaultAddr < EntryPtr - getPageSizeCached() ||
-            FaultAddr >= EntryPtr + EntrySize + getPageSizeCached())
-          continue;
-
-        // For UAF the ring buffer will contain two entries, one for the
-        // allocation and another for the deallocation. Don't report buffer
-        // overflow/underflow using the allocation entry if we have already
-        // collected a report from the deallocation entry.
-        bool Found = false;
-        for (uptr J = 0; J != NextErrorReport; ++J) {
-          if (ErrorInfo->reports[J].allocation_address == UntaggedEntryPtr) {
-            Found = true;
-            break;
-          }
-        }
-        if (Found)
-          continue;
-      }
-
-      auto *R = &ErrorInfo->reports[NextErrorReport++];
-      if (DeallocationTid)
-        R->error_type = USE_AFTER_FREE;
-      else if (FaultAddr < EntryPtr)
-        R->error_type = BUFFER_UNDERFLOW;
-      else
-        R->error_type = BUFFER_OVERFLOW;
-
-      R->allocation_address = UntaggedEntryPtr;
-      R->allocation_size = EntrySize;
-      collectTraceMaybe(Depot, R->allocation_trace, AllocationTrace);
-      R->allocation_tid = AllocationTid;
-      collectTraceMaybe(Depot, R->deallocation_trace, DeallocationTrace);
-      R->deallocation_tid = DeallocationTid;
-    }
-  }
-
   uptr getStats(ScopedString *Str) {
     Str->append("Config Stats Base: ");
     AllocatorConfig::getConfigValues(Str);
diff --git a/fuzz/get_error_info_fuzzer.cpp b/fuzz/get_error_info_fuzzer.cpp
deleted file mode 100644
index 2cef1c4..0000000
--- a/fuzz/get_error_info_fuzzer.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-//===-- get_error_info_fuzzer.cpp -----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#define SCUDO_FUZZ
-#include "allocator_config.h"
-#include "combined.h"
-#include "common.h"
-
-#include <fuzzer/FuzzedDataProvider.h>
-
-#include <string>
-#include <vector>
-
-extern "C" int LLVMFuzzerTestOneInput(uint8_t *Data, size_t Size) {
-  using AllocatorT = scudo::Allocator<scudo::AndroidConfig>;
-  FuzzedDataProvider FDP(Data, Size);
-
-  uintptr_t FaultAddr = FDP.ConsumeIntegral<uintptr_t>();
-  uintptr_t MemoryAddr = FDP.ConsumeIntegral<uintptr_t>();
-
-  std::string MemoryAndTags =
-      FDP.ConsumeRandomLengthString(FDP.remaining_bytes());
-  const char *Memory = MemoryAndTags.c_str();
-  // Assume 16-byte alignment.
-  size_t MemorySize = (MemoryAndTags.length() / 17) * 16;
-  const char *MemoryTags = Memory + MemorySize;
-
-  std::string StackDepotBytes =
-      FDP.ConsumeRandomLengthString(FDP.remaining_bytes());
-
-  std::string RegionInfoBytes =
-      FDP.ConsumeRandomLengthString(FDP.remaining_bytes());
-  std::vector<char> RegionInfo(AllocatorT::getRegionInfoArraySize(), 0);
-  for (size_t i = 0; i < RegionInfoBytes.length() && i < RegionInfo.size();
-       ++i) {
-    RegionInfo[i] = RegionInfoBytes[i];
-  }
-
-  std::string RingBufferBytes = FDP.ConsumeRemainingBytesAsString();
-
-  scudo_error_info ErrorInfo;
-  AllocatorT::getErrorInfo(&ErrorInfo, FaultAddr, StackDepotBytes.data(),
-                           StackDepotBytes.size(), RegionInfo.data(),
-                           RingBufferBytes.data(), RingBufferBytes.size(),
-                           Memory, MemoryTags, MemoryAddr, MemorySize);
-  return 0;
-}
diff --git a/include/scudo/interface.h b/include/scudo/interface.h
index cf80459..cf7b419 100644
--- a/include/scudo/interface.h
+++ b/include/scudo/interface.h
@@ -97,6 +97,7 @@
   BUFFER_UNDERFLOW,
 };
 
+const size_t ScudoTraceSize = 64;
 struct scudo_error_report {
   enum scudo_error_type error_type;
 
@@ -104,14 +105,15 @@
   uintptr_t allocation_size;
 
   uint32_t allocation_tid;
-  uintptr_t allocation_trace[64];
+  uintptr_t allocation_trace[ScudoTraceSize];
 
   uint32_t deallocation_tid;
-  uintptr_t deallocation_trace[64];
+  uintptr_t deallocation_trace[ScudoTraceSize];
 };
 
+const size_t ScudoNumErrorReports = 3;
 struct scudo_error_info {
-  struct scudo_error_report reports[3];
+  struct scudo_error_report reports[ScudoNumErrorReports];
 };
 
 const char *__scudo_get_stack_depot_addr(void);
diff --git a/wrappers_c.cpp b/wrappers_c.cpp
index daa0bdf..d445a20 100644
--- a/wrappers_c.cpp
+++ b/wrappers_c.cpp
@@ -437,39 +437,6 @@
   Allocator.getErrorInfo(fault_address, error_info);
 }
 
-INTERFACE void __scudo_get_error_info(
-    struct scudo_error_info *error_info, uintptr_t fault_addr,
-    const char *stack_depot, size_t stack_depot_size, const char *region_info,
-    const char *ring_buffer, size_t ring_buffer_size, const char *memory,
-    const char *memory_tags, uintptr_t memory_addr, size_t memory_size) {
-  Allocator.getErrorInfo(error_info, fault_addr, stack_depot, stack_depot_size,
-                         region_info, ring_buffer, ring_buffer_size, memory,
-                         memory_tags, memory_addr, memory_size);
-}
-
-INTERFACE const char *__scudo_get_stack_depot_addr() {
-  return Allocator.getStackDepotAddress();
-}
-
-INTERFACE size_t __scudo_get_stack_depot_size() {
-  return Allocator.getStackDepotSize();
-}
-
-INTERFACE const char *__scudo_get_region_info_addr() {
-  return Allocator.getRegionInfoArrayAddress();
-}
-
-INTERFACE size_t __scudo_get_region_info_size() {
-  return Allocator.getRegionInfoArraySize();
-}
-
-INTERFACE const char *__scudo_get_ring_buffer_addr() {
-  return Allocator.getRingBufferAddress();
-}
-
-INTERFACE size_t __scudo_get_ring_buffer_size() {
-  return Allocator.getRingBufferSize();
-}
 #endif
 
 } // extern "C"