mirror of
https://github.com/termux/termux-packages.git
synced 2025-02-23 01:07:10 +00:00
104 lines
4.6 KiB
Diff
104 lines
4.6 KiB
Diff
From: Mark Adler <madler@alumni.caltech.edu>
|
|
Subject: Do not raise a zip bomb alert for a misplaced central directory.
|
|
Origin: https://github.com/madler/unzip/commit/6d351831be705cc26d897db44f878a978f4138fc
|
|
Bug-Debian: https://bugs.debian.org/932404
|
|
X-Debian-version: 6.0-25
|
|
|
|
Do not raise a zip bomb alert for a misplaced central directory.
|
|
|
|
There is a zip-like file in the Firefox distribution, omni.ja,
|
|
which is a zip container with the central directory placed at the
|
|
start of the file instead of after the local entries as required
|
|
by the zip standard. This commit marks the actual location of the
|
|
central directory, as well as the end of central directory records,
|
|
as disallowed locations. This now permits such containers to not
|
|
raise a zip bomb alert, where in fact there are no overlaps.
|
|
|
|
--- a/extract.c
|
|
+++ b/extract.c
|
|
@@ -495,8 +495,11 @@
|
|
}
|
|
#endif /* !SFX || SFX_EXDIR */
|
|
|
|
- /* One more: initialize cover structure for bomb detection. Start with a
|
|
- span that covers the central directory though the end of the file. */
|
|
+ /* One more: initialize cover structure for bomb detection. Start with
|
|
+ spans that cover any extra bytes at the start, the central directory,
|
|
+ the end of central directory record (including the Zip64 end of central
|
|
+ directory locator, if present), and the Zip64 end of central directory
|
|
+ record, if present. */
|
|
if (G.cover == NULL) {
|
|
G.cover = malloc(sizeof(cover_t));
|
|
if (G.cover == NULL) {
|
|
@@ -508,15 +511,25 @@
|
|
((cover_t *)G.cover)->max = 0;
|
|
}
|
|
((cover_t *)G.cover)->num = 0;
|
|
- if ((G.extra_bytes != 0 &&
|
|
- cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
|
|
- cover_add((cover_t *)G.cover,
|
|
+ if (cover_add((cover_t *)G.cover,
|
|
G.extra_bytes + G.ecrec.offset_start_central_directory,
|
|
- G.ziplen) != 0) {
|
|
+ G.extra_bytes + G.ecrec.offset_start_central_directory +
|
|
+ G.ecrec.size_central_directory) != 0) {
|
|
Info(slide, 0x401, ((char *)slide,
|
|
LoadFarString(NotEnoughMemCover)));
|
|
return PK_MEM;
|
|
}
|
|
+ if ((G.extra_bytes != 0 &&
|
|
+ cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
|
|
+ (G.ecrec.have_ecr64 &&
|
|
+ cover_add((cover_t *)G.cover, G.ecrec.ec64_start,
|
|
+ G.ecrec.ec64_end) != 0) ||
|
|
+ cover_add((cover_t *)G.cover, G.ecrec.ec_start,
|
|
+ G.ecrec.ec_end) != 0) {
|
|
+ Info(slide, 0x401, ((char *)slide,
|
|
+ LoadFarString(OverlappedComponents)));
|
|
+ return PK_BOMB;
|
|
+ }
|
|
|
|
/*---------------------------------------------------------------------------
|
|
The basic idea of this function is as follows. Since the central di-
|
|
--- a/process.c
|
|
+++ b/process.c
|
|
@@ -1408,6 +1408,10 @@
|
|
|
|
/* Now, we are (almost) sure that we have a Zip64 archive. */
|
|
G.ecrec.have_ecr64 = 1;
|
|
+ G.ecrec.ec_start -= ECLOC64_SIZE+4;
|
|
+ G.ecrec.ec64_start = ecrec64_start_offset;
|
|
+ G.ecrec.ec64_end = ecrec64_start_offset +
|
|
+ 12 + makeint64(&byterec[ECREC64_LENGTH]);
|
|
|
|
/* Update the "end-of-central-dir offset" for later checks. */
|
|
G.real_ecrec_offset = ecrec64_start_offset;
|
|
@@ -1542,6 +1546,8 @@
|
|
makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
|
|
G.ecrec.zipfile_comment_length =
|
|
makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
|
|
+ G.ecrec.ec_start = G.real_ecrec_offset;
|
|
+ G.ecrec.ec_end = G.ecrec.ec_start + 22 + G.ecrec.zipfile_comment_length;
|
|
|
|
/* Now, we have to read the archive comment, BEFORE the file pointer
|
|
is moved away backwards to seek for a Zip64 ECLOC64 structure.
|
|
--- a/unzpriv.h
|
|
+++ b/unzpriv.h
|
|
@@ -2185,6 +2185,16 @@
|
|
int have_ecr64; /* valid Zip64 ecdir-record exists */
|
|
int is_zip64_archive; /* Zip64 ecdir-record is mandatory */
|
|
ush zipfile_comment_length;
|
|
+ zusz_t ec_start, ec_end; /* offsets of start and end of the
|
|
+ end of central directory record,
|
|
+ including if present the Zip64
|
|
+ end of central directory locator,
|
|
+ which immediately precedes the
|
|
+ end of central directory record */
|
|
+ zusz_t ec64_start, ec64_end; /* if have_ecr64 is true, then these
|
|
+ are the offsets of the start and
|
|
+ end of the Zip64 end of central
|
|
+ directory record */
|
|
} ecdir_rec;
|
|
|
|
|