From 6789e01e9370b3b7f65d52138c5657eaa712b4d1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 20 Nov 2015 00:54:07 +0100 Subject: do not segfault in cache generation on mmap failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Out of memory and similar circumstanzas could cause MMap::Map to fail and especially the mmap/malloc calls in it. With some additional checking we can avoid segfaults and similar in such situations – at least in theory as if this is a real out of memory everything we do to handle the error could just as well run into a memory problem as well… But at least in theory (if MMap::Map is made to fail always) we can deal with it so good that a user actually never sees a failure (as the cache it tries to load with it fails and is discarded, so that DynamicMMap takes over and a new one is build) instead of segfaulting. Closes: 803417 --- apt-pkg/pkgcachegen.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 5c61ff2b8..e1958f45a 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -125,7 +125,7 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) : advoid a problem during a crash */ pkgCacheGenerator::~pkgCacheGenerator() { - if (_error->PendingError() == true) + if (_error->PendingError() == true || Map.validData() == false) return; if (Map.Sync() == false) return; @@ -1307,6 +1307,8 @@ static bool CheckValidity(const string &CacheFile, // Map it FileFd CacheF(CacheFile,FileFd::ReadOnly); std::unique_ptr Map(new MMap(CacheF,0)); + if (unlikely(Map->validData()) == false) + return false; pkgCache Cache(Map.get()); if (_error->PendingError() || Map->Size() == 0) { @@ -1539,6 +1541,8 @@ static bool loadBackMMapFromFile(std::unique_ptr &Gen, std::unique_ptr &Map, OpProgress * const Progress, std::string const &FileName) { Map.reset(CreateDynamicMMap(NULL, 0)); + if (unlikely(Map->validData()) == false) + return false; FileFd CacheF(FileName, FileFd::ReadOnly); if (CacheF.IsOpen() == false || CacheF.Failed()) return false; @@ -1628,6 +1632,8 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress // At this point we know we need to construct something, so get storage ready std::unique_ptr Map(CreateDynamicMMap(NULL, 0)); + if (unlikely(Map->validData()) == false) + return false; if (Debug == true) std::clog << "Open memory Map (not filebased)" << std::endl; @@ -1716,6 +1722,8 @@ bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **O ScopedErrorMerge sem; std::unique_ptr Map(CreateDynamicMMap(NULL, 0)); + if (unlikely(Map->validData()) == false) + return false; map_filesize_t CurrentSize = 0; map_filesize_t TotalSize = 0; TotalSize = ComputeSize(NULL, Files.begin(), Files.end()); -- cgit v1.2.3