summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/deb/debfile.cc15
-rwxr-xr-xtest/integration/test-cve-2020-273503
-rw-r--r--test/interactive-helper/createdeb-cve-2020-27350.cc4
3 files changed, 22 insertions, 0 deletions
diff --git a/apt-pkg/deb/debfile.cc b/apt-pkg/deb/debfile.cc
index f8d752e7f..bef0cd0d8 100644
--- a/apt-pkg/deb/debfile.cc
+++ b/apt-pkg/deb/debfile.cc
@@ -184,11 +184,23 @@ bool debDebFile::ControlExtract::DoItem(Item &Itm,int &Fd)
// ---------------------------------------------------------------------
/* This sets up to extract the control block member file into a memory
block of just the right size. All other files go into the bit bucket. */
+
+// Upper size limit for control files. Two reasons for having a limit here:
+//
+// 1. We read those files into memory and want to avoid being killed by OOM
+//
+// 2. We allocate (Itm.Size+2)-large arrays, so this can overflow if Itm.Size
+// becomes 2**64-2 or larger. This is obviously
+//
+// 64 MiB seems like a terribly large size that everyone should be happy with.
+static const unsigned long long DEB_CONTROL_SIZE_LIMIT = 64 * 1024 * 1024;
bool debDebFile::MemControlExtract::DoItem(Item &Itm,int &Fd)
{
// At the control file, allocate buffer memory.
if (Member == Itm.Name)
{
+ if (Itm.Size > DEB_CONTROL_SIZE_LIMIT)
+ return _error->Error("Control file too large: %llu > %llu bytes", Itm.Size, DEB_CONTROL_SIZE_LIMIT);
delete [] Control;
Control = new char[Itm.Size+2];
IsControl = true;
@@ -237,6 +249,9 @@ bool debDebFile::MemControlExtract::Read(debDebFile &Deb)
record. */
bool debDebFile::MemControlExtract::TakeControl(const void *Data,unsigned long long Size)
{
+ if (Size > DEB_CONTROL_SIZE_LIMIT)
+ return _error->Error("Control file too large: %llu > %llu bytes", Size, DEB_CONTROL_SIZE_LIMIT);
+
delete [] Control;
Control = new char[Size+2];
Length = Size;
diff --git a/test/integration/test-cve-2020-27350 b/test/integration/test-cve-2020-27350
index 336dc5b7e..f4bb79bcb 100755
--- a/test/integration/test-cve-2020-27350
+++ b/test/integration/test-cve-2020-27350
@@ -17,3 +17,6 @@ testequal "E: Long name to large: 67108865 bytes > 1048576 bytes" runapt ${APTTE
${APTTESTHELPERSBINDIR}/createdeb-cve-2020-27350 long-link long-link.deb
testequal "E: Long name to large: 67108865 bytes > 1048576 bytes" runapt ${APTTESTHELPERSBINDIR}/extract-control long-link.deb control
+
+${APTTESTHELPERSBINDIR}/createdeb-cve-2020-27350 long-control long-control.deb
+testequal "E: Control file too large: 67108865 > 67108864 bytes" runapt ${APTTESTHELPERSBINDIR}/extract-control long-control.deb control
diff --git a/test/interactive-helper/createdeb-cve-2020-27350.cc b/test/interactive-helper/createdeb-cve-2020-27350.cc
index 7c58eb9df..af049d4e8 100644
--- a/test/interactive-helper/createdeb-cve-2020-27350.cc
+++ b/test/interactive-helper/createdeb-cve-2020-27350.cc
@@ -303,6 +303,10 @@ int main(int argc, char *argv[])
{
createdeb_bigtarfilelength(fd, 'K');
}
+ else if (strcmp(mode, "long-control") == 0)
+ {
+ createdeb_bigtarfilelength(fd, '0');
+ }
else if (strcmp(mode, "test") == 0)
{
createdeb_test(fd);