From 25c7a09d4a207bac875817559580f62c9ee07cb5 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 29 Dec 2015 15:11:11 +0100 Subject: Add support for calculating hashes over the entire cache --- apt-pkg/pkgcache.cc | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'apt-pkg/pkgcache.cc') diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index dd25fc51d..347a0954e 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -39,6 +39,7 @@ #include #include #include +#include #include /*}}}*/ @@ -173,9 +174,6 @@ bool pkgCache::ReMap(bool const &Errorchecks) HeaderP->CheckSizes(DefHeader) == false) return _error->Error(_("The package cache file is an incompatible version")); - if (Map.Size() < HeaderP->CacheFileSize) - return _error->Error(_("The package cache file is corrupted, it is too small")); - if (HeaderP->VerSysName == 0 || HeaderP->Architecture == 0 || HeaderP->GetArchitectures() == 0) return _error->Error(_("The package cache file is corrupted")); @@ -193,6 +191,13 @@ bool pkgCache::ReMap(bool const &Errorchecks) list != StrP + HeaderP->GetArchitectures()) return _error->Error(_("The package cache was built for different architectures: %s vs %s"), StrP + HeaderP->GetArchitectures(), list.c_str()); + + auto hash = CacheHash(); + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "Opened cache with hash " << hash << ", expecting " << HeaderP->CacheFileSize << "\n"; + if (hash != HeaderP->CacheFileSize) + return _error->Error(_("The package cache file is corrupted, it has the wrong hash")); + return true; } /*}}}*/ @@ -216,6 +221,31 @@ map_id_t pkgCache::sHash(const char *Str) const Hash = 33 * Hash + tolower_ascii(*I); return Hash % HeaderP->GetHashTableSize(); } + +uint32_t pkgCache::CacheHash() +{ + pkgCache::Header header = {}; + uLong adler = adler32(0L, Z_NULL, 0); + + if (Map.Size() < sizeof(header)) + return adler; + memcpy(&header, GetMap().Data(), sizeof(header)); + + header.Dirty = false; + header.CacheFileSize = 0; + + adler = adler32(adler, + reinterpret_cast(&header), + sizeof(header)); + + if (Map.Size() > sizeof(header)) { + adler = adler32(adler, + static_cast(GetMap().Data()) + sizeof(header), + GetMap().Size() - sizeof(header)); + } + + return adler; +} /*}}}*/ // Cache::FindPkg - Locate a package by name /*{{{*/ // --------------------------------------------------------------------- -- cgit v1.2.3