diff options
author | Heitor R. Alves de Siqueira <halves@canonical.com> | 2019-02-08 13:05:18 +0100 |
---|---|---|
committer | Julian Andres Klode <julian.klode@canonical.com> | 2019-02-08 13:05:18 +0100 |
commit | 22e3f5d3e311bc001a05803fcf39036f620b1d96 (patch) | |
tree | 92e111713b6c2deb0375f86d295aaa5767a45b7a /apt-pkg/contrib | |
parent | 5d07bad6105eb1b7c158c502fe89803e120be064 (diff) |
backport "do not segfault in cache generation on mmap failure"
Original commit message:
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
LP: #1815129
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r-- | apt-pkg/contrib/mmap.cc | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index b2a53a6cb..f82537afb 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -84,6 +84,8 @@ bool MMap::Map(FileFd &Fd) if ((Flags & ReadOnly) != ReadOnly) return _error->Error("Compressed file %s can only be mapped readonly", Fd.Name().c_str()); Base = malloc(iSize); + if (unlikely(Base == NULL)) + return _error->Errno("MMap-compressed-malloc", _("Couldn't make mmap of %llu bytes"), iSize); SyncToFd = new FileFd(); if (Fd.Seek(0L) == false || Fd.Read(Base, iSize) == false) return _error->Error("Compressed file %s can't be read into mmap", Fd.Name().c_str()); @@ -92,7 +94,7 @@ bool MMap::Map(FileFd &Fd) // Map it. Base = (Flags & Fallback) ? MAP_FAILED : mmap(0,iSize,Prot,Map,Fd.Fd(),0); - if (Base == (void *)-1) + if (Base == MAP_FAILED) { if (errno == ENODEV || errno == EINVAL || (Flags & Fallback)) { @@ -102,6 +104,8 @@ bool MMap::Map(FileFd &Fd) { // for readonly, we don't need sync, so make it simple Base = malloc(iSize); + if (unlikely(Base == NULL)) + return _error->Errno("MMap-malloc", _("Couldn't make mmap of %llu bytes"), iSize); SyncToFd = new FileFd(); return Fd.Read(Base, iSize); } @@ -111,13 +115,14 @@ bool MMap::Map(FileFd &Fd) return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd()); Base = calloc(iSize, 1); + if (unlikely(Base == NULL)) + return _error->Errno("MMap-calloc", _("Couldn't make mmap of %llu bytes"), iSize); SyncToFd = new FileFd (dupped_fd); if (!SyncToFd->Seek(0L) || !SyncToFd->Read(Base, iSize)) return false; } else - return _error->Errno("mmap",_("Couldn't make mmap of %llu bytes"), - iSize); + return _error->Errno("MMap-mmap",_("Couldn't make mmap of %llu bytes"), iSize); } return true; |