Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19c3315c authored by Todd Kennedy's avatar Todd Kennedy Committed by android-build-team Robot
Browse files

Loosen resource file verification

Bug: 77808145
Test: Tried to install corrupt APK prior to the change, install failed
Test: Tried to install corrupt APK after the change, install succeeded
Test: atest CtsAppSecurityHostTestCases:CorruptApkTests
Change-Id: I19a69e52a17c1080beaf2cc575c32f564b1033a3
(cherry picked from commit 28e663cb)
parent e1125aee
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -32,11 +32,30 @@ Chunk ChunkIterator::Next() {

  if (len_ != 0) {
    // Prepare the next chunk.
    if (VerifyNextChunkNonFatal()) {
      VerifyNextChunk();
    }
  }
  return Chunk(this_chunk);
}

// TODO(b/111401637) remove this and have full resource file verification
// Returns false if there was an error.
bool ChunkIterator::VerifyNextChunkNonFatal() {
  if (len_ < sizeof(ResChunk_header)) {
    last_error_ = "not enough space for header";
    last_error_was_fatal_ = false;
    return false;
  }
  const size_t size = dtohl(next_chunk_->size);
  if (size > len_) {
    last_error_ = "chunk size is bigger than given data";
    last_error_was_fatal_ = false;
    return false;
  }
  return true;
}

// Returns false if there was an error.
bool ChunkIterator::VerifyNextChunk() {
  const uintptr_t header_start = reinterpret_cast<uintptr_t>(next_chunk_);
+9 −3
Original line number Diff line number Diff line
@@ -560,8 +560,10 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,

  if (iter.HadError()) {
    LOG(ERROR) << iter.GetLastError();
    if (iter.HadFatalError()) {
      return {};
    }
  }

  // Flatten and construct the TypeSpecs.
  for (auto& entry : type_builder_map) {
@@ -641,8 +643,10 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,

  if (iter.HadError()) {
    LOG(ERROR) << iter.GetLastError();
    if (iter.HadFatalError()) {
      return false;
    }
  }
  return true;
}

@@ -673,8 +677,10 @@ std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const StringPiece& data,

  if (iter.HadError()) {
    LOG(ERROR) << iter.GetLastError();
    if (iter.HadFatalError()) {
      return {};
    }
  }

  // Need to force a move for mingw32.
  return std::move(loaded_arsc);
+9 −0
Original line number Diff line number Diff line
@@ -94,18 +94,27 @@ class ChunkIterator {

  Chunk Next();
  inline bool HasNext() const { return !HadError() && len_ != 0; };
  // Returns whether there was an error and processing should stop
  inline bool HadError() const { return last_error_ != nullptr; }
  inline std::string GetLastError() const { return last_error_; }
  // Returns whether there was an error and processing should stop. For legacy purposes,
  // some errors are considered "non fatal". Fatal errors stop processing new chunks and
  // throw away any chunks already processed. Non fatal errors also stop processing new
  // chunks, but, will retain and use any valid chunks already processed.
  inline bool HadFatalError() const { return HadError() && last_error_was_fatal_; }

 private:
  DISALLOW_COPY_AND_ASSIGN(ChunkIterator);

  // Returns false if there was an error.
  bool VerifyNextChunk();
  // Returns false if there was an error. For legacy purposes.
  bool VerifyNextChunkNonFatal();

  const ResChunk_header* next_chunk_;
  size_t len_;
  const char* last_error_;
  bool last_error_was_fatal_ = true;
};

}  // namespace android