From f17e3ce8213ba364d1eea7b5bab286a2175e5875 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 25 Feb 2020 11:26:18 +0100 Subject: Silence narrow conversion warnings, add error checks When converting a long offset to a uint32_t to be stored in the map, check that this is safe to do. If the offset is negative, or we lose data in the conversion, we lost. --- apt-pkg/pkgcachegen.cc | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 83a8c2e63..283866f88 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -48,6 +48,19 @@ static bool IsDuplicateDescription(pkgCache &Cache, pkgCache::DescIterator Desc, using std::string; using APT::StringView; +// Convert an offset returned from e.g. DynamicMMap or ptr difference to +// an uint32_t location without data loss. +template +static inline uint32_t NarrowOffset(T ptr) +{ + uint32_t res = static_cast(ptr); + if (unlikely(ptr < 0)) + abort(); + if (unlikely(static_cast(res) != ptr)) + abort(); + return res; +} + // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/ // --------------------------------------------------------------------- /* We set the dirty flag and make sure that is written to the disk */ @@ -210,7 +223,7 @@ map_stringitem_t pkgCacheGenerator::WriteStringInMap(const char *String, const unsigned long &Len) { size_t oldSize = Map.Size(); void const * const oldMap = Map.Data(); - map_stringitem_t const index{Map.WriteString(String, Len)}; + map_stringitem_t const index{NarrowOffset(Map.WriteString(String, Len))}; if (index != 0) ReMap(oldMap, Map.Data(), oldSize); return index; @@ -220,7 +233,7 @@ map_stringitem_t pkgCacheGenerator::WriteStringInMap(const char *String, map_stringitem_t pkgCacheGenerator::WriteStringInMap(const char *String) { size_t oldSize = Map.Size(); void const * const oldMap = Map.Data(); - map_stringitem_t const index{Map.WriteString(String)}; + map_stringitem_t const index{NarrowOffset(Map.WriteString(String))}; if (index != 0) ReMap(oldMap, Map.Data(), oldSize); return index; @@ -827,7 +840,7 @@ bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver, return false; pkgCache::VerFileIterator VF(Cache,Cache.VerFileP + VerFile); - VF->File = map_pointer{CurrentFile - Cache.PkgFileP}; + VF->File = map_pointer{NarrowOffset(CurrentFile - Cache.PkgFileP)}; // Link it to the end of the list map_pointer *Last = &Ver->FileList; @@ -912,7 +925,7 @@ bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc, return false; pkgCache::DescFileIterator DF(Cache,Cache.DescFileP + DescFile); - DF->File = map_pointer{CurrentFile - Cache.PkgFileP}; + DF->File = map_pointer{NarrowOffset(CurrentFile - Cache.PkgFileP)}; // Link it to the end of the list map_pointer *Last = &Desc->FileList; @@ -1267,7 +1280,7 @@ bool pkgCacheGenerator::SelectReleaseFile(const string &File,const string &Site, CurrentRlsFile->Flags = Flags; CurrentRlsFile->ID = Cache.HeaderP->ReleaseFileCount; RlsFileName = File; - Cache.HeaderP->RlsFileList = map_pointer{CurrentRlsFile - Cache.RlsFileP}; + Cache.HeaderP->RlsFileList = map_pointer{NarrowOffset(CurrentRlsFile - Cache.RlsFileP)}; Cache.HeaderP->ReleaseFileCount++; return true; @@ -1316,11 +1329,11 @@ bool pkgCacheGenerator::SelectFile(std::string const &File, CurrentFile->Component = component; CurrentFile->Flags = Flags; if (CurrentRlsFile != nullptr) - CurrentFile->Release = map_pointer{CurrentRlsFile - Cache.RlsFileP}; + CurrentFile->Release = map_pointer{NarrowOffset(CurrentRlsFile - Cache.RlsFileP)}; else CurrentFile->Release = 0; PkgFileName = File; - Cache.HeaderP->FileList = map_pointer{CurrentFile - Cache.PkgFileP}; + Cache.HeaderP->FileList = map_pointer{NarrowOffset(CurrentFile - Cache.PkgFileP)}; Cache.HeaderP->PackageFileCount++; if (Progress != 0) -- cgit v1.2.3