logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.git

0024-Do-not-raise-a-zip-bomb-alert-for-a-misplaced-centra.patch (5365B)


  1. From 9d516b8c761d3816f946aa8937ebf9fadfe6a002 Mon Sep 17 00:00:00 2001
  2. From: Mark Adler <madler@alumni.caltech.edu>
  3. Date: Fri, 31 Jan 2020 22:06:02 -0800
  4. Subject: [PATCH] Do not raise a zip bomb alert for a misplaced central
  5. directory.
  6. Do not raise a zip bomb alert for a misplaced central directory.
  7. There is a zip-like file in the Firefox distribution, omni.ja,
  8. which is a zip container with the central directory placed at the
  9. start of the file instead of after the local entries as required
  10. by the zip standard. This commit marks the actual location of the
  11. central directory, as well as the end of central directory records,
  12. as disallowed locations. This now permits such containers to not
  13. raise a zip bomb alert, where in fact there are no overlaps.
  14. ---
  15. extract.c | 25 +++++++++++++++++++------
  16. process.c | 6 ++++++
  17. unzpriv.h | 10 ++++++++++
  18. 3 files changed, 35 insertions(+), 6 deletions(-)
  19. diff --git a/extract.c b/extract.c
  20. index 1f078d1..ad5daac 100644
  21. --- a/extract.c
  22. +++ b/extract.c
  23. @@ -495,8 +495,11 @@ int extract_or_test_files(__G) /* return PK-type error code */
  24. }
  25. #endif /* !SFX || SFX_EXDIR */
  26. - /* One more: initialize cover structure for bomb detection. Start with a
  27. - span that covers the central directory though the end of the file. */
  28. + /* One more: initialize cover structure for bomb detection. Start with
  29. + spans that cover any extra bytes at the start, the central directory,
  30. + the end of central directory record (including the Zip64 end of central
  31. + directory locator, if present), and the Zip64 end of central directory
  32. + record, if present. */
  33. if (G.cover == NULL) {
  34. G.cover = malloc(sizeof(cover_t));
  35. if (G.cover == NULL) {
  36. @@ -508,15 +511,25 @@ int extract_or_test_files(__G) /* return PK-type error code */
  37. ((cover_t *)G.cover)->max = 0;
  38. }
  39. ((cover_t *)G.cover)->num = 0;
  40. - if ((G.extra_bytes != 0 &&
  41. - cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
  42. - cover_add((cover_t *)G.cover,
  43. + if (cover_add((cover_t *)G.cover,
  44. G.extra_bytes + G.ecrec.offset_start_central_directory,
  45. - G.ziplen) != 0) {
  46. + G.extra_bytes + G.ecrec.offset_start_central_directory +
  47. + G.ecrec.size_central_directory) != 0) {
  48. Info(slide, 0x401, ((char *)slide,
  49. LoadFarString(NotEnoughMemCover)));
  50. return PK_MEM;
  51. }
  52. + if ((G.extra_bytes != 0 &&
  53. + cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
  54. + (G.ecrec.have_ecr64 &&
  55. + cover_add((cover_t *)G.cover, G.ecrec.ec64_start,
  56. + G.ecrec.ec64_end) != 0) ||
  57. + cover_add((cover_t *)G.cover, G.ecrec.ec_start,
  58. + G.ecrec.ec_end) != 0) {
  59. + Info(slide, 0x401, ((char *)slide,
  60. + LoadFarString(OverlappedComponents)));
  61. + return PK_BOMB;
  62. + }
  63. /*---------------------------------------------------------------------------
  64. The basic idea of this function is as follows. Since the central di-
  65. diff --git a/process.c b/process.c
  66. index e4e7aee..d2a846e 100644
  67. --- a/process.c
  68. +++ b/process.c
  69. @@ -1408,6 +1408,10 @@ static int find_ecrec64(__G__ searchlen) /* return PK-class error */
  70. /* Now, we are (almost) sure that we have a Zip64 archive. */
  71. G.ecrec.have_ecr64 = 1;
  72. + G.ecrec.ec_start -= ECLOC64_SIZE+4;
  73. + G.ecrec.ec64_start = ecrec64_start_offset;
  74. + G.ecrec.ec64_end = ecrec64_start_offset +
  75. + 12 + makeint64(&byterec[ECREC64_LENGTH]);
  76. /* Update the "end-of-central-dir offset" for later checks. */
  77. G.real_ecrec_offset = ecrec64_start_offset;
  78. @@ -1542,6 +1546,8 @@ static int find_ecrec(__G__ searchlen) /* return PK-class error */
  79. makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
  80. G.ecrec.zipfile_comment_length =
  81. makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
  82. + G.ecrec.ec_start = G.real_ecrec_offset;
  83. + G.ecrec.ec_end = G.ecrec.ec_start + 22 + G.ecrec.zipfile_comment_length;
  84. /* Now, we have to read the archive comment, BEFORE the file pointer
  85. is moved away backwards to seek for a Zip64 ECLOC64 structure.
  86. diff --git a/unzpriv.h b/unzpriv.h
  87. index dc9eff5..297b3c7 100644
  88. --- a/unzpriv.h
  89. +++ b/unzpriv.h
  90. @@ -2185,6 +2185,16 @@ typedef struct VMStimbuf {
  91. int have_ecr64; /* valid Zip64 ecdir-record exists */
  92. int is_zip64_archive; /* Zip64 ecdir-record is mandatory */
  93. ush zipfile_comment_length;
  94. + zusz_t ec_start, ec_end; /* offsets of start and end of the
  95. + end of central directory record,
  96. + including if present the Zip64
  97. + end of central directory locator,
  98. + which immediately precedes the
  99. + end of central directory record */
  100. + zusz_t ec64_start, ec64_end; /* if have_ecr64 is true, then these
  101. + are the offsets of the start and
  102. + end of the Zip64 end of central
  103. + directory record */
  104. } ecdir_rec;
  105. --
  106. 2.25.0