diff options
author | Sam Bingner <sam@bingner.com> | 2021-03-13 01:03:46 -1000 |
---|---|---|
committer | Sam Bingner <sam@bingner.com> | 2021-03-13 01:03:46 -1000 |
commit | 9d8383bdee9f1ddc5685c36678b1ca033cbea971 (patch) | |
tree | 5dcc8c91e9c0a1b85ef15654a1cf58e7869753c5 /apt-inst/contrib/extracttar.cc | |
parent | 11cd82291bb7a02cafbb271c8416f8b59e1f1413 (diff) | |
parent | 95e417cb069928dfdb5dfacb418f025d71f32c4d (diff) |
Merge remote-tracking branch 'upstream/1.8.2.z' into 1.8.2.z+ios1.8.2.z+ios
Diffstat (limited to 'apt-inst/contrib/extracttar.cc')
-rw-r--r-- | apt-inst/contrib/extracttar.cc | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/apt-inst/contrib/extracttar.cc b/apt-inst/contrib/extracttar.cc index 19ac1c8b1..cbee4d12a 100644 --- a/apt-inst/contrib/extracttar.cc +++ b/apt-inst/contrib/extracttar.cc @@ -55,7 +55,17 @@ struct ExtractTar::TarHeader char Major[8]; char Minor[8]; }; - + +// We need to read long names (names and link targets) into memory, so let's +// have a limit (shamelessly stolen from libarchive) to avoid people OOMing +// us with large streams. +static const unsigned long long APT_LONGNAME_LIMIT = 1048576llu; + +// A file size limit that we allow extracting. Currently, that's 128 GB. +// We also should leave some wiggle room for code adding files to it, and +// possibly conversion for signed, so this should not be larger than like 2**62. +static const unsigned long long APT_FILESIZE_LIMIT = 1llu << 37; + // ExtractTar::ExtractTar - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -170,6 +180,11 @@ bool ExtractTar::Go(pkgDirStream &Stream) StrToNum(Tar->Minor,Itm.Minor,sizeof(Tar->Minor),8) == false) return _error->Error(_("Corrupted archive")); + // Security check. Prevents overflows below the code when rounding up in skip/copy code, + // and provides modest protection against decompression bombs. + if (Itm.Size > APT_FILESIZE_LIMIT) + return _error->Error("Tar member too large: %llu > %llu bytes", Itm.Size, APT_FILESIZE_LIMIT); + // Grab the filename and link target: use last long name if one was // set, otherwise use the header value as-is, but remember that it may // fill the entire 100-byte block and needs to be zero-terminated. @@ -222,6 +237,8 @@ bool ExtractTar::Go(pkgDirStream &Stream) { unsigned long long Length = Itm.Size; unsigned char Block[512]; + if (Length > APT_LONGNAME_LIMIT) + return _error->Error("Long name to large: %llu bytes > %llu bytes", Length, APT_LONGNAME_LIMIT); while (Length > 0) { if (InFd.Read(Block,sizeof(Block),true) == false) @@ -241,6 +258,8 @@ bool ExtractTar::Go(pkgDirStream &Stream) { unsigned long long Length = Itm.Size; unsigned char Block[512]; + if (Length > APT_LONGNAME_LIMIT) + return _error->Error("Long name to large: %llu bytes > %llu bytes", Length, APT_LONGNAME_LIMIT); while (Length > 0) { if (InFd.Read(Block,sizeof(Block),true) == false) |