summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-11-20 00:54:07 +0100
committerDavid Kalnischkies <david@kalnischkies.de>2015-11-20 00:54:07 +0100
commit6789e01e9370b3b7f65d52138c5657eaa712b4d1 (patch)
treecf0b9282cae981271918512f7af62da7dda4e64c /apt-pkg/contrib
parent520624d562e54e8e2c0191fae723e668e3ece6b4 (diff)
do not segfault in cache generation on mmap failure
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
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r--apt-pkg/contrib/mmap.cc15
1 files changed, 10 insertions, 5 deletions
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index 8e169027e..33c33d1c1 100644
--- a/apt-pkg/contrib/mmap.cc
+++ b/apt-pkg/contrib/mmap.cc
@@ -38,7 +38,7 @@
// ---------------------------------------------------------------------
/* */
MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
- Base(0), SyncToFd(NULL)
+ Base(nullptr), SyncToFd(nullptr)
{
if ((Flags & NoImmMap) != NoImmMap)
Map(F);
@@ -48,7 +48,7 @@ MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
// ---------------------------------------------------------------------
/* */
MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0),
- Base(0), SyncToFd(NULL)
+ Base(nullptr), SyncToFd(nullptr)
{
}
/*}}}*/
@@ -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 == nullptr))
+ 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 == nullptr))
+ 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 == nullptr))
+ 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;