* [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian
@ 2026-02-04 13:18 Thomas Perale via buildroot
2026-02-04 13:18 ` [Buildroot] [PATCH 2/4] package/heirloom-mailx: " Thomas Perale via buildroot
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Thomas Perale via buildroot @ 2026-02-04 13:18 UTC (permalink / raw)
To: buildroot; +Cc: Luca Ceresoli, Thomas Petazzoni
In Buildroot there are multiple way to apply patches on a package [1]
- Adding `.patch` file in the package directory.
- Define `<pkg>_PATCH` variable with the location of the patch tar.gz.
It used to download Debian patches tarball.
- Implement custom patching logic with `PRE`/`POST` patches hooks.
To make the CycloneDX SBOM generation not dependant on downloading the
packages, the two last options have the downside of not appearing on the
generated SBOM.
The unzip package is downloading a tarball from the Debian mirror with
the `<pkg>_PATCH` method [2].
To improve the tracking of the patched vulnerabilities for the unzip
package this commit import the patches previously downloaded with the
`_PATCH` variable in the Buildroot tree.
This allows to add the `CVE:` trailer [3] on the patches that fix
vulnerabilities to better track which patch is fixing the vulnerability.
[1] https://buildroot.org/downloads/manual/manual.html#patch-policy
[2] https://snapshot.debian.org/archive/debian/20250311T215724Z/pool/main/u/unzip/unzip_6.0-29.debian.tar.xz
[3] 1167d0ff3d docs/manual: mention CVE trailer
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
---
.checkpackageignore | 1 -
...pages-in-section-1-not-in-section-1l.patch | 297 +++++++++++++++
package/unzip/0002-this-is-debian-unzip.patch | 18 +
.../0003-include-unistd-for-kfreebsd.patch | 17 +
.../0004-handle-pkware-verification-bit.patch | 23 ++
package/unzip/0005-fix-uid-gid-handling.patch | 31 ++
.../0006-initialize-the-symlink-flag.patch | 22 ++
.../0007-increase-size-of-cfactorstr.patch | 19 +
.../0008-allow-greater-hostver-values.patch | 16 +
.../0009-cve-2014-8139-crc-overflow.patch | 56 +++
.../0010-cve-2014-8140-test-compr-eb.patch | 30 ++
.../0011-cve-2014-8141-getzip64data.patch | 140 ++++++++
.../0012-cve-2014-9636-test-compr-eb.patch | 44 +++
package/unzip/0013-remove-build-date.patch | 20 ++
package/unzip/0014-cve-2015-7696.patch | 35 ++
package/unzip/0015-cve-2015-7697.patch | 29 ++
...fix-integer-underflow-csiz-decrypted.patch | 34 ++
...7-restore-unix-timestamps-accurately.patch | 43 +++
...-cve-2014-9913-unzip-buffer-overflow.patch | 32 ++
...ve-2016-9844-zipinfo-buffer-overflow.patch | 31 ++
...e-2018-1000035-unzip-buffer-overflow.patch | 39 ++
...21-fix-warning-messages-on-big-files.patch | 16 +
...-2019-13232-fix-bug-in-undefer-input.patch | 25 ++
...232-zip-bomb-with-overlapped-entries.patch | 338 ++++++++++++++++++
...lert-for-misplaced-central-directory.patch | 106 ++++++
...-cve-2019-13232-fix-bug-in-uzbunzip2.patch | 26 ++
...-cve-2019-13232-fix-bug-in-uzinflate.patch | 26 ++
.../0027-zipgrep-avoid-test-errors.patch | 17 +
...0028-cve-2022-0529-and-cve-2022-0530.patch | 177 +++++++++
.../0029-handle-windows-zip64-files.patch | 21 ++
.../0030-drop-conflicting-declarations.patch | 18 +
package/unzip/0031-fix-zipgrep.patch | 20 ++
...eFile.txt-to-ease-cross-compilation.patch} | 1 +
package/unzip/unzip.mk | 55 ++-
34 files changed, 1806 insertions(+), 17 deletions(-)
create mode 100644 package/unzip/0001-manpages-in-section-1-not-in-section-1l.patch
create mode 100644 package/unzip/0002-this-is-debian-unzip.patch
create mode 100644 package/unzip/0003-include-unistd-for-kfreebsd.patch
create mode 100644 package/unzip/0004-handle-pkware-verification-bit.patch
create mode 100644 package/unzip/0005-fix-uid-gid-handling.patch
create mode 100644 package/unzip/0006-initialize-the-symlink-flag.patch
create mode 100644 package/unzip/0007-increase-size-of-cfactorstr.patch
create mode 100644 package/unzip/0008-allow-greater-hostver-values.patch
create mode 100644 package/unzip/0009-cve-2014-8139-crc-overflow.patch
create mode 100644 package/unzip/0010-cve-2014-8140-test-compr-eb.patch
create mode 100644 package/unzip/0011-cve-2014-8141-getzip64data.patch
create mode 100644 package/unzip/0012-cve-2014-9636-test-compr-eb.patch
create mode 100644 package/unzip/0013-remove-build-date.patch
create mode 100644 package/unzip/0014-cve-2015-7696.patch
create mode 100644 package/unzip/0015-cve-2015-7697.patch
create mode 100644 package/unzip/0016-fix-integer-underflow-csiz-decrypted.patch
create mode 100644 package/unzip/0017-restore-unix-timestamps-accurately.patch
create mode 100644 package/unzip/0018-cve-2014-9913-unzip-buffer-overflow.patch
create mode 100644 package/unzip/0019-cve-2016-9844-zipinfo-buffer-overflow.patch
create mode 100644 package/unzip/0020-cve-2018-1000035-unzip-buffer-overflow.patch
create mode 100644 package/unzip/0021-fix-warning-messages-on-big-files.patch
create mode 100644 package/unzip/0022-cve-2019-13232-fix-bug-in-undefer-input.patch
create mode 100644 package/unzip/0023-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
create mode 100644 package/unzip/0024-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
create mode 100644 package/unzip/0025-cve-2019-13232-fix-bug-in-uzbunzip2.patch
create mode 100644 package/unzip/0026-cve-2019-13232-fix-bug-in-uzinflate.patch
create mode 100644 package/unzip/0027-zipgrep-avoid-test-errors.patch
create mode 100644 package/unzip/0028-cve-2022-0529-and-cve-2022-0530.patch
create mode 100644 package/unzip/0029-handle-windows-zip64-files.patch
create mode 100644 package/unzip/0030-drop-conflicting-declarations.patch
create mode 100644 package/unzip/0031-fix-zipgrep.patch
rename package/unzip/{0001-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch => 0101-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch} (99%)
diff --git a/.checkpackageignore b/.checkpackageignore
index a04e96ac00..8e0a283441 100644
--- a/.checkpackageignore
+++ b/.checkpackageignore
@@ -967,7 +967,6 @@ package/uhttpd/0002-Fix-TCP_FASTOPEN-related-compile-error.patch lib_patch.Upstr
package/unbound/S70unbound Shellcheck
package/unifdef/0001-Makefile-fix-error-on-install.patch lib_patch.Upstream
package/unscd/S46unscd Shellcheck lib_sysv.Indent lib_sysv.Variables
-package/unzip/0001-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch lib_patch.Upstream
package/upmpdcli/S99upmpdcli Shellcheck lib_sysv.Indent lib_sysv.Variables
package/urg/0001-select-h.patch lib_patch.Upstream
package/urg/0002-urg-gcc6-fix-narrowing-conversion.patch lib_patch.Upstream
diff --git a/package/unzip/0001-manpages-in-section-1-not-in-section-1l.patch b/package/unzip/0001-manpages-in-section-1-not-in-section-1l.patch
new file mode 100644
index 0000000000..9d8f3ef241
--- /dev/null
+++ b/package/unzip/0001-manpages-in-section-1-not-in-section-1l.patch
@@ -0,0 +1,297 @@
+From: Santiago Vila <sanvila@debian.org>
+Subject: In Debian, manpages are in section 1, not in section 1L
+X-Debian-version: 5.52-3
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/01-manpages-in-section-1-not-in-section-1l.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/man/funzip.1
++++ b/man/funzip.1
+@@ -20,7 +20,7 @@
+ .in -4n
+ ..
+ .\" =========================================================================
+-.TH FUNZIP 1L "20 April 2009 (v3.95)" "Info-ZIP"
++.TH FUNZIP 1 "20 April 2009 (v3.95)" "Info-ZIP"
+ .SH NAME
+ funzip \- filter for extracting from a ZIP archive in a pipe
+ .PD
+@@ -78,7 +78,7 @@
+ .EE
+ .PP
+ To use \fIzip\fP and \fIfunzip\fP in place of \fIcompress\fP(1) and
+-\fIzcat\fP(1) (or \fIgzip\fP(1L) and \fIgzcat\fP(1L)) for tape backups:
++\fIzcat\fP(1) (or \fIgzip\fP(1) and \fIgzcat\fP(1)) for tape backups:
+ .PP
+ .EX
+ tar cf \- . | zip \-7 | dd of=/dev/nrst0 obs=8k
+@@ -108,8 +108,8 @@
+ .PD
+ .\" =========================================================================
+ .SH "SEE ALSO"
+-\fIgzip\fP(1L), \fIunzip\fP(1L), \fIunzipsfx\fP(1L), \fIzip\fP(1L),
+-\fIzipcloak\fP(1L), \fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
++\fIgzip\fP(1), \fIunzip\fP(1), \fIunzipsfx\fP(1), \fIzip\fP(1),
++\fIzipcloak\fP(1), \fIzipinfo\fP(1), \fIzipnote\fP(1), \fIzipsplit\fP(1)
+ .PD
+ .\" =========================================================================
+ .SH URL
+--- a/man/unzip.1
++++ b/man/unzip.1
+@@ -20,7 +20,7 @@
+ .in -4n
+ ..
+ .\" =========================================================================
+-.TH UNZIP 1L "20 April 2009 (v6.0)" "Info-ZIP"
++.TH UNZIP 1 "20 April 2009 (v6.0)" "Info-ZIP"
+ .SH NAME
+ unzip \- list, test and extract compressed files in a ZIP archive
+ .PD
+@@ -34,7 +34,7 @@
+ \fIunzip\fP will list, test, or extract files from a ZIP archive, commonly
+ found on MS-DOS systems. The default behavior (with no options) is to extract
+ into the current directory (and subdirectories below it) all files from the
+-specified ZIP archive. A companion program, \fIzip\fP(1L), creates ZIP
++specified ZIP archive. A companion program, \fIzip\fP(1), creates ZIP
+ archives; both programs are compatible with archives created by PKWARE's
+ \fIPKZIP\fP and \fIPKUNZIP\fP for MS-DOS, but in many cases the program
+ options or default behaviors differ.
+@@ -105,8 +105,8 @@
+ list of all possible flags. The exhaustive list follows:
+ .TP
+ .B \-Z
+-\fIzipinfo\fP(1L) mode. If the first option on the command line is \fB\-Z\fP,
+-the remaining options are taken to be \fIzipinfo\fP(1L) options. See the
++\fIzipinfo\fP(1) mode. If the first option on the command line is \fB\-Z\fP,
++the remaining options are taken to be \fIzipinfo\fP(1) options. See the
+ appropriate manual page for a description of these options.
+ .TP
+ .B \-A
+@@ -178,7 +178,7 @@
+ compressed size and compression ratio figures are independent of the entry's
+ encryption status and show the correct compression performance. (The complete
+ size of the encrypted compressed data stream for zipfile entries is reported
+-by the more verbose \fIzipinfo\fP(1L) reports, see the separate manual.)
++by the more verbose \fIzipinfo\fP(1) reports, see the separate manual.)
+ When no zipfile is specified (that is, the complete command is simply
+ ``\fCunzip \-v\fR''), a diagnostic screen is printed. In addition to
+ the normal header with release date and version, \fIunzip\fP lists the
+@@ -379,8 +379,8 @@
+ .TP
+ .B \-N
+ [Amiga] extract file comments as Amiga filenotes. File comments are created
+-with the \-c option of \fIzip\fP(1L), or with the \-N option of the Amiga port
+-of \fIzip\fP(1L), which stores filenotes as comments.
++with the \-c option of \fIzip\fP(1), or with the \-N option of the Amiga port
++of \fIzip\fP(1), which stores filenotes as comments.
+ .TP
+ .B \-o
+ overwrite existing files without prompting. This is a dangerous option, so
+@@ -598,7 +598,7 @@
+ As suggested by the examples above, the default variable names are UNZIP_OPTS
+ for VMS (where the symbol used to install \fIunzip\fP as a foreign command
+ would otherwise be confused with the environment variable), and UNZIP
+-for all other operating systems. For compatibility with \fIzip\fP(1L),
++for all other operating systems. For compatibility with \fIzip\fP(1),
+ UNZIPOPT is also accepted (don't ask). If both UNZIP and UNZIPOPT
+ are defined, however, UNZIP takes precedence. \fIunzip\fP's diagnostic
+ option (\fB\-v\fP with no zipfile name) can be used to check the values
+@@ -648,8 +648,8 @@
+ a password is not known, entering a null password (that is, just a carriage
+ return or ``Enter'') is taken as a signal to skip all further prompting.
+ Only unencrypted files in the archive(s) will thereafter be extracted. (In
+-fact, that's not quite true; older versions of \fIzip\fP(1L) and
+-\fIzipcloak\fP(1L) allowed null passwords, so \fIunzip\fP checks each encrypted
++fact, that's not quite true; older versions of \fIzip\fP(1) and
++\fIzipcloak\fP(1) allowed null passwords, so \fIunzip\fP checks each encrypted
+ file to see if the null password works. This may result in ``false positives''
+ and extraction errors, as noted above.)
+ .PP
+@@ -943,8 +943,8 @@
+ .PD
+ .\" =========================================================================
+ .SH "SEE ALSO"
+-\fIfunzip\fP(1L), \fIzip\fP(1L), \fIzipcloak\fP(1L), \fIzipgrep\fP(1L),
+-\fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
++\fIfunzip\fP(1), \fIzip\fP(1), \fIzipcloak\fP(1), \fIzipgrep\fP(1),
++\fIzipinfo\fP(1), \fIzipnote\fP(1), \fIzipsplit\fP(1)
+ .PD
+ .\" =========================================================================
+ .SH URL
+--- a/man/unzipsfx.1
++++ b/man/unzipsfx.1
+@@ -20,7 +20,7 @@
+ .in -4n
+ ..
+ .\" =========================================================================
+-.TH UNZIPSFX 1L "20 April 2009 (v6.0)" "Info-ZIP"
++.TH UNZIPSFX 1 "20 April 2009 (v6.0)" "Info-ZIP"
+ .SH NAME
+ unzipsfx \- self-extracting stub for prepending to ZIP archives
+ .PD
+@@ -30,7 +30,7 @@
+ .PD
+ .\" =========================================================================
+ .SH DESCRIPTION
+-\fIunzipsfx\fP is a modified version of \fIunzip\fP(1L) designed to be
++\fIunzipsfx\fP is a modified version of \fIunzip\fP(1) designed to be
+ prepended to existing ZIP archives in order to form self-extracting archives.
+ Instead of taking its first non-flag argument to be the zipfile(s) to be
+ extracted, \fIunzipsfx\fP seeks itself under the name by which it was invoked
+@@ -109,7 +109,7 @@
+ .PD
+ .\" =========================================================================
+ .SH OPTIONS
+-\fIunzipsfx\fP supports the following \fIunzip\fP(1L) options: \fB\-c\fP
++\fIunzipsfx\fP supports the following \fIunzip\fP(1) options: \fB\-c\fP
+ and \fB\-p\fP (extract to standard output/screen), \fB\-f\fP and \fB\-u\fP
+ (freshen and update existing files upon extraction), \fB\-t\fP (test
+ archive) and \fB\-z\fP (print archive comment). All normal listing options
+@@ -118,11 +118,11 @@
+ those creating self-extracting archives may wish to include a short listing
+ in the zipfile comment.
+ .PP
+-See \fIunzip\fP(1L) for a more complete description of these options.
++See \fIunzip\fP(1) for a more complete description of these options.
+ .PD
+ .\" =========================================================================
+ .SH MODIFIERS
+-\fIunzipsfx\fP currently supports all \fIunzip\fP(1L) modifiers: \fB\-a\fP
++\fIunzipsfx\fP currently supports all \fIunzip\fP(1) modifiers: \fB\-a\fP
+ (convert text files), \fB\-n\fP (never overwrite), \fB\-o\fP (overwrite
+ without prompting), \fB\-q\fP (operate quietly), \fB\-C\fP (match names
+ case-insensitively), \fB\-L\fP (convert uppercase-OS names to lowercase),
+@@ -137,18 +137,18 @@
+ of course continue to be supported since the zipfile format implies ASCII
+ storage of text files.)
+ .PP
+-See \fIunzip\fP(1L) for a more complete description of these modifiers.
++See \fIunzip\fP(1) for a more complete description of these modifiers.
+ .PD
+ .\" =========================================================================
+ .SH "ENVIRONMENT OPTIONS"
+-\fIunzipsfx\fP uses the same environment variables as \fIunzip\fP(1L) does,
++\fIunzipsfx\fP uses the same environment variables as \fIunzip\fP(1) does,
+ although this is likely to be an issue only for the person creating and
+-testing the self-extracting archive. See \fIunzip\fP(1L) for details.
++testing the self-extracting archive. See \fIunzip\fP(1) for details.
+ .PD
+ .\" =========================================================================
+ .SH DECRYPTION
+-Decryption is supported exactly as in \fIunzip\fP(1L); that is, interactively
+-with a non-echoing prompt for the password(s). See \fIunzip\fP(1L) for
++Decryption is supported exactly as in \fIunzip\fP(1); that is, interactively
++with a non-echoing prompt for the password(s). See \fIunzip\fP(1) for
+ details. Once again, note that if the archive has no encrypted files there
+ is no reason to use a version of \fIunzipsfx\fP with decryption support;
+ that only adds to the size of the archive.
+@@ -286,7 +286,7 @@
+ from anywhere in the user's path. The situation is not known for AmigaDOS,
+ Atari TOS, MacOS, etc.
+ .PP
+-As noted above, a number of the normal \fIunzip\fP(1L) functions have
++As noted above, a number of the normal \fIunzip\fP(1) functions have
+ been removed in order to make \fIunzipsfx\fP smaller: usage and diagnostic
+ info, listing functions and extraction to other directories. Also, only
+ stored and deflated files are supported. The latter limitation is mainly
+@@ -303,17 +303,17 @@
+ defined as a ``debug hunk.'') There may be compatibility problems between
+ the ROM levels of older Amigas and newer ones.
+ .PP
+-All current bugs in \fIunzip\fP(1L) exist in \fIunzipsfx\fP as well.
++All current bugs in \fIunzip\fP(1) exist in \fIunzipsfx\fP as well.
+ .PD
+ .\" =========================================================================
+ .SH DIAGNOSTICS
+ \fIunzipsfx\fP's exit status (error level) is identical to that of
+-\fIunzip\fP(1L); see the corresponding man page.
++\fIunzip\fP(1); see the corresponding man page.
+ .PD
+ .\" =========================================================================
+ .SH "SEE ALSO"
+-\fIfunzip\fP(1L), \fIunzip\fP(1L), \fIzip\fP(1L), \fIzipcloak\fP(1L),
+-\fIzipgrep\fP(1L), \fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
++\fIfunzip\fP(1), \fIunzip\fP(1), \fIzip\fP(1), \fIzipcloak\fP(1),
++\fIzipgrep\fP(1), \fIzipinfo\fP(1), \fIzipnote\fP(1), \fIzipsplit\fP(1)
+ .PD
+ .PD
+ .\" =========================================================================
+@@ -330,7 +330,7 @@
+ .\" =========================================================================
+ .SH AUTHORS
+ Greg Roelofs was responsible for the basic modifications to UnZip necessary
+-to create UnZipSFX. See \fIunzip\fP(1L) for the current list of Zip-Bugs
++to create UnZipSFX. See \fIunzip\fP(1) for the current list of Zip-Bugs
+ authors, or the file CONTRIBS in the UnZip source distribution for the
+ full list of Info-ZIP contributors.
+ .PD
+--- a/man/zipgrep.1
++++ b/man/zipgrep.1
+@@ -8,7 +8,7 @@
+ .\" zipgrep.1 by Greg Roelofs.
+ .\"
+ .\" =========================================================================
+-.TH ZIPGREP 1L "20 April 2009" "Info-ZIP"
++.TH ZIPGREP 1 "20 April 2009" "Info-ZIP"
+ .SH NAME
+ zipgrep \- search files in a ZIP archive for lines matching a pattern
+ .PD
+@@ -21,7 +21,7 @@
+ .SH DESCRIPTION
+ \fIzipgrep\fP will search files within a ZIP archive for lines matching
+ the given string or pattern. \fIzipgrep\fP is a shell script and requires
+-\fIegrep\fP(1) and \fIunzip\fP(1L) to function. Its output is identical to
++\fIegrep\fP(1) and \fIunzip\fP(1) to function. Its output is identical to
+ that of \fIegrep\fP(1).
+ .PD
+ .\" =========================================================================
+@@ -69,8 +69,8 @@
+ .PD
+ .\" =========================================================================
+ .SH "SEE ALSO"
+-\fIegrep\fP(1), \fIunzip\fP(1L), \fIzip\fP(1L), \fIfunzip\fP(1L),
+-\fIzipcloak\fP(1L), \fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
++\fIegrep\fP(1), \fIunzip\fP(1), \fIzip\fP(1), \fIfunzip\fP(1),
++\fIzipcloak\fP(1), \fIzipinfo\fP(1), \fIzipnote\fP(1), \fIzipsplit\fP(1)
+ .PD
+ .\" =========================================================================
+ .SH URL
+--- a/man/zipinfo.1
++++ b/man/zipinfo.1
+@@ -34,7 +34,7 @@
+ .in -4n
+ ..
+ .\" =========================================================================
+-.TH ZIPINFO 1L "20 April 2009 (v3.0)" "Info-ZIP"
++.TH ZIPINFO 1 "20 April 2009 (v3.0)" "Info-ZIP"
+ .SH NAME
+ zipinfo \- list detailed information about a ZIP archive
+ .PD
+@@ -272,7 +272,7 @@
+ Note that because of limitations in the MS-DOS format used to store file
+ times, the seconds field is always rounded to the nearest even second.
+ For Unix files this is expected to change in the next major releases of
+-\fIzip\fP(1L) and \fIunzip\fP.
++\fIzip\fP(1) and \fIunzip\fP.
+ .PP
+ In addition to individual file information, a default zipfile listing
+ also includes header and trailer lines:
+@@ -361,7 +361,7 @@
+ As suggested above, the default variable names are ZIPINFO_OPTS for VMS
+ (where the symbol used to install \fIzipinfo\fP as a foreign command
+ would otherwise be confused with the environment variable), and ZIPINFO
+-for all other operating systems. For compatibility with \fIzip\fP(1L),
++for all other operating systems. For compatibility with \fIzip\fP(1),
+ ZIPINFOOPT is also accepted (don't ask). If both ZIPINFO and ZIPINFOOPT
+ are defined, however, ZIPINFO takes precedence. \fIunzip\fP's diagnostic
+ option (\fB\-v\fP with no zipfile name) can be used to check the values
+@@ -496,8 +496,8 @@
+ .PP
+ .\" =========================================================================
+ .SH "SEE ALSO"
+-\fIls\fP(1), \fIfunzip\fP(1L), \fIunzip\fP(1L), \fIunzipsfx\fP(1L),
+-\fIzip\fP(1L), \fIzipcloak\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
++\fIls\fP(1), \fIfunzip\fP(1), \fIunzip\fP(1), \fIunzipsfx\fP(1),
++\fIzip\fP(1), \fIzipcloak\fP(1), \fIzipnote\fP(1), \fIzipsplit\fP(1)
+ .PD
+ .\" =========================================================================
+ .SH URL
diff --git a/package/unzip/0002-this-is-debian-unzip.patch b/package/unzip/0002-this-is-debian-unzip.patch
new file mode 100644
index 0000000000..8a9bd69a23
--- /dev/null
+++ b/package/unzip/0002-this-is-debian-unzip.patch
@@ -0,0 +1,18 @@
+From: Santiago Vila <sanvila@debian.org>
+Subject: "Branding patch": UnZip by Debian. Original by Info-ZIP.
+X-Debian-version: 5.52-5
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/02-this-is-debian-unzip.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/unzip.c
++++ b/unzip.c
+@@ -570,8 +570,7 @@
+ #else /* !VMS */
+ # ifdef COPYRIGHT_CLEAN
+ static ZCONST char Far UnzipUsageLine1[] = "\
+-UnZip %d.%d%d%s of %s, by Info-ZIP. Maintained by C. Spieler. Send\n\
+-bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
++UnZip %d.%d%d%s of %s, by Debian. Original by Info-ZIP.\
+ \n\n";
+ # else
+ static ZCONST char Far UnzipUsageLine1[] = "\
diff --git a/package/unzip/0003-include-unistd-for-kfreebsd.patch b/package/unzip/0003-include-unistd-for-kfreebsd.patch
new file mode 100644
index 0000000000..419c5954c1
--- /dev/null
+++ b/package/unzip/0003-include-unistd-for-kfreebsd.patch
@@ -0,0 +1,17 @@
+From: Aurelien Jarno <aurel32@debian.org>
+Subject: #include <unistd.h> for kFreeBSD
+Bug-Debian: https://bugs.debian.org/340693
+X-Debian-version: 5.52-8
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/03-include-unistd-for-kfreebsd.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/unix/unxcfg.h
++++ b/unix/unxcfg.h
+@@ -52,6 +52,7 @@
+
+ #include <sys/types.h> /* off_t, time_t, dev_t, ... */
+ #include <sys/stat.h>
++#include <unistd.h>
+
+ #ifdef NO_OFF_T
+ typedef long zoff_t;
diff --git a/package/unzip/0004-handle-pkware-verification-bit.patch b/package/unzip/0004-handle-pkware-verification-bit.patch
new file mode 100644
index 0000000000..58a3f2092e
--- /dev/null
+++ b/package/unzip/0004-handle-pkware-verification-bit.patch
@@ -0,0 +1,23 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Handle the PKWare verification bit of internal attributes
+Bug-Debian: https://bugs.debian.org/630078
+X-Debian-version: 6.0-5
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/04-handle-pkware-verification-bit.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/process.c
++++ b/process.c
+@@ -1729,6 +1729,13 @@
+ else if (uO.L_flag > 1) /* let -LL force lower case for all names */
+ G.pInfo->lcflag = 1;
+
++ /* Handle the PKWare verification bit, bit 2 (0x0004) of internal
++ attributes. If this is set, then a verification checksum is in the
++ first 3 bytes of the external attributes. In this case all we can use
++ for setting file attributes is the last external attributes byte. */
++ if (G.crec.internal_file_attributes & 0x0004)
++ G.crec.external_file_attributes &= (ulg)0xff;
++
+ /* do Amigas (AMIGA_) also have volume labels? */
+ if (IS_VOLID(G.crec.external_file_attributes) &&
+ (G.pInfo->hostnum == FS_FAT_ || G.pInfo->hostnum == FS_HPFS_ ||
diff --git a/package/unzip/0005-fix-uid-gid-handling.patch b/package/unzip/0005-fix-uid-gid-handling.patch
new file mode 100644
index 0000000000..eb229f5f2a
--- /dev/null
+++ b/package/unzip/0005-fix-uid-gid-handling.patch
@@ -0,0 +1,31 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Restore uid and gid information when requested
+Bug-Debian: https://bugs.debian.org/689212
+X-Debian-version: 6.0-8
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/05-fix-uid-gid-handling.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/process.c
++++ b/process.c
+@@ -2904,7 +2904,7 @@
+ #ifdef IZ_HAVE_UXUIDGID
+ if (eb_len >= EB_UX3_MINLEN
+ && z_uidgid != NULL
+- && (*((EB_HEADSIZE + 0) + ef_buf) == 1)
++ && (*((EB_HEADSIZE + 0) + ef_buf) == 1))
+ /* only know about version 1 */
+ {
+ uch uid_size;
+@@ -2916,10 +2916,10 @@
+ flags &= ~0x0ff; /* ignore any previous UNIX field */
+
+ if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
+- uid_size, z_uidgid[0])
++ uid_size, &z_uidgid[0])
+ &&
+ read_ux3_value((EB_HEADSIZE + uid_size + 3) + ef_buf,
+- gid_size, z_uidgid[1]) )
++ gid_size, &z_uidgid[1]) )
+ {
+ flags |= EB_UX2_VALID; /* signal success */
+ }
diff --git a/package/unzip/0006-initialize-the-symlink-flag.patch b/package/unzip/0006-initialize-the-symlink-flag.patch
new file mode 100644
index 0000000000..70c02edaef
--- /dev/null
+++ b/package/unzip/0006-initialize-the-symlink-flag.patch
@@ -0,0 +1,22 @@
+From: Andreas Schwab <schwab@linux-m68k.org>
+Subject: Initialize the symlink flag
+Bug-Debian: https://bugs.debian.org/717029
+X-Debian-version: 6.0-10
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/06-initialize-the-symlink-flag.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/process.c
++++ b/process.c
+@@ -1758,6 +1758,12 @@
+ = (G.crec.general_purpose_bit_flag & (1 << 11)) == (1 << 11);
+ #endif
+
++#ifdef SYMLINKS
++ /* Initialize the symlink flag, may be set by the platform-specific
++ mapattr function. */
++ G.pInfo->symlink = 0;
++#endif
++
+ return PK_COOL;
+
+ } /* end function process_cdir_file_hdr() */
diff --git a/package/unzip/0007-increase-size-of-cfactorstr.patch b/package/unzip/0007-increase-size-of-cfactorstr.patch
new file mode 100644
index 0000000000..2d13962f7f
--- /dev/null
+++ b/package/unzip/0007-increase-size-of-cfactorstr.patch
@@ -0,0 +1,19 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Increase size of cfactorstr array to avoid buffer overflow
+Bug-Debian: https://bugs.debian.org/741384
+X-Debian-version: 6.0-11
+CVE: CVE-2018-18384
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/07-increase-size-of-cfactorstr.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/list.c
++++ b/list.c
+@@ -97,7 +97,7 @@
+ {
+ int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
+ #ifndef WINDLL
+- char sgn, cfactorstr[10];
++ char sgn, cfactorstr[12];
+ int longhdr=(uO.vflag>1);
+ #endif
+ int date_format;
diff --git a/package/unzip/0008-allow-greater-hostver-values.patch b/package/unzip/0008-allow-greater-hostver-values.patch
new file mode 100644
index 0000000000..10038cfed6
--- /dev/null
+++ b/package/unzip/0008-allow-greater-hostver-values.patch
@@ -0,0 +1,16 @@
+From: Santiago Vila <sanvila@debian.org>
+Subject: zipinfo.c: Do not crash when hostver byte is >= 100
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/08-allow-greater-hostver-values.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/zipinfo.c
++++ b/zipinfo.c
+@@ -2114,7 +2114,7 @@
+ else
+ attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T==undefined */
+
+- sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
++ sprintf(&attribs[11], "%2u.%u", hostver/10, hostver%10);
+ break;
+
+ } /* end switch (hostnum: external attributes format) */
diff --git a/package/unzip/0009-cve-2014-8139-crc-overflow.patch b/package/unzip/0009-cve-2014-8139-crc-overflow.patch
new file mode 100644
index 0000000000..5ff301a344
--- /dev/null
+++ b/package/unzip/0009-cve-2014-8139-crc-overflow.patch
@@ -0,0 +1,56 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Fix CVE-2014-8139: CRC32 verification heap-based overflow
+Bug-Debian: https://bugs.debian.org/773722
+CVE: CVE-2014-8139
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/09-cve-2014-8139-crc-overflow.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/extract.c
++++ b/extract.c
+@@ -1,5 +1,5 @@
+ /*
+- Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
++ Copyright (c) 1990-2014 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+@@ -298,6 +298,8 @@
+ #ifndef SFX
+ static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
+ EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
++ static ZCONST char Far TooSmallEBlength[] = "bad extra-field entry:\n \
++ EF block length (%u bytes) invalid (< %d)\n";
+ static ZCONST char Far InvalidComprDataEAs[] =
+ " invalid compressed data for EAs\n";
+ # if (defined(WIN32) && defined(NTSD_EAS))
+@@ -2023,7 +2025,8 @@
+ ebID = makeword(ef);
+ ebLen = (unsigned)makeword(ef+EB_LEN);
+
+- if (ebLen > (ef_len - EB_HEADSIZE)) {
++ if (ebLen > (ef_len - EB_HEADSIZE))
++ {
+ /* Discovered some extra field inconsistency! */
+ if (uO.qflag)
+ Info(slide, 1, ((char *)slide, "%-22s ",
+@@ -2158,11 +2161,19 @@
+ }
+ break;
+ case EF_PKVMS:
+- if (makelong(ef+EB_HEADSIZE) !=
++ if (ebLen < 4)
++ {
++ Info(slide, 1,
++ ((char *)slide, LoadFarString(TooSmallEBlength),
++ ebLen, 4));
++ }
++ else if (makelong(ef+EB_HEADSIZE) !=
+ crc32(CRCVAL_INITIAL, ef+(EB_HEADSIZE+4),
+ (extent)(ebLen-4)))
++ {
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(BadCRC_EAs)));
++ }
+ break;
+ case EF_PKW32:
+ case EF_PKUNIX:
diff --git a/package/unzip/0010-cve-2014-8140-test-compr-eb.patch b/package/unzip/0010-cve-2014-8140-test-compr-eb.patch
new file mode 100644
index 0000000000..046efca3b5
--- /dev/null
+++ b/package/unzip/0010-cve-2014-8140-test-compr-eb.patch
@@ -0,0 +1,30 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Fix CVE-2014-8140: out-of-bounds write issue in test_compr_eb()
+Bug-Debian: https://bugs.debian.org/773722
+CVE: CVE-2014-8140
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/10-cve-2014-8140-test-compr-eb.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/extract.c
++++ b/extract.c
+@@ -2232,10 +2232,17 @@
+ if (compr_offset < 4) /* field is not compressed: */
+ return PK_OK; /* do nothing and signal OK */
+
++ /* Return no/bad-data error status if any problem is found:
++ * 1. eb_size is too small to hold the uncompressed size
++ * (eb_ucsize). (Else extract eb_ucsize.)
++ * 2. eb_ucsize is zero (invalid). 2014-12-04 SMS.
++ * 3. eb_ucsize is positive, but eb_size is too small to hold
++ * the compressed data header.
++ */
+ if ((eb_size < (EB_UCSIZE_P + 4)) ||
+- ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
+- eb_size <= (compr_offset + EB_CMPRHEADLEN)))
+- return IZ_EF_TRUNC; /* no compressed data! */
++ ((eb_ucsize = makelong( eb+ (EB_HEADSIZE+ EB_UCSIZE_P))) == 0L) ||
++ ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
++ return IZ_EF_TRUNC; /* no/bad compressed data! */
+
+ if (
+ #ifdef INT_16BIT
diff --git a/package/unzip/0011-cve-2014-8141-getzip64data.patch b/package/unzip/0011-cve-2014-8141-getzip64data.patch
new file mode 100644
index 0000000000..6e1835bda2
--- /dev/null
+++ b/package/unzip/0011-cve-2014-8141-getzip64data.patch
@@ -0,0 +1,140 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Fix CVE-2014-8141: out-of-bounds read issues in getZip64Data()
+Bug-Debian: https://bugs.debian.org/773722
+CVE: CVE-2014-8141
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/11-cve-2014-8141-getzip64data.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/fileio.c
++++ b/fileio.c
+@@ -176,6 +176,8 @@
+ #endif
+ static ZCONST char Far ExtraFieldTooLong[] =
+ "warning: extra field too long (%d). Ignoring...\n";
++static ZCONST char Far ExtraFieldCorrupt[] =
++ "warning: extra field (type: 0x%04x) corrupt. Continuing...\n";
+
+ #ifdef WINDLL
+ static ZCONST char Far DiskFullQuery[] =
+@@ -2295,7 +2297,12 @@
+ if (readbuf(__G__ (char *)G.extra_field, length) == 0)
+ return PK_EOF;
+ /* Looks like here is where extra fields are read */
+- getZip64Data(__G__ G.extra_field, length);
++ if (getZip64Data(__G__ G.extra_field, length) != PK_COOL)
++ {
++ Info(slide, 0x401, ((char *)slide,
++ LoadFarString( ExtraFieldCorrupt), EF_PKSZ64));
++ error = PK_WARN;
++ }
+ #ifdef UNICODE_SUPPORT
+ G.unipath_filename = NULL;
+ if (G.UzO.U_flag < 2) {
+--- a/process.c
++++ b/process.c
+@@ -1,5 +1,5 @@
+ /*
+- Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
++ Copyright (c) 1990-2014 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2009-Jan-02 or later
+ (the contents of which are also included in unzip.h) for terms of use.
+@@ -1901,48 +1901,82 @@
+ and a 4-byte version of disk start number.
+ Sets both local header and central header fields. Not terribly clever,
+ but it means that this procedure is only called in one place.
++
++ 2014-12-05 SMS.
++ Added checks to ensure that enough data are available before calling
++ makeint64() or makelong(). Replaced various sizeof() values with
++ simple ("4" or "8") constants. (The Zip64 structures do not depend
++ on our variable sizes.) Error handling is crude, but we should now
++ stay within the buffer.
+ ---------------------------------------------------------------------------*/
+
++#define Z64FLGS 0xffff
++#define Z64FLGL 0xffffffff
++
+ if (ef_len == 0 || ef_buf == NULL)
+ return PK_COOL;
+
+ Trace((stderr,"\ngetZip64Data: scanning extra field of length %u\n",
+ ef_len));
+
+- while (ef_len >= EB_HEADSIZE) {
++ while (ef_len >= EB_HEADSIZE)
++ {
+ eb_id = makeword(EB_ID + ef_buf);
+ eb_len = makeword(EB_LEN + ef_buf);
+
+- if (eb_len > (ef_len - EB_HEADSIZE)) {
+- /* discovered some extra field inconsistency! */
++ if (eb_len > (ef_len - EB_HEADSIZE))
++ {
++ /* Extra block length exceeds remaining extra field length. */
+ Trace((stderr,
+ "getZip64Data: block length %u > rest ef_size %u\n", eb_len,
+ ef_len - EB_HEADSIZE));
+ break;
+ }
+- if (eb_id == EF_PKSZ64) {
+-
++ if (eb_id == EF_PKSZ64)
++ {
+ int offset = EB_HEADSIZE;
+
+- if (G.crec.ucsize == 0xffffffff || G.lrec.ucsize == 0xffffffff){
+- G.lrec.ucsize = G.crec.ucsize = makeint64(offset + ef_buf);
+- offset += sizeof(G.crec.ucsize);
++ if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
++ {
++ if (offset+ 8 > ef_len)
++ return PK_ERR;
++
++ G.crec.ucsize = G.lrec.ucsize = makeint64(offset + ef_buf);
++ offset += 8;
+ }
+- if (G.crec.csize == 0xffffffff || G.lrec.csize == 0xffffffff){
+- G.csize = G.lrec.csize = G.crec.csize = makeint64(offset + ef_buf);
+- offset += sizeof(G.crec.csize);
++
++ if ((G.crec.csize == Z64FLGL) || (G.lrec.csize == Z64FLGL))
++ {
++ if (offset+ 8 > ef_len)
++ return PK_ERR;
++
++ G.csize = G.crec.csize = G.lrec.csize = makeint64(offset + ef_buf);
++ offset += 8;
+ }
+- if (G.crec.relative_offset_local_header == 0xffffffff){
++
++ if (G.crec.relative_offset_local_header == Z64FLGL)
++ {
++ if (offset+ 8 > ef_len)
++ return PK_ERR;
++
+ G.crec.relative_offset_local_header = makeint64(offset + ef_buf);
+- offset += sizeof(G.crec.relative_offset_local_header);
++ offset += 8;
+ }
+- if (G.crec.disk_number_start == 0xffff){
++
++ if (G.crec.disk_number_start == Z64FLGS)
++ {
++ if (offset+ 4 > ef_len)
++ return PK_ERR;
++
+ G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf);
+- offset += sizeof(G.crec.disk_number_start);
++ offset += 4;
+ }
++#if 0
++ break; /* Expect only one EF_PKSZ64 block. */
++#endif /* 0 */
+ }
+
+- /* Skip this extra field block */
++ /* Skip this extra field block. */
+ ef_buf += (eb_len + EB_HEADSIZE);
+ ef_len -= (eb_len + EB_HEADSIZE);
+ }
diff --git a/package/unzip/0012-cve-2014-9636-test-compr-eb.patch b/package/unzip/0012-cve-2014-9636-test-compr-eb.patch
new file mode 100644
index 0000000000..a68a249e2b
--- /dev/null
+++ b/package/unzip/0012-cve-2014-9636-test-compr-eb.patch
@@ -0,0 +1,44 @@
+From: mancha <mancha1 AT zoho DOT com>
+Date: Wed, 11 Feb 2015
+Subject: Info-ZIP UnZip buffer overflow
+Bug-Debian: https://bugs.debian.org/776589
+
+By carefully crafting a corrupt ZIP archive with "extra fields" that
+purport to have compressed blocks larger than the corresponding
+uncompressed blocks in STORED no-compression mode, an attacker can
+trigger a heap overflow that can result in application crash or
+possibly have other unspecified impact.
+
+This patch ensures that when extra fields use STORED mode, the
+"compressed" and uncompressed block sizes match.
+
+CVE: CVE-2014-9636
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/12-cve-2014-9636-test-compr-eb.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/extract.c
++++ b/extract.c
+@@ -2228,6 +2228,7 @@
+ ulg eb_ucsize;
+ uch *eb_ucptr;
+ int r;
++ ush eb_compr_method;
+
+ if (compr_offset < 4) /* field is not compressed: */
+ return PK_OK; /* do nothing and signal OK */
+@@ -2244,6 +2245,15 @@
+ ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
+ return IZ_EF_TRUNC; /* no/bad compressed data! */
+
++ /* 2015-02-10 Mancha(?), Michal Zalewski, Tomas Hoger, SMS.
++ * For STORE method, compressed and uncompressed sizes must agree.
++ * http://www.info-zip.org/phpBB3/viewtopic.php?f=7&t=450
++ */
++ eb_compr_method = makeword( eb + (EB_HEADSIZE + compr_offset));
++ if ((eb_compr_method == STORED) &&
++ (eb_size != compr_offset + EB_CMPRHEADLEN + eb_ucsize))
++ return PK_ERR;
++
+ if (
+ #ifdef INT_16BIT
+ (((ulg)(extent)eb_ucsize) != eb_ucsize) ||
diff --git a/package/unzip/0013-remove-build-date.patch b/package/unzip/0013-remove-build-date.patch
new file mode 100644
index 0000000000..48353aa8d4
--- /dev/null
+++ b/package/unzip/0013-remove-build-date.patch
@@ -0,0 +1,20 @@
+From: Jérémy Bobbio <lunar@debian.org>
+Subject: Remove build date
+Bug-Debian: https://bugs.debian.org/782851
+ In order to make unzip build reproducibly, we remove the
+ (already optional) build date from the binary.
+
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/13-remove-build-date.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+--- a/unix/unix.c
++++ b/unix/unix.c
+@@ -1705,7 +1705,7 @@
+ #endif /* Sun */
+ #endif /* SGI */
+
+-#ifdef __DATE__
++#if 0
+ " on ", __DATE__
+ #else
+ "", ""
diff --git a/package/unzip/0014-cve-2015-7696.patch b/package/unzip/0014-cve-2015-7696.patch
new file mode 100644
index 0000000000..b64b2b829a
--- /dev/null
+++ b/package/unzip/0014-cve-2015-7696.patch
@@ -0,0 +1,35 @@
+From: Petr Stodulka <pstodulk@redhat.com>
+Date: Mon, 14 Sep 2015 18:23:17 +0200
+Subject: Upstream fix for heap overflow
+Bug-Debian: https://bugs.debian.org/802162
+Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1260944
+Origin: https://bugzilla.redhat.com/attachment.cgi?id=1073002
+Forwarded: yes
+CVE: CVE-2015-7696
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/14-cve-2015-7696.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+ crypt.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/crypt.c
++++ b/crypt.c
+@@ -465,7 +465,17 @@
+ GLOBAL(pInfo->encrypted) = FALSE;
+ defer_leftover_input(__G);
+ for (n = 0; n < RAND_HEAD_LEN; n++) {
+- b = NEXTBYTE;
++ /* 2012-11-23 SMS. (OUSPG report.)
++ * Quit early if compressed size < HEAD_LEN. The resulting
++ * error message ("unable to get password") could be improved,
++ * but it's better than trying to read nonexistent data, and
++ * then continuing with a negative G.csize. (See
++ * fileio.c:readbyte()).
++ */
++ if ((b = NEXTBYTE) == (ush)EOF)
++ {
++ return PK_ERR;
++ }
+ h[n] = (uch)b;
+ Trace((stdout, " (%02x)", h[n]));
+ }
diff --git a/package/unzip/0015-cve-2015-7697.patch b/package/unzip/0015-cve-2015-7697.patch
new file mode 100644
index 0000000000..e60b40cdeb
--- /dev/null
+++ b/package/unzip/0015-cve-2015-7697.patch
@@ -0,0 +1,29 @@
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Mon, 14 Sep 2015 18:24:56 +0200
+Subject: fix infinite loop when extracting empty bzip2 data
+Bug-Debian: https://bugs.debian.org/802160
+Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1260944
+Origin: other, https://bugzilla.redhat.com/attachment.cgi?id=1073339
+
+CVE: CVE-2015-7697
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/15-cve-2015-7697.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+ extract.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/extract.c
++++ b/extract.c
+@@ -2729,6 +2729,12 @@
+ int repeated_buf_err;
+ bz_stream bstrm;
+
++ if (G.incnt <= 0 && G.csize <= 0L) {
++ /* avoid an infinite loop */
++ Trace((stderr, "UZbunzip2() got empty input\n"));
++ return 2;
++ }
++
+ #if (defined(DLL) && !defined(NO_SLIDE_REDIR))
+ if (G.redirect_slide)
+ wsize = G.redirect_size, redirSlide = G.redirect_buffer;
diff --git a/package/unzip/0016-fix-integer-underflow-csiz-decrypted.patch b/package/unzip/0016-fix-integer-underflow-csiz-decrypted.patch
new file mode 100644
index 0000000000..bc01506c50
--- /dev/null
+++ b/package/unzip/0016-fix-integer-underflow-csiz-decrypted.patch
@@ -0,0 +1,34 @@
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Tue, 22 Sep 2015 18:52:23 +0200
+Subject: [PATCH] extract: prevent unsigned overflow on invalid input
+Origin: other, https://bugzilla.redhat.com/attachment.cgi?id=1075942
+Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1260944
+
+Suggested-by: Stefan Cornelius
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/16-fix-integer-underflow-csiz-decrypted.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+ extract.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/extract.c
++++ b/extract.c
+@@ -1257,8 +1257,17 @@
+ if (G.lrec.compression_method == STORED) {
+ zusz_t csiz_decrypted = G.lrec.csize;
+
+- if (G.pInfo->encrypted)
++ if (G.pInfo->encrypted) {
++ if (csiz_decrypted < 12) {
++ /* handle the error now to prevent unsigned overflow */
++ Info(slide, 0x401, ((char *)slide,
++ LoadFarStringSmall(ErrUnzipNoFile),
++ LoadFarString(InvalidComprData),
++ LoadFarStringSmall2(Inflate)));
++ return PK_ERR;
++ }
+ csiz_decrypted -= 12;
++ }
+ if (G.lrec.ucsize != csiz_decrypted) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall2(WrnStorUCSizCSizDiff),
diff --git a/package/unzip/0017-restore-unix-timestamps-accurately.patch b/package/unzip/0017-restore-unix-timestamps-accurately.patch
new file mode 100644
index 0000000000..484fa2df9c
--- /dev/null
+++ b/package/unzip/0017-restore-unix-timestamps-accurately.patch
@@ -0,0 +1,43 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Do not ignore extra fields containing Unix Timestamps
+Bug-Debian: https://bugs.debian.org/842993
+X-Debian-version: 6.0-21
+
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/17-restore-unix-timestamps-accurately.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/process.c
++++ b/process.c
+@@ -2914,10 +2914,13 @@
+ break;
+
+ case EF_IZUNIX2:
+- if (have_new_type_eb == 0) {
+- flags &= ~0x0ff; /* ignore any previous IZUNIX field */
++ if (have_new_type_eb == 0) { /* (< 1) */
+ have_new_type_eb = 1;
+ }
++ if (have_new_type_eb <= 1) {
++ /* Ignore any prior (EF_IZUNIX/EF_PKUNIX) UID/GID. */
++ flags &= 0x0ff;
++ }
+ #ifdef IZ_HAVE_UXUIDGID
+ if (have_new_type_eb > 1)
+ break; /* IZUNIX3 overrides IZUNIX2 e.f. block ! */
+@@ -2933,6 +2936,8 @@
+ /* new 3rd generation Unix ef */
+ have_new_type_eb = 2;
+
++ /* Ignore any prior EF_IZUNIX/EF_PKUNIX/EF_IZUNIX2 UID/GID. */
++ flags &= 0x0ff;
+ /*
+ Version 1 byte version of this extra field, currently 1
+ UIDSize 1 byte Size of UID field
+@@ -2953,8 +2958,6 @@
+ uid_size = *((EB_HEADSIZE + 1) + ef_buf);
+ gid_size = *((EB_HEADSIZE + uid_size + 2) + ef_buf);
+
+- flags &= ~0x0ff; /* ignore any previous UNIX field */
+-
+ if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
+ uid_size, &z_uidgid[0])
+ &&
diff --git a/package/unzip/0018-cve-2014-9913-unzip-buffer-overflow.patch b/package/unzip/0018-cve-2014-9913-unzip-buffer-overflow.patch
new file mode 100644
index 0000000000..5be35bc084
--- /dev/null
+++ b/package/unzip/0018-cve-2014-9913-unzip-buffer-overflow.patch
@@ -0,0 +1,32 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Fix CVE-2014-9913, buffer overflow in unzip
+Bug: https://sourceforge.net/p/infozip/bugs/27/
+Bug-Debian: https://bugs.debian.org/847485
+Bug-Ubuntu: https://launchpad.net/bugs/387350
+X-Debian-version: 6.0-21
+
+CVE: CVE-2014-9913
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/18-cve-2014-9913-unzip-buffer-overflow.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/list.c
++++ b/list.c
+@@ -339,7 +339,18 @@
+ G.crec.compression_method == ENHDEFLATED) {
+ methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3];
+ } else if (methnum >= NUM_METHODS) {
+- sprintf(&methbuf[4], "%03u", G.crec.compression_method);
++ /* 2013-02-26 SMS.
++ * http://sourceforge.net/p/infozip/bugs/27/ CVE-2014-9913.
++ * Unexpectedly large compression methods overflow
++ * &methbuf[]. Use the old, three-digit decimal format
++ * for values which fit. Otherwise, sacrifice the
++ * colon, and use four-digit hexadecimal.
++ */
++ if (G.crec.compression_method <= 999) {
++ sprintf( &methbuf[ 4], "%03u", G.crec.compression_method);
++ } else {
++ sprintf( &methbuf[ 3], "%04X", G.crec.compression_method);
++ }
+ }
+
+ #if 0 /* GRR/Euro: add this? */
diff --git a/package/unzip/0019-cve-2016-9844-zipinfo-buffer-overflow.patch b/package/unzip/0019-cve-2016-9844-zipinfo-buffer-overflow.patch
new file mode 100644
index 0000000000..9760e6a3bb
--- /dev/null
+++ b/package/unzip/0019-cve-2016-9844-zipinfo-buffer-overflow.patch
@@ -0,0 +1,31 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Fix CVE-2016-9844, buffer overflow in zipinfo
+Bug-Debian: https://bugs.debian.org/847486
+Bug-Ubuntu: https://launchpad.net/bugs/1643750
+X-Debian-version: 6.0-21
+
+CVE: CVE-2016-9844
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/19-cve-2016-9844-zipinfo-buffer-overflow.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/zipinfo.c
++++ b/zipinfo.c
+@@ -1921,7 +1921,18 @@
+ ush dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
+ methbuf[3] = dtype[dnum];
+ } else if (methnum >= NUM_METHODS) { /* unknown */
+- sprintf(&methbuf[1], "%03u", G.crec.compression_method);
++ /* 2016-12-05 SMS.
++ * https://launchpad.net/bugs/1643750
++ * Unexpectedly large compression methods overflow
++ * &methbuf[]. Use the old, three-digit decimal format
++ * for values which fit. Otherwise, sacrifice the "u",
++ * and use four-digit hexadecimal.
++ */
++ if (G.crec.compression_method <= 999) {
++ sprintf( &methbuf[ 1], "%03u", G.crec.compression_method);
++ } else {
++ sprintf( &methbuf[ 0], "%04X", G.crec.compression_method);
++ }
+ }
+
+ for (k = 0; k < 15; ++k)
diff --git a/package/unzip/0020-cve-2018-1000035-unzip-buffer-overflow.patch b/package/unzip/0020-cve-2018-1000035-unzip-buffer-overflow.patch
new file mode 100644
index 0000000000..e105ae86df
--- /dev/null
+++ b/package/unzip/0020-cve-2018-1000035-unzip-buffer-overflow.patch
@@ -0,0 +1,39 @@
+From: Karol Babioch <kbabioch@suse.com>
+Subject: Fix buffer overflow in password protected zip archives
+Bug-Debian: https://bugs.debian.org/889838
+Origin: https://bugzilla.novell.com/attachment.cgi?id=759406
+X-Debian-version: 6.0-22
+
+CVE: CVE-2018-1000035
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/20-cve-2018-1000035-unzip-buffer-overflow.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/fileio.c
++++ b/fileio.c
+@@ -1582,6 +1582,10 @@
+ int r = IZ_PW_ENTERED;
+ char *m;
+ char *prompt;
++ char *zfnf;
++ char *efnf;
++ size_t zfnfl;
++ int isOverflow;
+
+ #ifndef REENTRANT
+ /* tell picky compilers to shut up about "unused variable" warnings */
+@@ -1590,7 +1594,15 @@
+
+ if (*rcnt == 0) { /* First call for current entry */
+ *rcnt = 2;
+- if ((prompt = (char *)malloc(2*FILNAMSIZ + 15)) != (char *)NULL) {
++ zfnf = FnFilter1(zfn);
++ efnf = FnFilter2(efn);
++ zfnfl = strlen(zfnf);
++ isOverflow = TRUE;
++ if (2*FILNAMSIZ >= zfnfl && (2*FILNAMSIZ - zfnfl) >= strlen(efnf))
++ {
++ isOverflow = FALSE;
++ }
++ if ((isOverflow == FALSE) && ((prompt = (char *)malloc(2*FILNAMSIZ + 15)) != (char *)NULL)) {
+ sprintf(prompt, LoadFarString(PasswPrompt),
+ FnFilter1(zfn), FnFilter2(efn));
+ m = prompt;
diff --git a/package/unzip/0021-fix-warning-messages-on-big-files.patch b/package/unzip/0021-fix-warning-messages-on-big-files.patch
new file mode 100644
index 0000000000..fd9cb49f9c
--- /dev/null
+++ b/package/unzip/0021-fix-warning-messages-on-big-files.patch
@@ -0,0 +1,16 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Fix lame code in fileio.c
+Bug-Debian: https://bugs.debian.org/929502
+X-Debian-version: 6.0-23
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/21-fix-warning-messages-on-big-files.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/fileio.c
++++ b/fileio.c
+@@ -2477,6 +2477,7 @@
+ */
+ return (((zusz_t)sig[7]) << 56)
+ + (((zusz_t)sig[6]) << 48)
++ + (((zusz_t)sig[5]) << 40)
+ + (((zusz_t)sig[4]) << 32)
+ + (zusz_t)((((ulg)sig[3]) << 24)
+ + (((ulg)sig[2]) << 16)
diff --git a/package/unzip/0022-cve-2019-13232-fix-bug-in-undefer-input.patch b/package/unzip/0022-cve-2019-13232-fix-bug-in-undefer-input.patch
new file mode 100644
index 0000000000..529ddf9aa9
--- /dev/null
+++ b/package/unzip/0022-cve-2019-13232-fix-bug-in-undefer-input.patch
@@ -0,0 +1,25 @@
+From: Mark Adler <madler@alumni.caltech.edu>
+Subject: Fix bug in undefer_input() that misplaced the input state.
+Origin: https://github.com/madler/unzip/commit/41beb477c5744bc396fa1162ee0c14218ec12213
+Bug-Debian: https://bugs.debian.org/931433
+X-Debian-version: 6.0-24
+
+ Fix bug in undefer_input() that misplaced the input state.
+
+CVE: CVE-2019-13232
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/22-cve-2019-13232-fix-bug-in-undefer-input.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/fileio.c
++++ b/fileio.c
+@@ -532,8 +532,10 @@
+ * This condition was checked when G.incnt_leftover was set > 0 in
+ * defer_leftover_input(), and it is NOT allowed to touch G.csize
+ * before calling undefer_input() when (G.incnt_leftover > 0)
+- * (single exception: see read_byte()'s "G.csize <= 0" handling) !!
++ * (single exception: see readbyte()'s "G.csize <= 0" handling) !!
+ */
++ if (G.csize < 0L)
++ G.csize = 0L;
+ G.incnt = G.incnt_leftover + (int)G.csize;
+ G.inptr = G.inptr_leftover - (int)G.csize;
+ G.incnt_leftover = 0;
diff --git a/package/unzip/0023-cve-2019-13232-zip-bomb-with-overlapped-entries.patch b/package/unzip/0023-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
new file mode 100644
index 0000000000..60b218262a
--- /dev/null
+++ b/package/unzip/0023-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
@@ -0,0 +1,338 @@
+From: Mark Adler <madler@alumni.caltech.edu>
+Subject: Detect and reject a zip bomb using overlapped entries.
+Origin: https://github.com/madler/unzip/commit/47b3ceae397d21bf822bc2ac73052a4b1daf8e1c
+Bug-Debian: https://bugs.debian.org/931433
+X-Debian-version: 6.0-24
+
+ Detect and reject a zip bomb using overlapped entries.
+
+ This detects an invalid zip file that has at least one entry that
+ overlaps with another entry or with the central directory to the
+ end of the file. A Fifield zip bomb uses overlapped local entries
+ to vastly increase the potential inflation ratio. Such an invalid
+ zip file is rejected.
+
+ See https://www.bamsoftware.com/hacks/zipbomb/ for David Fifield's
+ analysis, construction, and examples of such zip bombs.
+
+ The detection maintains a list of covered spans of the zip files
+ so far, where the central directory to the end of the file and any
+ bytes preceding the first entry at zip file offset zero are
+ considered covered initially. Then as each entry is decompressed
+ or tested, it is considered covered. When a new entry is about to
+ be processed, its initial offset is checked to see if it is
+ contained by a covered span. If so, the zip file is rejected as
+ invalid.
+
+ This commit depends on a preceding commit: "Fix bug in
+ undefer_input() that misplaced the input state."
+
+CVE: CVE-2019-13232
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/23-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/extract.c
++++ b/extract.c
+@@ -321,6 +321,125 @@
+ "\nerror: unsupported extra-field compression type (%u)--skipping\n";
+ static ZCONST char Far BadExtraFieldCRC[] =
+ "error [%s]: bad extra-field CRC %08lx (should be %08lx)\n";
++static ZCONST char Far NotEnoughMemCover[] =
++ "error: not enough memory for bomb detection\n";
++static ZCONST char Far OverlappedComponents[] =
++ "error: invalid zip file with overlapped components (possible zip bomb)\n";
++
++
++
++
++
++/* A growable list of spans. */
++typedef zoff_t bound_t;
++typedef struct {
++ bound_t beg; /* start of the span */
++ bound_t end; /* one past the end of the span */
++} span_t;
++typedef struct {
++ span_t *span; /* allocated, distinct, and sorted list of spans */
++ size_t num; /* number of spans in the list */
++ size_t max; /* allocated number of spans (num <= max) */
++} cover_t;
++
++/*
++ * Return the index of the first span in cover whose beg is greater than val.
++ * If there is no such span, then cover->num is returned.
++ */
++static size_t cover_find(cover, val)
++ cover_t *cover;
++ bound_t val;
++{
++ size_t lo = 0, hi = cover->num;
++ while (lo < hi) {
++ size_t mid = (lo + hi) >> 1;
++ if (val < cover->span[mid].beg)
++ hi = mid;
++ else
++ lo = mid + 1;
++ }
++ return hi;
++}
++
++/* Return true if val lies within any one of the spans in cover. */
++static int cover_within(cover, val)
++ cover_t *cover;
++ bound_t val;
++{
++ size_t pos = cover_find(cover, val);
++ return pos > 0 && val < cover->span[pos - 1].end;
++}
++
++/*
++ * Add a new span to the list, but only if the new span does not overlap any
++ * spans already in the list. The new span covers the values beg..end-1. beg
++ * must be less than end.
++ *
++ * Keep the list sorted and merge adjacent spans. Grow the allocated space for
++ * the list as needed. On success, 0 is returned. If the new span overlaps any
++ * existing spans, then 1 is returned and the new span is not added to the
++ * list. If the new span is invalid because beg is greater than or equal to
++ * end, then -1 is returned. If the list needs to be grown but the memory
++ * allocation fails, then -2 is returned.
++ */
++static int cover_add(cover, beg, end)
++ cover_t *cover;
++ bound_t beg;
++ bound_t end;
++{
++ size_t pos;
++ int prec, foll;
++
++ if (beg >= end)
++ /* The new span is invalid. */
++ return -1;
++
++ /* Find where the new span should go, and make sure that it does not
++ overlap with any existing spans. */
++ pos = cover_find(cover, beg);
++ if ((pos > 0 && beg < cover->span[pos - 1].end) ||
++ (pos < cover->num && end > cover->span[pos].beg))
++ return 1;
++
++ /* Check for adjacencies. */
++ prec = pos > 0 && beg == cover->span[pos - 1].end;
++ foll = pos < cover->num && end == cover->span[pos].beg;
++ if (prec && foll) {
++ /* The new span connects the preceding and following spans. Merge the
++ following span into the preceding span, and delete the following
++ span. */
++ cover->span[pos - 1].end = cover->span[pos].end;
++ cover->num--;
++ memmove(cover->span + pos, cover->span + pos + 1,
++ (cover->num - pos) * sizeof(span_t));
++ }
++ else if (prec)
++ /* The new span is adjacent only to the preceding span. Extend the end
++ of the preceding span. */
++ cover->span[pos - 1].end = end;
++ else if (foll)
++ /* The new span is adjacent only to the following span. Extend the
++ beginning of the following span. */
++ cover->span[pos].beg = beg;
++ else {
++ /* The new span has gaps between both the preceding and the following
++ spans. Assure that there is room and insert the span. */
++ if (cover->num == cover->max) {
++ size_t max = cover->max == 0 ? 16 : cover->max << 1;
++ span_t *span = realloc(cover->span, max * sizeof(span_t));
++ if (span == NULL)
++ return -2;
++ cover->span = span;
++ cover->max = max;
++ }
++ memmove(cover->span + pos + 1, cover->span + pos,
++ (cover->num - pos) * sizeof(span_t));
++ cover->num++;
++ cover->span[pos].beg = beg;
++ cover->span[pos].end = end;
++ }
++ return 0;
++}
+
+
+
+@@ -376,6 +495,29 @@
+ }
+ #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. */
++ if (G.cover == NULL) {
++ G.cover = malloc(sizeof(cover_t));
++ if (G.cover == NULL) {
++ Info(slide, 0x401, ((char *)slide,
++ LoadFarString(NotEnoughMemCover)));
++ return PK_MEM;
++ }
++ ((cover_t *)G.cover)->span = NULL;
++ ((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,
++ G.extra_bytes + G.ecrec.offset_start_central_directory,
++ G.ziplen) != 0) {
++ Info(slide, 0x401, ((char *)slide,
++ LoadFarString(NotEnoughMemCover)));
++ return PK_MEM;
++ }
++
+ /*---------------------------------------------------------------------------
+ The basic idea of this function is as follows. Since the central di-
+ rectory lies at the end of the zipfile and the member files lie at the
+@@ -593,7 +735,8 @@
+ if (error > error_in_archive)
+ error_in_archive = error;
+ /* ...and keep going (unless disk full or user break) */
+- if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
++ if (G.disk_full > 1 || error_in_archive == IZ_CTRLC ||
++ error == PK_BOMB) {
+ /* clear reached_end to signal premature stop ... */
+ reached_end = FALSE;
+ /* ... and cancel scanning the central directory */
+@@ -1062,6 +1205,11 @@
+
+ /* seek_zipf(__G__ pInfo->offset); */
+ request = G.pInfo->offset + G.extra_bytes;
++ if (cover_within((cover_t *)G.cover, request)) {
++ Info(slide, 0x401, ((char *)slide,
++ LoadFarString(OverlappedComponents)));
++ return PK_BOMB;
++ }
+ inbuf_offset = request % INBUFSIZ;
+ bufstart = request - inbuf_offset;
+
+@@ -1602,6 +1750,18 @@
+ return IZ_CTRLC; /* cancel operation by user request */
+ }
+ #endif
++ error = cover_add((cover_t *)G.cover, request,
++ G.cur_zipfile_bufstart + (G.inptr - G.inbuf));
++ if (error < 0) {
++ Info(slide, 0x401, ((char *)slide,
++ LoadFarString(NotEnoughMemCover)));
++ return PK_MEM;
++ }
++ if (error != 0) {
++ Info(slide, 0x401, ((char *)slide,
++ LoadFarString(OverlappedComponents)));
++ return PK_BOMB;
++ }
+ #ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
+ UserStop();
+ #endif
+@@ -2003,6 +2163,34 @@
+ }
+
+ undefer_input(__G);
++
++ if ((G.lrec.general_purpose_bit_flag & 8) != 0) {
++ /* skip over data descriptor (harder than it sounds, due to signature
++ * ambiguity)
++ */
++# define SIG 0x08074b50
++# define LOW 0xffffffff
++ uch buf[12];
++ unsigned shy = 12 - readbuf((char *)buf, 12);
++ ulg crc = shy ? 0 : makelong(buf);
++ ulg clen = shy ? 0 : makelong(buf + 4);
++ ulg ulen = shy ? 0 : makelong(buf + 8); /* or high clen if ZIP64 */
++ if (crc == SIG && /* if not SIG, no signature */
++ (G.lrec.crc32 != SIG || /* if not SIG, have signature */
++ (clen == SIG && /* if not SIG, no signature */
++ ((G.lrec.csize & LOW) != SIG || /* if not SIG, have signature */
++ (ulen == SIG && /* if not SIG, no signature */
++ (G.zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG
++ /* if not SIG, have signature */
++ )))))
++ /* skip four more bytes to account for signature */
++ shy += 4 - readbuf((char *)buf, 4);
++ if (G.zip64)
++ shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */
++ if (shy)
++ error = PK_ERR;
++ }
++
+ return error;
+
+ } /* end function extract_or_test_member() */
+--- a/globals.c
++++ b/globals.c
+@@ -181,6 +181,7 @@
+ # if (!defined(NO_TIMESTAMPS))
+ uO.D_flag=1; /* default to '-D', no restoration of dir timestamps */
+ # endif
++ G.cover = NULL; /* not allocated yet */
+ #endif
+
+ uO.lflag=(-1);
+--- a/globals.h
++++ b/globals.h
+@@ -260,12 +260,15 @@
+ ecdir_rec ecrec; /* used in unzip.c, extract.c */
+ z_stat statbuf; /* used by main, mapname, check_for_newer */
+
++ int zip64; /* true if Zip64 info in extra field */
++
+ int mem_mode;
+ uch *outbufptr; /* extract.c static */
+ ulg outsize; /* extract.c static */
+ int reported_backslash; /* extract.c static */
+ int disk_full;
+ int newfile;
++ void **cover; /* used in extract.c for bomb detection */
+
+ int didCRlast; /* fileio static */
+ ulg numlines; /* fileio static: number of lines printed */
+--- a/process.c
++++ b/process.c
+@@ -637,6 +637,13 @@
+ }
+ #endif
+
++ /* Free the cover span list and the cover structure. */
++ if (G.cover != NULL) {
++ free(*(G.cover));
++ free(G.cover);
++ G.cover = NULL;
++ }
++
+ } /* end function free_G_buffers() */
+
+
+@@ -1913,6 +1920,8 @@
+ #define Z64FLGS 0xffff
+ #define Z64FLGL 0xffffffff
+
++ G.zip64 = FALSE;
++
+ if (ef_len == 0 || ef_buf == NULL)
+ return PK_COOL;
+
+@@ -2084,6 +2093,8 @@
+ (ZCONST char *)(offset + ef_buf), ULen);
+ G.unipath_filename[ULen] = '\0';
+ }
++
++ G.zip64 = TRUE;
+ }
+
+ /* Skip this extra field block */
+--- a/unzip.h
++++ b/unzip.h
+@@ -645,6 +645,7 @@
+ #define PK_NOZIP 9 /* zipfile not found */
+ #define PK_PARAM 10 /* bad or illegal parameters specified */
+ #define PK_FIND 11 /* no files found */
++#define PK_BOMB 12 /* likely zip bomb */
+ #define PK_DISK 50 /* disk full */
+ #define PK_EOF 51 /* unexpected EOF */
+
diff --git a/package/unzip/0024-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch b/package/unzip/0024-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
new file mode 100644
index 0000000000..7b2092f1c5
--- /dev/null
+++ b/package/unzip/0024-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
@@ -0,0 +1,106 @@
+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.
+
+CVE: CVE-2019-13232
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/24-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- 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;
+
+
diff --git a/package/unzip/0025-cve-2019-13232-fix-bug-in-uzbunzip2.patch b/package/unzip/0025-cve-2019-13232-fix-bug-in-uzbunzip2.patch
new file mode 100644
index 0000000000..c743faa342
--- /dev/null
+++ b/package/unzip/0025-cve-2019-13232-fix-bug-in-uzbunzip2.patch
@@ -0,0 +1,26 @@
+From: Mark Adler <madler@alumni.caltech.edu>
+Subject: Fix bug in UZbunzip2() that incorrectly updated G.incnt
+Origin: https://github.com/madler/unzip/commit/5e2efcd633a4a1fb95a129a75508e7d769e767be
+Bug-Debian: https://bugs.debian.org/963996
+X-Debian-version: 6.0-26
+
+ Fix bug in UZbunzip2() that incorrectly updated G.incnt.
+
+ The update assumed a full buffer, which is not always full. This
+ could result in a false overlapped element detection when a small
+ bzip2-compressed file was unzipped. This commit remedies that.
+
+CVE: CVE-2019-13232
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/25-cve-2019-13232-fix-bug-in-uzbunzip2.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/extract.c
++++ b/extract.c
+@@ -3052,7 +3052,7 @@
+ #endif
+
+ G.inptr = (uch *)bstrm.next_in;
+- G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */
++ G.incnt -= G.inptr - G.inbuf; /* reset for other routines */
+
+ uzbunzip_cleanup_exit:
+ err = BZ2_bzDecompressEnd(&bstrm);
diff --git a/package/unzip/0026-cve-2019-13232-fix-bug-in-uzinflate.patch b/package/unzip/0026-cve-2019-13232-fix-bug-in-uzinflate.patch
new file mode 100644
index 0000000000..822e800a6e
--- /dev/null
+++ b/package/unzip/0026-cve-2019-13232-fix-bug-in-uzinflate.patch
@@ -0,0 +1,26 @@
+From: Mark Adler <madler@alumni.caltech.edu>
+Subject: Fix bug in UZinflate() that incorrectly updated G.incnt.
+Origin: https://github.com/madler/unzip/commit/5c572555cf5d80309a07c30cf7a54b2501493720
+X-Debian-version: 6.0-26
+
+ Fix bug in UZinflate() that incorrectly updated G.incnt.
+
+ The update assumed a full buffer, which is not always full. This
+ could result in a false overlapped element detection when a small
+ deflate-compressed file was unzipped using an old zlib. This
+ commit remedies that.
+
+CVE: CVE-2019-13232
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/26-cve-2019-13232-fix-bug-in-uzinflate.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/inflate.c
++++ b/inflate.c
+@@ -700,7 +700,7 @@
+ G.dstrm.total_out));
+
+ G.inptr = (uch *)G.dstrm.next_in;
+- G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */
++ G.incnt -= G.inptr - G.inbuf; /* reset for other routines */
+
+ uzinflate_cleanup_exit:
+ err = inflateReset(&G.dstrm);
diff --git a/package/unzip/0027-zipgrep-avoid-test-errors.patch b/package/unzip/0027-zipgrep-avoid-test-errors.patch
new file mode 100644
index 0000000000..ac53dcd016
--- /dev/null
+++ b/package/unzip/0027-zipgrep-avoid-test-errors.patch
@@ -0,0 +1,17 @@
+From: Kevin Locke <kevin@kevinlocke.name>
+Subject: zipgrep: Avoid test errors when no members present
+Bug-Debian: https://bugs.debian.org/972233
+X-Debian-version: 6.0-26
+
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/27-zipgrep-avoid-test-errors.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/unix/zipgrep
++++ b/unix/zipgrep
+@@ -44,6 +44,7 @@
+ opt="-$opt"
+ fi
+
++sts=0
+ status_grep_global=1
+ IFS='
+ '
diff --git a/package/unzip/0028-cve-2022-0529-and-cve-2022-0530.patch b/package/unzip/0028-cve-2022-0529-and-cve-2022-0530.patch
new file mode 100644
index 0000000000..2a36b65b3c
--- /dev/null
+++ b/package/unzip/0028-cve-2022-0529-and-cve-2022-0530.patch
@@ -0,0 +1,177 @@
+From: Steven M. Schweda <sms@antinode.info>
+Subject: Fix for CVE-2022-0529 and CVE-2022-0530
+Bug-Debian: https://bugs.debian.org/1010355
+X-Debian-version: 6.0-27
+
+CVE: CVE-2022-0529
+CVE: CVE-2022-0530
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/28-cve-2022-0529-and-cve-2022-0530.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/fileio.c
++++ b/fileio.c
+@@ -171,8 +171,10 @@
+ static ZCONST char Far FilenameTooLongTrunc[] =
+ "warning: filename too long--truncating.\n";
+ #ifdef UNICODE_SUPPORT
++ static ZCONST char Far UFilenameCorrupt[] =
++ "error: Unicode filename corrupt.\n";
+ static ZCONST char Far UFilenameTooLongTrunc[] =
+- "warning: Converted unicode filename too long--truncating.\n";
++ "warning: Converted Unicode filename too long--truncating.\n";
+ #endif
+ static ZCONST char Far ExtraFieldTooLong[] =
+ "warning: extra field too long (%d). Ignoring...\n";
+@@ -2361,16 +2363,30 @@
+ /* convert UTF-8 to local character set */
+ fn = utf8_to_local_string(G.unipath_filename,
+ G.unicode_escape_all);
+- /* make sure filename is short enough */
+- if (strlen(fn) >= FILNAMSIZ) {
+- fn[FILNAMSIZ - 1] = '\0';
++
++ /* 2022-07-22 SMS, et al. CVE-2022-0530
++ * Detect conversion failure, emit message.
++ * Continue with unconverted name.
++ */
++ if (fn == NULL)
++ {
+ Info(slide, 0x401, ((char *)slide,
+- LoadFarString(UFilenameTooLongTrunc)));
+- error = PK_WARN;
++ LoadFarString(UFilenameCorrupt)));
++ error = PK_ERR;
++ }
++ else
++ {
++ /* make sure filename is short enough */
++ if (strlen(fn) >= FILNAMSIZ) {
++ fn[FILNAMSIZ - 1] = '\0';
++ Info(slide, 0x401, ((char *)slide,
++ LoadFarString(UFilenameTooLongTrunc)));
++ error = PK_WARN;
++ }
++ /* replace filename with converted UTF-8 */
++ strcpy(G.filename, fn);
++ free(fn);
+ }
+- /* replace filename with converted UTF-8 */
+- strcpy(G.filename, fn);
+- free(fn);
+ }
+ # endif /* UNICODE_WCHAR */
+ if (G.unipath_filename != G.filename_full)
+--- a/process.c
++++ b/process.c
+@@ -222,6 +222,8 @@
+ "\nwarning: Unicode Path version > 1\n";
+ static ZCONST char Far UnicodeMismatchError[] =
+ "\nwarning: Unicode Path checksum invalid\n";
++ static ZCONST char Far UFilenameTooLongTrunc[] =
++ "warning: filename too long (P1) -- truncating.\n";
+ #endif
+
+
+@@ -1915,7 +1917,7 @@
+ Sets both local header and central header fields. Not terribly clever,
+ but it means that this procedure is only called in one place.
+
+- 2014-12-05 SMS.
++ 2014-12-05 SMS. (oCERT.org report.) CVE-2014-8141.
+ Added checks to ensure that enough data are available before calling
+ makeint64() or makelong(). Replaced various sizeof() values with
+ simple ("4" or "8") constants. (The Zip64 structures do not depend
+@@ -1947,9 +1949,10 @@
+ ef_len - EB_HEADSIZE));
+ break;
+ }
++
+ if (eb_id == EF_PKSZ64)
+ {
+- int offset = EB_HEADSIZE;
++ unsigned offset = EB_HEADSIZE;
+
+ if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
+ {
+@@ -2046,7 +2049,7 @@
+ }
+ if (eb_id == EF_UNIPATH) {
+
+- int offset = EB_HEADSIZE;
++ unsigned offset = EB_HEADSIZE;
+ ush ULen = eb_len - 5;
+ ulg chksum = CRCVAL_INITIAL;
+
+@@ -2504,16 +2507,17 @@
+ int state_dependent;
+ int wsize = 0;
+ int max_bytes = MB_CUR_MAX;
+- char buf[9];
++ char buf[ MB_CUR_MAX+ 1]; /* ("+1" not really needed?) */
+ char *buffer = NULL;
+ char *local_string = NULL;
++ size_t buffer_size; /* CVE-2022-0529 */
+
+ for (wsize = 0; wide_string[wsize]; wsize++) ;
+
+ if (max_bytes < MAX_ESCAPE_BYTES)
+ max_bytes = MAX_ESCAPE_BYTES;
+-
+- if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) {
++ buffer_size = wsize * max_bytes + 1; /* Reused below. */
++ if ((buffer = (char *)malloc( buffer_size)) == NULL) {
+ return NULL;
+ }
+
+@@ -2551,8 +2555,28 @@
+ } else {
+ /* no MB for this wide */
+ /* use escape for wide character */
+- char *escape_string = wide_to_escape_string(wide_string[i]);
+- strcat(buffer, escape_string);
++ size_t buffer_len;
++ size_t escape_string_len;
++ char *escape_string;
++ int err_msg = 0;
++
++ escape_string = wide_to_escape_string(wide_string[i]);
++ buffer_len = strlen( buffer);
++ escape_string_len = strlen( escape_string);
++
++ /* Append escape string, as space allows. */
++ /* 2022-07-18 SMS, et al. CVE-2022-0529 */
++ if (escape_string_len > buffer_size- buffer_len- 1)
++ {
++ escape_string_len = buffer_size- buffer_len- 1;
++ if (err_msg == 0)
++ {
++ err_msg = 1;
++ Info(slide, 0x401, ((char *)slide,
++ LoadFarString( UFilenameTooLongTrunc)));
++ }
++ }
++ strncat( buffer, escape_string, escape_string_len);
+ free(escape_string);
+ }
+ }
+@@ -2604,9 +2628,18 @@
+ ZCONST char *utf8_string;
+ int escape_all;
+ {
+- zwchar *wide = utf8_to_wide_string(utf8_string);
+- char *loc = wide_to_local_string(wide, escape_all);
+- free(wide);
++ zwchar *wide;
++ char *loc = NULL;
++
++ wide = utf8_to_wide_string( utf8_string);
++
++ /* 2022-07-25 SMS, et al. CVE-2022-0530 */
++ if (wide != NULL)
++ {
++ loc = wide_to_local_string( wide, escape_all);
++ free( wide);
++ }
++
+ return loc;
+ }
+
diff --git a/package/unzip/0029-handle-windows-zip64-files.patch b/package/unzip/0029-handle-windows-zip64-files.patch
new file mode 100644
index 0000000000..c4cd35fd0c
--- /dev/null
+++ b/package/unzip/0029-handle-windows-zip64-files.patch
@@ -0,0 +1,21 @@
+From: Roy Tam
+Subject: Handle Microsoft ZIP64 files by ignoring invalid "Total number of disks" field
+Origin: https://sourceforge.net/p/infozip/bugs/42/
+Bug: https://sourceforge.net/p/infozip/bugs/42/
+Bug-Debian: https://bugs.debian.org/1064000
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/unzip/+bug/2051952
+X-Debian-version: 6.0-29
+
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/29-handle-windows-zip64-files.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/process.c
++++ b/process.c
+@@ -1281,7 +1281,7 @@
+ fprintf(stdout,"\nnumber of disks (ECR) %u, (ECLOC64) %lu\n",
+ G.ecrec.number_this_disk, ecloc64_total_disks); fflush(stdout);
+ #endif
+- if ((G.ecrec.number_this_disk != 0xFFFF) &&
++ if ((G.ecrec.number_this_disk != 0xFFFF) && ecloc64_total_disks &&
+ (G.ecrec.number_this_disk != ecloc64_total_disks - 1)) {
+ /* Note: For some unknown reason, the developers at PKWARE decided to
+ store the "zip64 total disks" value as a counter starting from 1,
diff --git a/package/unzip/0030-drop-conflicting-declarations.patch b/package/unzip/0030-drop-conflicting-declarations.patch
new file mode 100644
index 0000000000..ff32e04d2d
--- /dev/null
+++ b/package/unzip/0030-drop-conflicting-declarations.patch
@@ -0,0 +1,18 @@
+From: Santiago Vila <sanvila@debian.org>
+Subject: Drop conflicting declarations of gmtime() and localtime()
+Bug-Debian: https://bugs.debian.org/1098043
+X-Debian-version: 6.0-29
+
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/30-drop-conflicting-declarations.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/unix/unxcfg.h
++++ b/unix/unxcfg.h
+@@ -118,7 +118,7 @@
+ # endif
+ #else
+ # include <time.h>
+- struct tm *gmtime(), *localtime();
++/* struct tm *gmtime(), *localtime(); */
+ #endif
+
+ #if (defined(BSD4_4) || (defined(SYSV) && defined(MODERN)))
diff --git a/package/unzip/0031-fix-zipgrep.patch b/package/unzip/0031-fix-zipgrep.patch
new file mode 100644
index 0000000000..374ca06f12
--- /dev/null
+++ b/package/unzip/0031-fix-zipgrep.patch
@@ -0,0 +1,20 @@
+From: Vincent Lefevre <vincent@vinc17.net>
+Subject: Do not escape shell-special characters in "pat"
+Bug-Debian: https://bugs.debian.org/1054628
+X-Debian-version: 6.0-29
+
+Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/31-fix-zipgrep.patch
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+--- a/unix/zipgrep
++++ b/unix/zipgrep
+@@ -49,10 +49,6 @@
+ IFS='
+ '
+
+-# Escape shell-special characters in "pat".
+-pat=` echo "$pat" | \
+- sed -e 's/\\\\/\\\\\\\\/g' -e 's/|/\\\|/g' -e 's/&/\\\&/g' `
+-
+ # Use "unzip -Z1" to get a listing of the specified members from the
+ # specified archive. Escape any backslashes in a file name.
+ for i in `unzip -Z1 "$zipfile" ${1+"$@"} | sed -e 's/\\\\/\\\\\\\\/g' `; do
diff --git a/package/unzip/0001-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch b/package/unzip/0101-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch
similarity index 99%
rename from package/unzip/0001-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch
rename to package/unzip/0101-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch
index bdb3eae6af..3c4c60f01d 100644
--- a/package/unzip/0001-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch
+++ b/package/unzip/0101-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch
@@ -19,6 +19,7 @@ build options and flags as the original Makefile does.
[0] http://git.buildroot.net/buildroot/tree/package/infozip?id=2015.11-rc3
+Upstream: N/A
Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
---
CMakeLists.txt | 17 +++++++++++++++++
diff --git a/package/unzip/unzip.mk b/package/unzip/unzip.mk
index 8dccaf6ce3..5436c7a46c 100644
--- a/package/unzip/unzip.mk
+++ b/package/unzip/unzip.mk
@@ -6,27 +6,50 @@
UNZIP_VERSION = 6.0
UNZIP_SOURCE = unzip_$(UNZIP_VERSION).orig.tar.gz
-UNZIP_PATCH = unzip_$(UNZIP_VERSION)-29.debian.tar.xz
UNZIP_SITE = https://snapshot.debian.org/archive/debian/20250311T215724Z/pool/main/u/unzip
UNZIP_LICENSE = Info-ZIP
UNZIP_LICENSE_FILES = LICENSE
UNZIP_CPE_ID_VALID = YES
-# unzip_$(UNZIP_VERSION)-29.debian.tar.xz has patches to fix:
-UNZIP_IGNORE_CVES = \
- CVE-2014-8139 \
- CVE-2014-8140 \
- CVE-2014-8141 \
- CVE-2014-9636 \
- CVE-2014-9913 \
- CVE-2015-7696 \
- CVE-2015-7697 \
- CVE-2016-9844 \
- CVE-2018-18384 \
- CVE-2018-1000035 \
- CVE-2019-13232 \
- CVE-2022-0529 \
- CVE-2022-0530
+# 0009-cve-2014-8139-crc-overflow.patch
+UNZIP_IGNORE_CVES += CVE-2014-8139
+
+# 0010-cve-2014-8140-test-compr-eb.patch
+UNZIP_IGNORE_CVES += CVE-2014-8140
+
+# 0011-cve-2014-8141-getzip64data.patch
+UNZIP_IGNORE_CVES += CVE-2014-8141
+
+# 0012-cve-2014-9636-test-compr-eb.patch
+UNZIP_IGNORE_CVES += CVE-2014-9636
+
+# 0018-cve-2014-9913-unzip-buffer-overflow.patch
+UNZIP_IGNORE_CVES += CVE-2014-9913
+
+# 0014-cve-2015-7696.patch
+UNZIP_IGNORE_CVES += CVE-2015-7696
+
+# 0015-cve-2015-7697.patch
+UNZIP_IGNORE_CVES += CVE-2015-7697
+
+# 0019-cve-2016-9844-zipinfo-buffer-overflow.patch
+UNZIP_IGNORE_CVES += CVE-2016-9844
+
+# 0007-increase-size-of-cfactorstr.patch
+UNZIP_IGNORE_CVES += CVE-2018-18384
+
+# 0020-cve-2018-1000035-unzip-buffer-overflow.patch
+UNZIP_IGNORE_CVES += CVE-2018-1000035
+
+# 0022-cve-2019-13232-fix-bug-in-undefer-input.patch
+# 0023-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
+# 0024-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
+# 0025-cve-2019-13232-fix-bug-in-uzbunzip2.patch
+# 0026-cve-2019-13232-fix-bug-in-uzinflate.patch
+UNZIP_IGNORE_CVES += CVE-2019-13232
+
+# 0028-cve-2022-0529-and-cve-2022-0530.patch
+UNZIP_IGNORE_CVES += CVE-2022-0529 CVE-2022-0530
# unzip already defines _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE when
# necessary, redefining it on the command line causes some warnings.
--
2.52.0
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Buildroot] [PATCH 2/4] package/heirloom-mailx: import patches from Debian
2026-02-04 13:18 [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian Thomas Perale via buildroot
@ 2026-02-04 13:18 ` Thomas Perale via buildroot
2026-06-05 12:49 ` Thomas Perale via buildroot
2026-02-04 13:18 ` [Buildroot] [PATCH 3/4] package/libmad: remove Debian patches Thomas Perale via buildroot
` (3 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Thomas Perale via buildroot @ 2026-02-04 13:18 UTC (permalink / raw)
To: buildroot; +Cc: Luca Ceresoli, Thomas Petazzoni
In Buildroot there are multiple way to apply patches on a package [1]
- Adding `.patch` file in the package directory.
- Define `<pkg>_PATCH` variable with the location of the patch tar.gz.
It used to download Debian patches tarball.
- Implement custom patching logic with `PRE`/`POST` patches hooks.
To make the CycloneDX SBOM generation not dependant on downloading the
packages, the two last options have the downside of not appearing on the
generated SBOM.
The heirloom-mailx package is downloading a tarball from the Debian
mirror with the `<pkg>_PATCH` method [2].
To improve the tracking of the patched vulnerabilities for the
heirloom-mailx package this commit import the patches previously
downloaded with the `_PATCH` variable in the Buildroot tree. This allows
to add the `CVE:` trailer [3] on the patches that fix vulnerabilities to
better track which patch is fixing the vulnerability.
[1] https://buildroot.org/downloads/manual/manual.html#patch-policy
[2] http://snapshot.debian.org/archive/debian/20150815T155609Z/pool/main/h/heirloom-mailx/heirloom-mailx_12.5-5.debian.tar.xz
[3] 1167d0ff3d docs/manual: mention CVE trailer
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
---
.checkpackageignore | 1 -
...k-symbol-optopt-to-fix-FTBFS-on-mips.patch | 57 +++++++++
...-support-since-it-is-no-longer-suppo.patch | 39 ++++++
...-warning-warning-macro-N-not-defined.patch | 23 ++++
...0011-outof-Introduce-expandaddr-flag.patch | 69 +++++++++++
...ption-processing-for-email-addresses.patch | 77 ++++++++++++
...onditionally-require-wordexp-support.patch | 111 ++++++++++++++++++
...bname-Invoke-wordexp-with-WRDE_NOCMD.patch | 29 +++++
.../0015-usr-sbin-sendmail.patch | 36 ++++++
....patch => 0101-fix-libressl-support.patch} | 1 +
package/heirloom-mailx/heirloom-mailx.mk | 5 +-
11 files changed, 444 insertions(+), 4 deletions(-)
create mode 100644 package/heirloom-mailx/0001-Don-t-reuse-weak-symbol-optopt-to-fix-FTBFS-on-mips.patch
create mode 100644 package/heirloom-mailx/0002-Patched-out-SSL2-support-since-it-is-no-longer-suppo.patch
create mode 100644 package/heirloom-mailx/0003-Fixed-Lintian-warning-warning-macro-N-not-defined.patch
create mode 100644 package/heirloom-mailx/0011-outof-Introduce-expandaddr-flag.patch
create mode 100644 package/heirloom-mailx/0012-unpack-Disable-option-processing-for-email-addresses.patch
create mode 100644 package/heirloom-mailx/0013-fio.c-Unconditionally-require-wordexp-support.patch
create mode 100644 package/heirloom-mailx/0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch
create mode 100644 package/heirloom-mailx/0015-usr-sbin-sendmail.patch
rename package/heirloom-mailx/{0001-fix-libressl-support.patch => 0101-fix-libressl-support.patch} (99%)
diff --git a/.checkpackageignore b/.checkpackageignore
index 8e0a283441..340e353ab6 100644
--- a/.checkpackageignore
+++ b/.checkpackageignore
@@ -437,7 +437,6 @@ package/gutenprint/0002-cups-support-replaces-static-with-static-libtool-lib.pat
package/harfbuzz/0001-meson.build-check-for-pthread.h.patch lib_patch.Upstream
package/haserl/0001-add-haserl_lualib.inc.patch lib_patch.Upstream
package/haveged/S21haveged Shellcheck lib_sysv.Variables
-package/heirloom-mailx/0001-fix-libressl-support.patch lib_patch.Upstream
package/hplip/0001-build-use-pkg-config-to-discover-libusb.patch lib_patch.Upstream
package/hplip/0002-configure.in-fix-AM_INIT_AUTOMAKE-call.patch lib_patch.Upstream
package/i2pd/S99i2pd Shellcheck lib_sysv.Indent lib_sysv.Variables
diff --git a/package/heirloom-mailx/0001-Don-t-reuse-weak-symbol-optopt-to-fix-FTBFS-on-mips.patch b/package/heirloom-mailx/0001-Don-t-reuse-weak-symbol-optopt-to-fix-FTBFS-on-mips.patch
new file mode 100644
index 0000000000..967344159e
--- /dev/null
+++ b/package/heirloom-mailx/0001-Don-t-reuse-weak-symbol-optopt-to-fix-FTBFS-on-mips.patch
@@ -0,0 +1,57 @@
+From: Luk Claes <luk@debian.org>
+Date: Sat, 4 Jul 2009 10:54:53 +0200
+Subject: Don't reuse weak symbol optopt to fix FTBFS on mips*
+
+Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0001-Don-t-reuse-weak-symbol-optopt-to-fix-FTBFS-on-mips.patch/
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+ getopt.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/getopt.c b/getopt.c
+index 83ce628..82e983c 100644
+--- a/getopt.c
++++ b/getopt.c
+@@ -43,7 +43,7 @@ typedef int ssize_t;
+ char *optarg;
+ int optind = 1;
+ int opterr = 1;
+-int optopt;
++int optoptc;
+
+ static void
+ error(const char *s, int c)
+@@ -69,7 +69,7 @@ error(const char *s, int c)
+ *bp++ = *s++;
+ while (*msg)
+ *bp++ = *msg++;
+- *bp++ = optopt;
++ *bp++ = optoptc;
+ *bp++ = '\n';
+ write(2, buf, bp - buf);
+ ac_free(buf);
+@@ -101,13 +101,13 @@ getopt(int argc, char *const argv[], const char *optstring)
+ }
+ curp = &argv[optind][1];
+ }
+- optopt = curp[0] & 0377;
++ optoptc = curp[0] & 0377;
+ while (optstring[0]) {
+ if (optstring[0] == ':') {
+ optstring++;
+ continue;
+ }
+- if ((optstring[0] & 0377) == optopt) {
++ if ((optstring[0] & 0377) == optoptc) {
+ if (optstring[1] == ':') {
+ if (curp[1] != '\0') {
+ optarg = (char *)&curp[1];
+@@ -127,7 +127,7 @@ getopt(int argc, char *const argv[], const char *optstring)
+ optind++;
+ optarg = 0;
+ }
+- return optopt;
++ return optoptc;
+ }
+ optstring++;
+ }
diff --git a/package/heirloom-mailx/0002-Patched-out-SSL2-support-since-it-is-no-longer-suppo.patch b/package/heirloom-mailx/0002-Patched-out-SSL2-support-since-it-is-no-longer-suppo.patch
new file mode 100644
index 0000000000..156aea7a37
--- /dev/null
+++ b/package/heirloom-mailx/0002-Patched-out-SSL2-support-since-it-is-no-longer-suppo.patch
@@ -0,0 +1,39 @@
+From: Hilko Bengen <bengen@debian.org>
+Date: Wed, 27 Apr 2011 00:18:42 +0200
+Subject: Patched out SSL2 support since it is no longer supported by OpenSSL.
+
+Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0002-Patched-out-SSL2-support-since-it-is-no-longer-suppo.patch/
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+ mailx.1 | 2 +-
+ openssl.c | 4 +---
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/mailx.1 b/mailx.1
+index 417ea04..a02e430 100644
+--- a/mailx.1
++++ b/mailx.1
+@@ -3575,7 +3575,7 @@ Only applicable if SSL/TLS support is built using OpenSSL.
+ .TP
+ .B ssl-method
+ Selects a SSL/TLS protocol version;
+-valid values are `ssl2', `ssl3', and `tls1'.
++valid values are `ssl3', and `tls1'.
+ If unset, the method is selected automatically,
+ if possible.
+ .TP
+diff --git a/openssl.c b/openssl.c
+index b4e33fc..44fe4e5 100644
+--- a/openssl.c
++++ b/openssl.c
+@@ -216,9 +216,7 @@ ssl_select_method(const char *uhp)
+
+ cp = ssl_method_string(uhp);
+ if (cp != NULL) {
+- if (equal(cp, "ssl2"))
+- method = SSLv2_client_method();
+- else if (equal(cp, "ssl3"))
++ if (equal(cp, "ssl3"))
+ method = SSLv3_client_method();
+ else if (equal(cp, "tls1"))
+ method = TLSv1_client_method();
diff --git a/package/heirloom-mailx/0003-Fixed-Lintian-warning-warning-macro-N-not-defined.patch b/package/heirloom-mailx/0003-Fixed-Lintian-warning-warning-macro-N-not-defined.patch
new file mode 100644
index 0000000000..724f7c8b81
--- /dev/null
+++ b/package/heirloom-mailx/0003-Fixed-Lintian-warning-warning-macro-N-not-defined.patch
@@ -0,0 +1,23 @@
+From: Hilko Bengen <bengen@debian.org>
+Date: Sat, 14 Apr 2012 20:22:43 +0200
+Subject: Fixed Lintian warning (warning: macro `N' not defined)
+
+Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0003-Fixed-Lintian-warning-warning-macro-N-not-defined.patch/
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+ mailx.1 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mailx.1 b/mailx.1
+index a02e430..b0723bd 100644
+--- a/mailx.1
++++ b/mailx.1
+@@ -3781,7 +3781,7 @@ you could examine the first message by giving the command:
+ .sp
+ .fi
+ which might cause
+-.N mailx
++.I mailx
+ to respond with, for example:
+ .nf
+ .sp
diff --git a/package/heirloom-mailx/0011-outof-Introduce-expandaddr-flag.patch b/package/heirloom-mailx/0011-outof-Introduce-expandaddr-flag.patch
new file mode 100644
index 0000000000..7825b788bc
--- /dev/null
+++ b/package/heirloom-mailx/0011-outof-Introduce-expandaddr-flag.patch
@@ -0,0 +1,69 @@
+From 9984ae5cb0ea0d61df1612b06952a61323c083d9 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 17 Nov 2014 11:13:38 +0100
+Subject: [PATCH] outof: Introduce expandaddr flag
+
+Document that address expansion is disabled unless the expandaddr
+binary option is set.
+
+This has been assigned CVE-2014-7844 for BSD mailx, but it is not
+a vulnerability in Heirloom mailx because this feature was documented.
+
+CVE: CVE-2014-7844
+Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0011-outof-Introduce-expandaddr-flag.patch/
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+ mailx.1 | 14 ++++++++++++++
+ names.c | 3 +++
+ 2 files changed, 17 insertions(+)
+
+diff --git a/mailx.1 b/mailx.1
+index 70a7859..22a171b 100644
+--- a/mailx.1
++++ b/mailx.1
+@@ -656,6 +656,14 @@ but any reply returned to the machine
+ will have the system wide alias expanded
+ as all mail goes through sendmail.
+ .SS "Recipient address specifications"
++If the
++.I expandaddr
++option is not set (the default), recipient addresses must be names of
++local mailboxes or Internet mail addresses.
++.PP
++If the
++.I expandaddr
++option is set, the following rules apply:
+ When an address is used to name a recipient
+ (in any of To, Cc, or Bcc),
+ names of local mail folders
+@@ -2391,6 +2399,12 @@ and exits immediately.
+ If this option is set,
+ \fImailx\fR starts even with an empty mailbox.
+ .TP
++.B expandaddr
++Causes
++.I mailx
++to expand message recipient addresses, as explained in the section,
++Recipient address specifications.
++.TP
+ .B flipr
+ Exchanges the
+ .I Respond
+diff --git a/names.c b/names.c
+index 66e976b..c69560f 100644
+--- a/names.c
++++ b/names.c
+@@ -268,6 +268,9 @@ outof(struct name *names, FILE *fo, struct header *hp)
+ FILE *fout, *fin;
+ int ispipe;
+
++ if (value("expandaddr") == NULL)
++ return names;
++
+ top = names;
+ np = names;
+ time(&now);
+--
+1.9.3
+
+
diff --git a/package/heirloom-mailx/0012-unpack-Disable-option-processing-for-email-addresses.patch b/package/heirloom-mailx/0012-unpack-Disable-option-processing-for-email-addresses.patch
new file mode 100644
index 0000000000..64a1e7f246
--- /dev/null
+++ b/package/heirloom-mailx/0012-unpack-Disable-option-processing-for-email-addresses.patch
@@ -0,0 +1,77 @@
+From e34e2ac67b80497080ebecccec40c3b61456167d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 17 Nov 2014 11:14:06 +0100
+Subject: [PATCH] unpack: Disable option processing for email addresses
+ when calling sendmail
+
+Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0012-unpack-Disable-option-processing-for-email-addresses.patch/
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+ extern.h | 2 +-
+ names.c | 8 ++++++--
+ sendout.c | 2 +-
+ 3 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/extern.h b/extern.h
+index 6b85ba0..8873fe8 100644
+--- a/extern.h
++++ b/extern.h
+@@ -396,7 +396,7 @@ struct name *outof(struct name *names, FILE *fo, struct header *hp);
+ int is_fileaddr(char *name);
+ struct name *usermap(struct name *names);
+ struct name *cat(struct name *n1, struct name *n2);
+-char **unpack(struct name *np);
++char **unpack(struct name *smopts, struct name *np);
+ struct name *elide(struct name *names);
+ int count(struct name *np);
+ struct name *delete_alternates(struct name *np);
+diff --git a/names.c b/names.c
+index c69560f..45bbaed 100644
+--- a/names.c
++++ b/names.c
+@@ -549,7 +549,7 @@ cat(struct name *n1, struct name *n2)
+ * Return an error if the name list won't fit.
+ */
+ char **
+-unpack(struct name *np)
++unpack(struct name *smopts, struct name *np)
+ {
+ char **ap, **top;
+ struct name *n;
+@@ -564,7 +564,7 @@ unpack(struct name *np)
+ * the terminating 0 pointer. Additional spots may be needed
+ * to pass along -f to the host mailer.
+ */
+- extra = 2;
++ extra = 3 + count(smopts);
+ extra++;
+ metoo = value("metoo") != NULL;
+ if (metoo)
+@@ -581,6 +581,10 @@ unpack(struct name *np)
+ *ap++ = "-m";
+ if (verbose)
+ *ap++ = "-v";
++ for (; smopts != NULL; smopts = smopts->n_flink)
++ if ((smopts->n_type & GDEL) == 0)
++ *ap++ = smopts->n_name;
++ *ap++ = "--";
+ for (; n != NULL; n = n->n_flink)
+ if ((n->n_type & GDEL) == 0)
+ *ap++ = n->n_name;
+diff --git a/sendout.c b/sendout.c
+index 7b7f2eb..c52f15d 100644
+--- a/sendout.c
++++ b/sendout.c
+@@ -835,7 +835,7 @@ start_mta(struct name *to, struct name *mailargs, FILE *input,
+ #endif /* HAVE_SOCKETS */
+
+ if ((smtp = value("smtp")) == NULL) {
+- args = unpack(cat(mailargs, to));
++ args = unpack(mailargs, to);
+ if (debug || value("debug")) {
+ printf(catgets(catd, CATSET, 181,
+ "Sendmail arguments:"));
+--
+1.9.3
+
+
diff --git a/package/heirloom-mailx/0013-fio.c-Unconditionally-require-wordexp-support.patch b/package/heirloom-mailx/0013-fio.c-Unconditionally-require-wordexp-support.patch
new file mode 100644
index 0000000000..6938daec12
--- /dev/null
+++ b/package/heirloom-mailx/0013-fio.c-Unconditionally-require-wordexp-support.patch
@@ -0,0 +1,111 @@
+From 2bae8ecf04ec2ba6bb9f0af5b80485dd0edb427d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 17 Nov 2014 12:48:25 +0100
+Subject: [PATCH] fio.c: Unconditionally require wordexp support
+
+Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0013-fio.c-Unconditionally-require-wordexp-support.patch/
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+ fio.c | 67 +++++--------------------------------------------------------------
+ 1 file changed, 5 insertions(+), 62 deletions(-)
+
+diff --git a/fio.c b/fio.c
+index 65e8f10..1529236 100644
+--- a/fio.c
++++ b/fio.c
+@@ -43,12 +43,15 @@ static char sccsid[] = "@(#)fio.c 2.76 (gritter) 9/16/09";
+ #endif /* not lint */
+
+ #include "rcv.h"
++
++#ifndef HAVE_WORDEXP
++#error wordexp support is required
++#endif
++
+ #include <sys/stat.h>
+ #include <sys/file.h>
+ #include <sys/wait.h>
+-#ifdef HAVE_WORDEXP
+ #include <wordexp.h>
+-#endif /* HAVE_WORDEXP */
+ #include <unistd.h>
+
+ #if defined (USE_NSS)
+@@ -481,7 +484,6 @@ next:
+ static char *
+ globname(char *name)
+ {
+-#ifdef HAVE_WORDEXP
+ wordexp_t we;
+ char *cp;
+ sigset_t nset;
+@@ -527,65 +529,6 @@ globname(char *name)
+ }
+ wordfree(&we);
+ return cp;
+-#else /* !HAVE_WORDEXP */
+- char xname[PATHSIZE];
+- char cmdbuf[PATHSIZE]; /* also used for file names */
+- int pid, l;
+- char *cp, *shell;
+- int pivec[2];
+- extern int wait_status;
+- struct stat sbuf;
+-
+- if (pipe(pivec) < 0) {
+- perror("pipe");
+- return name;
+- }
+- snprintf(cmdbuf, sizeof cmdbuf, "echo %s", name);
+- if ((shell = value("SHELL")) == NULL)
+- shell = SHELL;
+- pid = start_command(shell, 0, -1, pivec[1], "-c", cmdbuf, NULL);
+- if (pid < 0) {
+- close(pivec[0]);
+- close(pivec[1]);
+- return NULL;
+- }
+- close(pivec[1]);
+-again:
+- l = read(pivec[0], xname, sizeof xname);
+- if (l < 0) {
+- if (errno == EINTR)
+- goto again;
+- perror("read");
+- close(pivec[0]);
+- return NULL;
+- }
+- close(pivec[0]);
+- if (wait_child(pid) < 0 && WTERMSIG(wait_status) != SIGPIPE) {
+- fprintf(stderr, catgets(catd, CATSET, 81,
+- "\"%s\": Expansion failed.\n"), name);
+- return NULL;
+- }
+- if (l == 0) {
+- fprintf(stderr, catgets(catd, CATSET, 82,
+- "\"%s\": No match.\n"), name);
+- return NULL;
+- }
+- if (l == sizeof xname) {
+- fprintf(stderr, catgets(catd, CATSET, 83,
+- "\"%s\": Expansion buffer overflow.\n"), name);
+- return NULL;
+- }
+- xname[l] = 0;
+- for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--)
+- ;
+- cp[1] = '\0';
+- if (strchr(xname, ' ') && stat(xname, &sbuf) < 0) {
+- fprintf(stderr, catgets(catd, CATSET, 84,
+- "\"%s\": Ambiguous.\n"), name);
+- return NULL;
+- }
+- return savestr(xname);
+-#endif /* !HAVE_WORDEXP */
+ }
+
+ /*
+--
+1.9.3
+
+
diff --git a/package/heirloom-mailx/0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch b/package/heirloom-mailx/0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch
new file mode 100644
index 0000000000..378b157d8a
--- /dev/null
+++ b/package/heirloom-mailx/0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch
@@ -0,0 +1,29 @@
+From 73fefa0c1ac70043ec84f2d8b8f9f683213f168d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 17 Nov 2014 13:11:32 +0100
+Subject: [PATCH] globname: Invoke wordexp with WRDE_NOCMD (CVE-2004-2771)
+
+CVE: CVE-2004-2771
+Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch/
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+ fio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fio.c b/fio.c
+index 1529236..774a204 100644
+--- a/fio.c
++++ b/fio.c
+@@ -497,7 +497,7 @@ globname(char *name)
+ sigemptyset(&nset);
+ sigaddset(&nset, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &nset, NULL);
+- i = wordexp(name, &we, 0);
++ i = wordexp(name, &we, WRDE_NOCMD);
+ sigprocmask(SIG_UNBLOCK, &nset, NULL);
+ switch (i) {
+ case 0:
+--
+1.9.3
+
+
diff --git a/package/heirloom-mailx/0015-usr-sbin-sendmail.patch b/package/heirloom-mailx/0015-usr-sbin-sendmail.patch
new file mode 100644
index 0000000000..195b606c01
--- /dev/null
+++ b/package/heirloom-mailx/0015-usr-sbin-sendmail.patch
@@ -0,0 +1,36 @@
+Description: Sendmail is at /usr/sbin/sendmail
+ As per Debian Policy §11.6
+Author: Ryan Kavanagh <rak@debian.org>
+Origin: Debian
+Forwarded: no
+
+Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0015-usr-sbin-sendmail.patch/
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+Index: heirloom-mailx-12.5/Makefile
+===================================================================
+--- heirloom-mailx-12.5.orig/Makefile 2011-04-26 17:23:22.000000000 -0400
++++ heirloom-mailx-12.5/Makefile 2015-01-27 13:20:04.733542801 -0500
+@@ -13,7 +13,7 @@
+
+ MAILRC = $(SYSCONFDIR)/nail.rc
+ MAILSPOOL = /var/mail
+-SENDMAIL = /usr/lib/sendmail
++SENDMAIL = /usr/sbin/sendmail
+
+ DESTDIR =
+
+Index: heirloom-mailx-12.5/mailx.1
+===================================================================
+--- heirloom-mailx-12.5.orig/mailx.1 2015-01-27 13:18:49.000000000 -0500
++++ heirloom-mailx-12.5/mailx.1 2015-01-27 13:20:32.382336867 -0500
+@@ -4922,7 +4922,7 @@
+ which just acts as a proxy.
+ .PP
+ \fIMailx\fR immediately contacts the SMTP server (or
+-.IR \%/usr/lib/sendmail )
++.IR \%/usr/sbin/sendmail )
+ even when operating in
+ .I disconnected
+ mode.
diff --git a/package/heirloom-mailx/0001-fix-libressl-support.patch b/package/heirloom-mailx/0101-fix-libressl-support.patch
similarity index 99%
rename from package/heirloom-mailx/0001-fix-libressl-support.patch
rename to package/heirloom-mailx/0101-fix-libressl-support.patch
index b54aaaf73c..25cc92d580 100644
--- a/package/heirloom-mailx/0001-fix-libressl-support.patch
+++ b/package/heirloom-mailx/0101-fix-libressl-support.patch
@@ -10,6 +10,7 @@ heirloom-mailx has two small issues when compiling against LibreSSL:
- SSLv3_client_method function is used (LibreSSL does not support SSLv3)
Solution: "Guard" the code with #ifndef OPENSSL_NO_SSL3
+Upstream: N/A
Signed-off-by: Adam Duskett <aduskett@gmail.com>
---
openssl.c | 7 +++++++
diff --git a/package/heirloom-mailx/heirloom-mailx.mk b/package/heirloom-mailx/heirloom-mailx.mk
index 063fccf5eb..075b5f6a59 100644
--- a/package/heirloom-mailx/heirloom-mailx.mk
+++ b/package/heirloom-mailx/heirloom-mailx.mk
@@ -7,14 +7,13 @@
HEIRLOOM_MAILX_VERSION = 12.5
HEIRLOOM_MAILX_SOURCE = heirloom-mailx_$(HEIRLOOM_MAILX_VERSION).orig.tar.gz
HEIRLOOM_MAILX_SITE = http://snapshot.debian.org/archive/debian/20150815T155609Z/pool/main/h/heirloom-mailx
-HEIRLOOM_MAILX_PATCH = heirloom-mailx_$(HEIRLOOM_MAILX_VERSION)-5.debian.tar.xz
HEIRLOOM_MAILX_LICENSE = BSD-4-Clause, Bellcore (base64), OpenVision (imap_gssapi), RSA Data Security (md5), Network Working Group (hmac), MPL-1.1 (nss)
HEIRLOOM_MAILX_LICENSE_FILES = COPYING
HEIRLOOM_MAILX_CPE_ID_VENDOR = heirloom
HEIRLOOM_MAILX_CPE_ID_PRODUCT = mailx
-# 0011-outof-Introduce-expandaddr-flag.patch in the Debian patches
+# 0011-outof-Introduce-expandaddr-flag.patch
HEIRLOOM_MAILX_IGNORE_CVES += CVE-2014-7844
-# 0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch in the Debian patches
+# 0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch
HEIRLOOM_MAILX_IGNORE_CVES += CVE-2004-2771
ifeq ($(BR2_PACKAGE_OPENSSL),y)
--
2.52.0
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Buildroot] [PATCH 3/4] package/libmad: remove Debian patches
2026-02-04 13:18 [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian Thomas Perale via buildroot
2026-02-04 13:18 ` [Buildroot] [PATCH 2/4] package/heirloom-mailx: " Thomas Perale via buildroot
@ 2026-02-04 13:18 ` Thomas Perale via buildroot
2026-06-05 12:49 ` Thomas Perale via buildroot
2026-02-04 13:18 ` [Buildroot] [PATCH 4/4] package/libmad: add patch for CVE-2017-837{2, 3, 4} Thomas Perale via buildroot
` (2 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Thomas Perale via buildroot @ 2026-02-04 13:18 UTC (permalink / raw)
To: buildroot; +Cc: Luca Ceresoli, Thomas Petazzoni
In Buildroot there are multiple way to apply patches on a package [1]
- Adding `.patch` file in the package directory.
- Define `<pkg>_PATCH` variable with the location of the patch tar.gz.
It used to download Debian patches tarball.
- Implement custom patching logic with `PRE`/`POST` patches hooks.
The libmad package is downloading a diff file from the Debian
mirror with the `<pkg>_PATCH` method [2] and then apply that diff to
create a directory containing patches. The patches are then applied in
the `PRE_PATCH_HOOK`.
The Debian patches were integrated in commit [4], in commit [5] the
application of the patches was moved to the PRE_PATCH_HOOK.
The problem is that in the PRE_PATCH step the `_PATCH` downloaded from
Debian don't exist yet and end up not being applied at all.
Since this is not used, remove the Debian patches.
[1] https://buildroot.org/downloads/manual/manual.html#patch-policy
[2] http://snapshot.debian.org/archive/debian/20190310T213528Z/pool/main/libm/libmad/libmad_0.15.1b-10.diff.gz
[3] 1167d0ff3d docs/manual: mention CVE trailer
[4] 858df3643f package/libmad: switch to debian to fix CVEs
[5] b21184a877 package/libmad: update the patches to be applied with fuzz 0
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
---
package/libmad/libmad.mk | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/package/libmad/libmad.mk b/package/libmad/libmad.mk
index db04d22e92..611f13eb67 100644
--- a/package/libmad/libmad.mk
+++ b/package/libmad/libmad.mk
@@ -5,7 +5,6 @@
################################################################################
LIBMAD_VERSION = 0.15.1b
-LIBMAD_PATCH = libmad_$(LIBMAD_VERSION)-10.diff.gz
LIBMAD_SOURCE = libmad_$(LIBMAD_VERSION).orig.tar.gz
LIBMAD_SITE = \
http://snapshot.debian.org/archive/debian/20190310T213528Z/pool/main/libm/libmad
@@ -13,20 +12,6 @@ LIBMAD_INSTALL_STAGING = YES
LIBMAD_LICENSE = GPL-2.0+
LIBMAD_LICENSE_FILES = COPYING
-define LIBMAD_APPLY_DEBIAN_PATCHES
- if [ -d $(@D)/debian/patches ]; then \
- $(APPLY_PATCHES) $(@D) $(@D)/debian/patches *.patch; \
- fi
-endef
-
-LIBMAD_PRE_PATCH_HOOKS += LIBMAD_APPLY_DEBIAN_PATCHES
-
-# debian/patches/md_size.diff
-LIBMAD_IGNORE_CVES += CVE-2017-8372 CVE-2017-8373
-
-# debian/patches/length-check.patch
-LIBMAD_IGNORE_CVES += CVE-2017-8374
-
# Force autoreconf to be able to use a more recent libtool script, that
# is able to properly behave in the face of a missing C++ compiler.
LIBMAD_AUTORECONF = YES
--
2.52.0
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Buildroot] [PATCH 4/4] package/libmad: add patch for CVE-2017-837{2, 3, 4}
2026-02-04 13:18 [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian Thomas Perale via buildroot
2026-02-04 13:18 ` [Buildroot] [PATCH 2/4] package/heirloom-mailx: " Thomas Perale via buildroot
2026-02-04 13:18 ` [Buildroot] [PATCH 3/4] package/libmad: remove Debian patches Thomas Perale via buildroot
@ 2026-02-04 13:18 ` Thomas Perale via buildroot
2026-06-05 12:49 ` Thomas Perale via buildroot
2026-05-29 9:45 ` [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian Thomas Petazzoni via buildroot
2026-06-05 12:49 ` Thomas Perale via buildroot
4 siblings, 1 reply; 9+ messages in thread
From: Thomas Perale via buildroot @ 2026-02-04 13:18 UTC (permalink / raw)
To: buildroot; +Cc: Luca Ceresoli, Thomas Petazzoni
The commit [1] introduced fixes for the following CVEs:
- CVE-2017-8372: The mad_layer_III function in layer3.c in Underbit MAD
libmad 0.15.1b, if NDEBUG is omitted, allows remote attackers to cause
a denial of service (assertion failure and application exit) via a
crafted audio file.
- CVE-2017-8373: The mad_layer_III function in layer3.c in Underbit MAD
libmad 0.15.1b allows remote attackers to cause a denial of service
(heap-based buffer overflow and application crash) or possibly have
unspecified other impact via a crafted audio file.
- CVE-2017-8374: The mad_bit_skip function in bit.c in Underbit MAD
libmad 0.15.1b allows remote attackers to cause a denial of service
(heap-based buffer over-read and application crash) via a crafted
audio file.
In commit [2], the patches ended up not being applied anymore because
the APPLY_PATCHES step was called before the patch content exists.
This commit import the fixes in Buildroot.
[1] 858df3643f package/libmad: switch to debian to fix CVEs
[2] b21184a877 package/libmad: update the patches to be applied with fuzz 0
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
---
package/libmad/0004-md_size.patch | 63 ++
package/libmad/0005-length-check.patch | 821 +++++++++++++++++++++++++
package/libmad/libmad.mk | 6 +
3 files changed, 890 insertions(+)
create mode 100644 package/libmad/0004-md_size.patch
create mode 100644 package/libmad/0005-length-check.patch
diff --git a/package/libmad/0004-md_size.patch b/package/libmad/0004-md_size.patch
new file mode 100644
index 0000000000..b2b3b99df2
--- /dev/null
+++ b/package/libmad/0004-md_size.patch
@@ -0,0 +1,63 @@
+From: Kurt Roeckx <kurt@roeckx.be>
+Date: Sun, 28 Jan 2018 15:44:08 +0100
+Subject: Check the size of the main data
+
+The main data to decode a frame can come from the current frame and part of the
+previous frame, the so called bit reservoir. si.main_data_begin is the part of
+the previous frame we need for this frame. frame_space is the amount of main
+data that can be in this frame, and next_md_begin is the part of this frame that
+is going to be used for the next frame.
+
+The maximum amount of data from a previous frame that the format allows is 511
+bytes. The maximum frame size for the defined bitrates is at MPEG 2.5 layer 2
+at 320 kbit/s and 8 kHz sample rate which gives 72 * (320000 / 8000) + 1 = 2881.
+So those defines are not large enough:
+ # define MAD_BUFFER_GUARD 8
+ # define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD)
+
+There is also support for a "free" bitrate which allows you to create any frame
+size, which can be larger than the buffer.
+
+Changing the defines is not an option since it's part of the ABI, so we check
+that the main data fits in the bufer.
+
+The previous frame data is stored in *stream->main_data and contains
+stream->md_len bytes. If stream->md_len is larger than the data we
+need from the previous frame (si.main_data_begin) it still wouldn't fit
+in the buffer, so just keep the data that we need.
+
+CVE: CVE-2017-8372
+CVE: CVE-2017-8373
+Upstream: http://snapshot.debian.org/archive/debian/20190310T213528Z/pool/main/libm/libmad/libmad_0.15.1b-10.diff.gz
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+Index: libmad-0.15.1b/layer3.c
+===================================================================
+--- libmad-0.15.1b.orig/layer3.c
++++ libmad-0.15.1b/layer3.c
+@@ -2608,6 +2608,11 @@ int mad_layer_III(struct mad_stream *str
+ next_md_begin = 0;
+
+ md_len = si.main_data_begin + frame_space - next_md_begin;
++ if (md_len + MAD_BUFFER_GUARD > MAD_BUFFER_MDLEN) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
+
+ frame_used = 0;
+
+@@ -2625,8 +2630,11 @@ int mad_layer_III(struct mad_stream *str
+ }
+ }
+ else {
+- mad_bit_init(&ptr,
+- *stream->main_data + stream->md_len - si.main_data_begin);
++ memmove(stream->main_data,
++ *stream->main_data + stream->md_len - si.main_data_begin,
++ si.main_data_begin);
++ stream->md_len = si.main_data_begin;
++ mad_bit_init(&ptr, *stream->main_data);
+
+ if (md_len > si.main_data_begin) {
+ assert(stream->md_len + md_len -
diff --git a/package/libmad/0005-length-check.patch b/package/libmad/0005-length-check.patch
new file mode 100644
index 0000000000..5c56849da7
--- /dev/null
+++ b/package/libmad/0005-length-check.patch
@@ -0,0 +1,821 @@
+From: Kurt Roeckx <kurt@roeckx.be>
+Date: Sun, 28 Jan 2018 19:26:36 +0100
+Subject: Check the size before reading with mad_bit_read
+
+There are various cases where it attemps to read past the end of the buffer
+using mad_bit_read(). Most functions didn't even know the size of the buffer
+they were reading from.
+
+CVE: CVE-2017-8374
+Upstream: http://snapshot.debian.org/archive/debian/20190310T213528Z/pool/main/libm/libmad/libmad_0.15.1b-10.diff.gz
+Signed-off-by: Thomas Perale <thomas.perale@mind.be>
+
+Index: libmad-0.15.1b/bit.c
+===================================================================
+--- libmad-0.15.1b.orig/bit.c
++++ libmad-0.15.1b/bit.c
+@@ -138,6 +138,9 @@ unsigned long mad_bit_read(struct mad_bi
+ {
+ register unsigned long value;
+
++ if (len == 0)
++ return 0;
++
+ if (bitptr->left == CHAR_BIT)
+ bitptr->cache = *bitptr->byte;
+
+Index: libmad-0.15.1b/frame.c
+===================================================================
+--- libmad-0.15.1b.orig/frame.c
++++ libmad-0.15.1b/frame.c
+@@ -120,11 +120,18 @@ static
+ int decode_header(struct mad_header *header, struct mad_stream *stream)
+ {
+ unsigned int index;
++ struct mad_bitptr bufend_ptr;
+
+ header->flags = 0;
+ header->private_bits = 0;
+
++ mad_bit_init(&bufend_ptr, stream->bufend);
++
+ /* header() */
++ if (mad_bit_length(&stream->ptr, &bufend_ptr) < 32) {
++ stream->error = MAD_ERROR_BUFLEN;
++ return -1;
++ }
+
+ /* syncword */
+ mad_bit_skip(&stream->ptr, 11);
+@@ -225,8 +232,13 @@ int decode_header(struct mad_header *hea
+ /* error_check() */
+
+ /* crc_check */
+- if (header->flags & MAD_FLAG_PROTECTION)
++ if (header->flags & MAD_FLAG_PROTECTION) {
++ if (mad_bit_length(&stream->ptr, &bufend_ptr) < 16) {
++ stream->error = MAD_ERROR_BUFLEN;
++ return -1;
++ }
+ header->crc_target = mad_bit_read(&stream->ptr, 16);
++ }
+
+ return 0;
+ }
+@@ -338,7 +350,7 @@ int mad_header_decode(struct mad_header
+ stream->error = MAD_ERROR_BUFLEN;
+ goto fail;
+ }
+- else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
++ else if ((end - ptr >= 2) && !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
+ /* mark point where frame sync word was expected */
+ stream->this_frame = ptr;
+ stream->next_frame = ptr + 1;
+@@ -361,6 +373,8 @@ int mad_header_decode(struct mad_header
+ ptr = mad_bit_nextbyte(&stream->ptr);
+ }
+
++ stream->error = MAD_ERROR_NONE;
++
+ /* begin processing */
+ stream->this_frame = ptr;
+ stream->next_frame = ptr + 1; /* possibly bogus sync word */
+@@ -413,7 +427,7 @@ int mad_header_decode(struct mad_header
+ /* check that a valid frame header follows this frame */
+
+ ptr = stream->next_frame;
+- if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
++ if ((end - ptr >= 2) && !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
+ ptr = stream->next_frame = stream->this_frame + 1;
+ goto sync;
+ }
+Index: libmad-0.15.1b/layer12.c
+===================================================================
+--- libmad-0.15.1b.orig/layer12.c
++++ libmad-0.15.1b/layer12.c
+@@ -72,10 +72,18 @@ mad_fixed_t const linear_table[14] = {
+ * DESCRIPTION: decode one requantized Layer I sample from a bitstream
+ */
+ static
+-mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb)
++mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb, struct mad_stream *stream)
+ {
+ mad_fixed_t sample;
++ struct mad_bitptr frameend_ptr;
+
++ mad_bit_init(&frameend_ptr, stream->next_frame);
++
++ if (mad_bit_length(ptr, &frameend_ptr) < nb) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return 0;
++ }
+ sample = mad_bit_read(ptr, nb);
+
+ /* invert most significant bit, extend sign, then scale to fixed format */
+@@ -106,6 +114,10 @@ int mad_layer_I(struct mad_stream *strea
+ struct mad_header *header = &frame->header;
+ unsigned int nch, bound, ch, s, sb, nb;
+ unsigned char allocation[2][32], scalefactor[2][32];
++ struct mad_bitptr bufend_ptr, frameend_ptr;
++
++ mad_bit_init(&bufend_ptr, stream->bufend);
++ mad_bit_init(&frameend_ptr, stream->next_frame);
+
+ nch = MAD_NCHANNELS(header);
+
+@@ -118,6 +130,11 @@ int mad_layer_I(struct mad_stream *strea
+ /* check CRC word */
+
+ if (header->flags & MAD_FLAG_PROTECTION) {
++ if (mad_bit_length(&stream->ptr, &bufend_ptr)
++ < 4 * (bound * nch + (32 - bound))) {
++ stream->error = MAD_ERROR_BADCRC;
++ return -1;
++ }
+ header->crc_check =
+ mad_bit_crc(stream->ptr, 4 * (bound * nch + (32 - bound)),
+ header->crc_check);
+@@ -133,6 +150,11 @@ int mad_layer_I(struct mad_stream *strea
+
+ for (sb = 0; sb < bound; ++sb) {
+ for (ch = 0; ch < nch; ++ch) {
++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 4) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
+ nb = mad_bit_read(&stream->ptr, 4);
+
+ if (nb == 15) {
+@@ -145,6 +167,11 @@ int mad_layer_I(struct mad_stream *strea
+ }
+
+ for (sb = bound; sb < 32; ++sb) {
++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 4) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
+ nb = mad_bit_read(&stream->ptr, 4);
+
+ if (nb == 15) {
+@@ -161,6 +188,11 @@ int mad_layer_I(struct mad_stream *strea
+ for (sb = 0; sb < 32; ++sb) {
+ for (ch = 0; ch < nch; ++ch) {
+ if (allocation[ch][sb]) {
++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 6) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
+ scalefactor[ch][sb] = mad_bit_read(&stream->ptr, 6);
+
+ # if defined(OPT_STRICT)
+@@ -185,8 +217,10 @@ int mad_layer_I(struct mad_stream *strea
+ for (ch = 0; ch < nch; ++ch) {
+ nb = allocation[ch][sb];
+ frame->sbsample[ch][s][sb] = nb ?
+- mad_f_mul(I_sample(&stream->ptr, nb),
++ mad_f_mul(I_sample(&stream->ptr, nb, stream),
+ sf_table[scalefactor[ch][sb]]) : 0;
++ if (stream->error != 0)
++ return -1;
+ }
+ }
+
+@@ -194,7 +228,14 @@ int mad_layer_I(struct mad_stream *strea
+ if ((nb = allocation[0][sb])) {
+ mad_fixed_t sample;
+
+- sample = I_sample(&stream->ptr, nb);
++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < nb) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
++ sample = I_sample(&stream->ptr, nb, stream);
++ if (stream->error != 0)
++ return -1;
+
+ for (ch = 0; ch < nch; ++ch) {
+ frame->sbsample[ch][s][sb] =
+@@ -280,13 +321,21 @@ struct quantclass {
+ static
+ void II_samples(struct mad_bitptr *ptr,
+ struct quantclass const *quantclass,
+- mad_fixed_t output[3])
++ mad_fixed_t output[3], struct mad_stream *stream)
+ {
+ unsigned int nb, s, sample[3];
++ struct mad_bitptr frameend_ptr;
++
++ mad_bit_init(&frameend_ptr, stream->next_frame);
+
+ if ((nb = quantclass->group)) {
+ unsigned int c, nlevels;
+
++ if (mad_bit_length(ptr, &frameend_ptr) < quantclass->bits) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return;
++ }
+ /* degrouping */
+ c = mad_bit_read(ptr, quantclass->bits);
+ nlevels = quantclass->nlevels;
+@@ -299,8 +348,14 @@ void II_samples(struct mad_bitptr *ptr,
+ else {
+ nb = quantclass->bits;
+
+- for (s = 0; s < 3; ++s)
++ for (s = 0; s < 3; ++s) {
++ if (mad_bit_length(ptr, &frameend_ptr) < nb) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return;
++ }
+ sample[s] = mad_bit_read(ptr, nb);
++ }
+ }
+
+ for (s = 0; s < 3; ++s) {
+@@ -336,6 +391,9 @@ int mad_layer_II(struct mad_stream *stre
+ unsigned char const *offsets;
+ unsigned char allocation[2][32], scfsi[2][32], scalefactor[2][32][3];
+ mad_fixed_t samples[3];
++ struct mad_bitptr frameend_ptr;
++
++ mad_bit_init(&frameend_ptr, stream->next_frame);
+
+ nch = MAD_NCHANNELS(header);
+
+@@ -402,13 +460,24 @@ int mad_layer_II(struct mad_stream *stre
+ for (sb = 0; sb < bound; ++sb) {
+ nbal = bitalloc_table[offsets[sb]].nbal;
+
+- for (ch = 0; ch < nch; ++ch)
++ for (ch = 0; ch < nch; ++ch) {
++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < nbal) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
+ allocation[ch][sb] = mad_bit_read(&stream->ptr, nbal);
++ }
+ }
+
+ for (sb = bound; sb < sblimit; ++sb) {
+ nbal = bitalloc_table[offsets[sb]].nbal;
+
++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < nbal) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
+ allocation[0][sb] =
+ allocation[1][sb] = mad_bit_read(&stream->ptr, nbal);
+ }
+@@ -417,8 +486,14 @@ int mad_layer_II(struct mad_stream *stre
+
+ for (sb = 0; sb < sblimit; ++sb) {
+ for (ch = 0; ch < nch; ++ch) {
+- if (allocation[ch][sb])
++ if (allocation[ch][sb]) {
++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 2) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
+ scfsi[ch][sb] = mad_bit_read(&stream->ptr, 2);
++ }
+ }
+ }
+
+@@ -441,6 +516,11 @@ int mad_layer_II(struct mad_stream *stre
+ for (sb = 0; sb < sblimit; ++sb) {
+ for (ch = 0; ch < nch; ++ch) {
+ if (allocation[ch][sb]) {
++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 6) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
+ scalefactor[ch][sb][0] = mad_bit_read(&stream->ptr, 6);
+
+ switch (scfsi[ch][sb]) {
+@@ -451,11 +531,21 @@ int mad_layer_II(struct mad_stream *stre
+ break;
+
+ case 0:
++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 6) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
+ scalefactor[ch][sb][1] = mad_bit_read(&stream->ptr, 6);
+ /* fall through */
+
+ case 1:
+ case 3:
++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 6) {
++ stream->error = MAD_ERROR_LOSTSYNC;
++ stream->sync = 0;
++ return -1;
++ }
+ scalefactor[ch][sb][2] = mad_bit_read(&stream->ptr, 6);
+ }
+
+@@ -487,7 +577,9 @@ int mad_layer_II(struct mad_stream *stre
+ if ((index = allocation[ch][sb])) {
+ index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
+
+- II_samples(&stream->ptr, &qc_table[index], samples);
++ II_samples(&stream->ptr, &qc_table[index], samples, stream);
++ if (stream->error != 0)
++ return -1;
+
+ for (s = 0; s < 3; ++s) {
+ frame->sbsample[ch][3 * gr + s][sb] =
+@@ -505,7 +597,9 @@ int mad_layer_II(struct mad_stream *stre
+ if ((index = allocation[0][sb])) {
+ index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
+
+- II_samples(&stream->ptr, &qc_table[index], samples);
++ II_samples(&stream->ptr, &qc_table[index], samples, stream);
++ if (stream->error != 0)
++ return -1;
+
+ for (ch = 0; ch < nch; ++ch) {
+ for (s = 0; s < 3; ++s) {
+Index: libmad-0.15.1b/layer3.c
+===================================================================
+--- libmad-0.15.1b.orig/layer3.c
++++ libmad-0.15.1b/layer3.c
+@@ -598,7 +598,8 @@ enum mad_error III_sideinfo(struct mad_b
+ static
+ unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr,
+ struct channel *channel,
+- struct channel *gr1ch, int mode_extension)
++ struct channel *gr1ch, int mode_extension,
++ unsigned int bits_left, unsigned int *part2_length)
+ {
+ struct mad_bitptr start;
+ unsigned int scalefac_compress, index, slen[4], part, n, i;
+@@ -644,8 +645,12 @@ unsigned int III_scalefactors_lsf(struct
+
+ n = 0;
+ for (part = 0; part < 4; ++part) {
+- for (i = 0; i < nsfb[part]; ++i)
++ for (i = 0; i < nsfb[part]; ++i) {
++ if (bits_left < slen[part])
++ return MAD_ERROR_BADSCFSI;
+ channel->scalefac[n++] = mad_bit_read(ptr, slen[part]);
++ bits_left -= slen[part];
++ }
+ }
+
+ while (n < 39)
+@@ -690,7 +695,10 @@ unsigned int III_scalefactors_lsf(struct
+ max = (1 << slen[part]) - 1;
+
+ for (i = 0; i < nsfb[part]; ++i) {
++ if (bits_left < slen[part])
++ return MAD_ERROR_BADSCFSI;
+ is_pos = mad_bit_read(ptr, slen[part]);
++ bits_left -= slen[part];
+
+ channel->scalefac[n] = is_pos;
+ gr1ch->scalefac[n++] = (is_pos == max);
+@@ -703,7 +711,8 @@ unsigned int III_scalefactors_lsf(struct
+ }
+ }
+
+- return mad_bit_length(&start, ptr);
++ *part2_length = mad_bit_length(&start, ptr);
++ return MAD_ERROR_NONE;
+ }
+
+ /*
+@@ -712,7 +721,8 @@ unsigned int III_scalefactors_lsf(struct
+ */
+ static
+ unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel,
+- struct channel const *gr0ch, unsigned int scfsi)
++ struct channel const *gr0ch, unsigned int scfsi,
++ unsigned int bits_left, unsigned int *part2_length)
+ {
+ struct mad_bitptr start;
+ unsigned int slen1, slen2, sfbi;
+@@ -728,12 +738,20 @@ unsigned int III_scalefactors(struct mad
+ sfbi = 0;
+
+ nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3;
+- while (nsfb--)
++ while (nsfb--) {
++ if (bits_left < slen1)
++ return MAD_ERROR_BADSCFSI;
+ channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1);
++ bits_left -= slen1;
++ }
+
+ nsfb = 6 * 3;
+- while (nsfb--)
++ while (nsfb--) {
++ if (bits_left < slen2)
++ return MAD_ERROR_BADSCFSI;
+ channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2);
++ bits_left -= slen2;
++ }
+
+ nsfb = 1 * 3;
+ while (nsfb--)
+@@ -745,8 +763,12 @@ unsigned int III_scalefactors(struct mad
+ channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
+ }
+ else {
+- for (sfbi = 0; sfbi < 6; ++sfbi)
++ for (sfbi = 0; sfbi < 6; ++sfbi) {
++ if (bits_left < slen1)
++ return MAD_ERROR_BADSCFSI;
+ channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
++ bits_left -= slen1;
++ }
+ }
+
+ if (scfsi & 0x4) {
+@@ -754,8 +776,12 @@ unsigned int III_scalefactors(struct mad
+ channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
+ }
+ else {
+- for (sfbi = 6; sfbi < 11; ++sfbi)
++ for (sfbi = 6; sfbi < 11; ++sfbi) {
++ if (bits_left < slen1)
++ return MAD_ERROR_BADSCFSI;
+ channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
++ bits_left -= slen1;
++ }
+ }
+
+ if (scfsi & 0x2) {
+@@ -763,8 +789,12 @@ unsigned int III_scalefactors(struct mad
+ channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
+ }
+ else {
+- for (sfbi = 11; sfbi < 16; ++sfbi)
++ for (sfbi = 11; sfbi < 16; ++sfbi) {
++ if (bits_left < slen2)
++ return MAD_ERROR_BADSCFSI;
+ channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
++ bits_left -= slen2;
++ }
+ }
+
+ if (scfsi & 0x1) {
+@@ -772,14 +802,19 @@ unsigned int III_scalefactors(struct mad
+ channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
+ }
+ else {
+- for (sfbi = 16; sfbi < 21; ++sfbi)
++ for (sfbi = 16; sfbi < 21; ++sfbi) {
++ if (bits_left < slen2)
++ return MAD_ERROR_BADSCFSI;
+ channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
++ bits_left -= slen2;
++ }
+ }
+
+ channel->scalefac[21] = 0;
+ }
+
+- return mad_bit_length(&start, ptr);
++ *part2_length = mad_bit_length(&start, ptr);
++ return MAD_ERROR_NONE;
+ }
+
+ /*
+@@ -933,19 +968,17 @@ static
+ enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576],
+ struct channel *channel,
+ unsigned char const *sfbwidth,
+- unsigned int part2_length)
++ signed int part3_length)
+ {
+ signed int exponents[39], exp;
+ signed int const *expptr;
+ struct mad_bitptr peek;
+- signed int bits_left, cachesz;
++ signed int bits_left, cachesz, fakebits;
+ register mad_fixed_t *xrptr;
+ mad_fixed_t const *sfbound;
+ register unsigned long bitcache;
+
+- bits_left = (signed) channel->part2_3_length - (signed) part2_length;
+- if (bits_left < 0)
+- return MAD_ERROR_BADPART3LEN;
++ bits_left = part3_length;
+
+ III_exponents(channel, sfbwidth, exponents);
+
+@@ -956,8 +989,12 @@ enum mad_error III_huffdecode(struct mad
+ cachesz = mad_bit_bitsleft(&peek);
+ cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7;
+
++ if (bits_left < cachesz) {
++ cachesz = bits_left;
++ }
+ bitcache = mad_bit_read(&peek, cachesz);
+ bits_left -= cachesz;
++ fakebits = 0;
+
+ xrptr = &xr[0];
+
+@@ -986,7 +1023,7 @@ enum mad_error III_huffdecode(struct mad
+
+ big_values = channel->big_values;
+
+- while (big_values-- && cachesz + bits_left > 0) {
++ while (big_values-- && cachesz + bits_left - fakebits > 0) {
+ union huffpair const *pair;
+ unsigned int clumpsz, value;
+ register mad_fixed_t requantized;
+@@ -1023,10 +1060,19 @@ enum mad_error III_huffdecode(struct mad
+ unsigned int bits;
+
+ bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7;
++ if (bits_left < bits) {
++ bits = bits_left;
++ }
+ bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
+ cachesz += bits;
+ bits_left -= bits;
+ }
++ if (cachesz < 21) {
++ unsigned int bits = 21 - cachesz;
++ bitcache <<= bits;
++ cachesz += bits;
++ fakebits += bits;
++ }
+
+ /* hcod (0..19) */
+
+@@ -1041,6 +1087,8 @@ enum mad_error III_huffdecode(struct mad
+ }
+
+ cachesz -= pair->value.hlen;
++ if (cachesz < fakebits)
++ return MAD_ERROR_BADHUFFDATA;
+
+ if (linbits) {
+ /* x (0..14) */
+@@ -1054,10 +1102,15 @@ enum mad_error III_huffdecode(struct mad
+
+ case 15:
+ if (cachesz < linbits + 2) {
+- bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
+- cachesz += 16;
+- bits_left -= 16;
++ unsigned int bits = 16;
++ if (bits_left < 16)
++ bits = bits_left;
++ bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
++ cachesz += bits;
++ bits_left -= bits;
+ }
++ if (cachesz - fakebits < linbits)
++ return MAD_ERROR_BADHUFFDATA;
+
+ value += MASK(bitcache, cachesz, linbits);
+ cachesz -= linbits;
+@@ -1074,6 +1127,8 @@ enum mad_error III_huffdecode(struct mad
+ }
+
+ x_final:
++ if (cachesz - fakebits < 1)
++ return MAD_ERROR_BADHUFFDATA;
+ xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
+ -requantized : requantized;
+ }
+@@ -1089,10 +1144,15 @@ enum mad_error III_huffdecode(struct mad
+
+ case 15:
+ if (cachesz < linbits + 1) {
+- bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
+- cachesz += 16;
+- bits_left -= 16;
++ unsigned int bits = 16;
++ if (bits_left < 16)
++ bits = bits_left;
++ bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
++ cachesz += bits;
++ bits_left -= bits;
+ }
++ if (cachesz - fakebits < linbits)
++ return MAD_ERROR_BADHUFFDATA;
+
+ value += MASK(bitcache, cachesz, linbits);
+ cachesz -= linbits;
+@@ -1109,6 +1169,8 @@ enum mad_error III_huffdecode(struct mad
+ }
+
+ y_final:
++ if (cachesz - fakebits < 1)
++ return MAD_ERROR_BADHUFFDATA;
+ xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
+ -requantized : requantized;
+ }
+@@ -1128,6 +1190,8 @@ enum mad_error III_huffdecode(struct mad
+ requantized = reqcache[value] = III_requantize(value, exp);
+ }
+
++ if (cachesz - fakebits < 1)
++ return MAD_ERROR_BADHUFFDATA;
+ xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
+ -requantized : requantized;
+ }
+@@ -1146,6 +1210,8 @@ enum mad_error III_huffdecode(struct mad
+ requantized = reqcache[value] = III_requantize(value, exp);
+ }
+
++ if (cachesz - fakebits < 1)
++ return MAD_ERROR_BADHUFFDATA;
+ xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
+ -requantized : requantized;
+ }
+@@ -1155,9 +1221,6 @@ enum mad_error III_huffdecode(struct mad
+ }
+ }
+
+- if (cachesz + bits_left < 0)
+- return MAD_ERROR_BADHUFFDATA; /* big_values overrun */
+-
+ /* count1 */
+ {
+ union huffquad const *table;
+@@ -1167,15 +1230,24 @@ enum mad_error III_huffdecode(struct mad
+
+ requantized = III_requantize(1, exp);
+
+- while (cachesz + bits_left > 0 && xrptr <= &xr[572]) {
++ while (cachesz + bits_left - fakebits > 0 && xrptr <= &xr[572]) {
+ union huffquad const *quad;
+
+ /* hcod (1..6) */
+
+ if (cachesz < 10) {
+- bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
+- cachesz += 16;
+- bits_left -= 16;
++ unsigned int bits = 16;
++ if (bits_left < 16)
++ bits = bits_left;
++ bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
++ cachesz += bits;
++ bits_left -= bits;
++ }
++ if (cachesz < 10) {
++ unsigned int bits = 10 - cachesz;
++ bitcache <<= bits;
++ cachesz += bits;
++ fakebits += bits;
+ }
+
+ quad = &table[MASK(bitcache, cachesz, 4)];
+@@ -1188,6 +1260,11 @@ enum mad_error III_huffdecode(struct mad
+ MASK(bitcache, cachesz, quad->ptr.bits)];
+ }
+
++ if (cachesz - fakebits < quad->value.hlen + quad->value.v
++ + quad->value.w + quad->value.x + quad->value.y)
++ /* We don't have enough bits to read one more entry, consider them
++ * stuffing bits. */
++ break;
+ cachesz -= quad->value.hlen;
+
+ if (xrptr == sfbound) {
+@@ -1236,22 +1313,8 @@ enum mad_error III_huffdecode(struct mad
+
+ xrptr += 2;
+ }
+-
+- if (cachesz + bits_left < 0) {
+-# if 0 && defined(DEBUG)
+- fprintf(stderr, "huffman count1 overrun (%d bits)\n",
+- -(cachesz + bits_left));
+-# endif
+-
+- /* technically the bitstream is misformatted, but apparently
+- some encoders are just a bit sloppy with stuffing bits */
+-
+- xrptr -= 4;
+- }
+ }
+
+- assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);
+-
+ # if 0 && defined(DEBUG)
+ if (bits_left < 0)
+ fprintf(stderr, "read %d bits too many\n", -bits_left);
+@@ -2348,10 +2411,11 @@ void III_freqinver(mad_fixed_t sample[18
+ */
+ static
+ enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame,
+- struct sideinfo *si, unsigned int nch)
++ struct sideinfo *si, unsigned int nch, unsigned int md_len)
+ {
+ struct mad_header *header = &frame->header;
+ unsigned int sfreqi, ngr, gr;
++ int bits_left = md_len * CHAR_BIT;
+
+ {
+ unsigned int sfreq;
+@@ -2383,6 +2447,7 @@ enum mad_error III_decode(struct mad_bit
+ for (ch = 0; ch < nch; ++ch) {
+ struct channel *channel = &granule->ch[ch];
+ unsigned int part2_length;
++ unsigned int part3_length;
+
+ sfbwidth[ch] = sfbwidth_table[sfreqi].l;
+ if (channel->block_type == 2) {
+@@ -2391,18 +2456,30 @@ enum mad_error III_decode(struct mad_bit
+ }
+
+ if (header->flags & MAD_FLAG_LSF_EXT) {
+- part2_length = III_scalefactors_lsf(ptr, channel,
++ error = III_scalefactors_lsf(ptr, channel,
+ ch == 0 ? 0 : &si->gr[1].ch[1],
+- header->mode_extension);
++ header->mode_extension, bits_left, &part2_length);
+ }
+ else {
+- part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],
+- gr == 0 ? 0 : si->scfsi[ch]);
++ error = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],
++ gr == 0 ? 0 : si->scfsi[ch], bits_left, &part2_length);
+ }
++ if (error)
++ return error;
++
++ bits_left -= part2_length;
+
+- error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length);
++ if (part2_length > channel->part2_3_length)
++ return MAD_ERROR_BADPART3LEN;
++
++ part3_length = channel->part2_3_length - part2_length;
++ if (part3_length > bits_left)
++ return MAD_ERROR_BADPART3LEN;
++
++ error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part3_length);
+ if (error)
+ return error;
++ bits_left -= part3_length;
+ }
+
+ /* joint stereo processing */
+@@ -2519,11 +2596,13 @@ int mad_layer_III(struct mad_stream *str
+ unsigned int nch, priv_bitlen, next_md_begin = 0;
+ unsigned int si_len, data_bitlen, md_len;
+ unsigned int frame_space, frame_used, frame_free;
+- struct mad_bitptr ptr;
++ struct mad_bitptr ptr, bufend_ptr;
+ struct sideinfo si;
+ enum mad_error error;
+ int result = 0;
+
++ mad_bit_init(&bufend_ptr, stream->bufend);
++
+ /* allocate Layer III dynamic structures */
+
+ if (stream->main_data == 0) {
+@@ -2587,14 +2666,15 @@ int mad_layer_III(struct mad_stream *str
+ unsigned long header;
+
+ mad_bit_init(&peek, stream->next_frame);
++ if (mad_bit_length(&peek, &bufend_ptr) >= 57) {
++ header = mad_bit_read(&peek, 32);
++ if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) {
++ if (!(header & 0x00010000L)) /* protection_bit */
++ mad_bit_skip(&peek, 16); /* crc_check */
+
+- header = mad_bit_read(&peek, 32);
+- if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) {
+- if (!(header & 0x00010000L)) /* protection_bit */
+- mad_bit_skip(&peek, 16); /* crc_check */
+-
+- next_md_begin =
+- mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8);
++ next_md_begin =
++ mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8);
++ }
+ }
+
+ mad_bit_finish(&peek);
+@@ -2653,7 +2733,7 @@ int mad_layer_III(struct mad_stream *str
+ /* decode main_data */
+
+ if (result == 0) {
+- error = III_decode(&ptr, frame, &si, nch);
++ error = III_decode(&ptr, frame, &si, nch, md_len);
+ if (error) {
+ stream->error = error;
+ result = -1;
diff --git a/package/libmad/libmad.mk b/package/libmad/libmad.mk
index 611f13eb67..d69adcc1d5 100644
--- a/package/libmad/libmad.mk
+++ b/package/libmad/libmad.mk
@@ -12,6 +12,12 @@ LIBMAD_INSTALL_STAGING = YES
LIBMAD_LICENSE = GPL-2.0+
LIBMAD_LICENSE_FILES = COPYING
+# 0004-md_size.patch
+LIBMAD_IGNORE_CVES += CVE-2017-8372 CVE-2017-8373
+
+# 0005-length-check.patch
+LIBMAD_IGNORE_CVES += CVE-2017-8374
+
# Force autoreconf to be able to use a more recent libtool script, that
# is able to properly behave in the face of a missing C++ compiler.
LIBMAD_AUTORECONF = YES
--
2.52.0
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian
2026-02-04 13:18 [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian Thomas Perale via buildroot
` (2 preceding siblings ...)
2026-02-04 13:18 ` [Buildroot] [PATCH 4/4] package/libmad: add patch for CVE-2017-837{2, 3, 4} Thomas Perale via buildroot
@ 2026-05-29 9:45 ` Thomas Petazzoni via buildroot
2026-06-05 12:49 ` Thomas Perale via buildroot
4 siblings, 0 replies; 9+ messages in thread
From: Thomas Petazzoni via buildroot @ 2026-05-29 9:45 UTC (permalink / raw)
To: Thomas Perale; +Cc: buildroot, Luca Ceresoli
Hello Thomas,
On Wed, Feb 04, 2026 at 02:18:30PM +0100, Thomas Perale via buildroot wrote:
> In Buildroot there are multiple way to apply patches on a package [1]
>
> - Adding `.patch` file in the package directory.
> - Define `<pkg>_PATCH` variable with the location of the patch tar.gz.
> It used to download Debian patches tarball.
> - Implement custom patching logic with `PRE`/`POST` patches hooks.
>
> To make the CycloneDX SBOM generation not dependant on downloading the
> packages, the two last options have the downside of not appearing on the
> generated SBOM.
>
> The unzip package is downloading a tarball from the Debian mirror with
> the `<pkg>_PATCH` method [2].
>
> To improve the tracking of the patched vulnerabilities for the unzip
> package this commit import the patches previously downloaded with the
> `_PATCH` variable in the Buildroot tree.
> This allows to add the `CVE:` trailer [3] on the patches that fix
> vulnerabilities to better track which patch is fixing the vulnerability.
>
> [1] https://buildroot.org/downloads/manual/manual.html#patch-policy
> [2] https://snapshot.debian.org/archive/debian/20250311T215724Z/pool/main/u/unzip/unzip_6.0-29.debian.tar.xz
> [3] 1167d0ff3d docs/manual: mention CVE trailer
>
> Signed-off-by: Thomas Perale <thomas.perale@mind.be>
Thanks a lot, entire series applied to master.
Actually PATCH 3/4 is fixing a pretty nasty bug: we were pretending
that some of the CVEs were fixed by patches, but we were not actually
applying those patches, so the CVEs were not actually fixed.
Thomas
--
Thomas Petazzoni, co-owner and CEO, Bootlin
Embedded Linux and Kernel engineering and training
https://bootlin.com
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Buildroot] [PATCH 2/4] package/heirloom-mailx: import patches from Debian
2026-02-04 13:18 ` [Buildroot] [PATCH 2/4] package/heirloom-mailx: " Thomas Perale via buildroot
@ 2026-06-05 12:49 ` Thomas Perale via buildroot
0 siblings, 0 replies; 9+ messages in thread
From: Thomas Perale via buildroot @ 2026-06-05 12:49 UTC (permalink / raw)
To: Thomas Perale; +Cc: buildroot
In reply of:
> In Buildroot there are multiple way to apply patches on a package [1]
>
> - Adding `.patch` file in the package directory.
> - Define `<pkg>_PATCH` variable with the location of the patch tar.gz.
> It used to download Debian patches tarball.
> - Implement custom patching logic with `PRE`/`POST` patches hooks.
>
> To make the CycloneDX SBOM generation not dependant on downloading the
> packages, the two last options have the downside of not appearing on the
> generated SBOM.
>
> The heirloom-mailx package is downloading a tarball from the Debian
> mirror with the `<pkg>_PATCH` method [2].
>
> To improve the tracking of the patched vulnerabilities for the
> heirloom-mailx package this commit import the patches previously
> downloaded with the `_PATCH` variable in the Buildroot tree. This allows
> to add the `CVE:` trailer [3] on the patches that fix vulnerabilities to
> better track which patch is fixing the vulnerability.
>
> [1] https://buildroot.org/downloads/manual/manual.html#patch-policy
> [2] http://snapshot.debian.org/archive/debian/20150815T155609Z/pool/main/h/heirloom-mailx/heirloom-mailx_12.5-5.debian.tar.xz
> [3] 1167d0ff3d docs/manual: mention CVE trailer
>
> Signed-off-by: Thomas Perale <thomas.perale@mind.be>
Applied to 2025.02.x & 2026.02.x. Thanks
> ---
> .checkpackageignore | 1 -
> ...k-symbol-optopt-to-fix-FTBFS-on-mips.patch | 57 +++++++++
> ...-support-since-it-is-no-longer-suppo.patch | 39 ++++++
> ...-warning-warning-macro-N-not-defined.patch | 23 ++++
> ...0011-outof-Introduce-expandaddr-flag.patch | 69 +++++++++++
> ...ption-processing-for-email-addresses.patch | 77 ++++++++++++
> ...onditionally-require-wordexp-support.patch | 111 ++++++++++++++++++
> ...bname-Invoke-wordexp-with-WRDE_NOCMD.patch | 29 +++++
> .../0015-usr-sbin-sendmail.patch | 36 ++++++
> ....patch => 0101-fix-libressl-support.patch} | 1 +
> package/heirloom-mailx/heirloom-mailx.mk | 5 +-
> 11 files changed, 444 insertions(+), 4 deletions(-)
> create mode 100644 package/heirloom-mailx/0001-Don-t-reuse-weak-symbol-optopt-to-fix-FTBFS-on-mips.patch
> create mode 100644 package/heirloom-mailx/0002-Patched-out-SSL2-support-since-it-is-no-longer-suppo.patch
> create mode 100644 package/heirloom-mailx/0003-Fixed-Lintian-warning-warning-macro-N-not-defined.patch
> create mode 100644 package/heirloom-mailx/0011-outof-Introduce-expandaddr-flag.patch
> create mode 100644 package/heirloom-mailx/0012-unpack-Disable-option-processing-for-email-addresses.patch
> create mode 100644 package/heirloom-mailx/0013-fio.c-Unconditionally-require-wordexp-support.patch
> create mode 100644 package/heirloom-mailx/0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch
> create mode 100644 package/heirloom-mailx/0015-usr-sbin-sendmail.patch
> rename package/heirloom-mailx/{0001-fix-libressl-support.patch => 0101-fix-libressl-support.patch} (99%)
>
> diff --git a/.checkpackageignore b/.checkpackageignore
> index 8e0a283441..340e353ab6 100644
> --- a/.checkpackageignore
> +++ b/.checkpackageignore
> @@ -437,7 +437,6 @@ package/gutenprint/0002-cups-support-replaces-static-with-static-libtool-lib.pat
> package/harfbuzz/0001-meson.build-check-for-pthread.h.patch lib_patch.Upstream
> package/haserl/0001-add-haserl_lualib.inc.patch lib_patch.Upstream
> package/haveged/S21haveged Shellcheck lib_sysv.Variables
> -package/heirloom-mailx/0001-fix-libressl-support.patch lib_patch.Upstream
> package/hplip/0001-build-use-pkg-config-to-discover-libusb.patch lib_patch.Upstream
> package/hplip/0002-configure.in-fix-AM_INIT_AUTOMAKE-call.patch lib_patch.Upstream
> package/i2pd/S99i2pd Shellcheck lib_sysv.Indent lib_sysv.Variables
> diff --git a/package/heirloom-mailx/0001-Don-t-reuse-weak-symbol-optopt-to-fix-FTBFS-on-mips.patch b/package/heirloom-mailx/0001-Don-t-reuse-weak-symbol-optopt-to-fix-FTBFS-on-mips.patch
> new file mode 100644
> index 0000000000..967344159e
> --- /dev/null
> +++ b/package/heirloom-mailx/0001-Don-t-reuse-weak-symbol-optopt-to-fix-FTBFS-on-mips.patch
> @@ -0,0 +1,57 @@
> +From: Luk Claes <luk@debian.org>
> +Date: Sat, 4 Jul 2009 10:54:53 +0200
> +Subject: Don't reuse weak symbol optopt to fix FTBFS on mips*
> +
> +Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0001-Don-t-reuse-weak-symbol-optopt-to-fix-FTBFS-on-mips.patch/
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> + getopt.c | 10 +++++-----
> + 1 file changed, 5 insertions(+), 5 deletions(-)
> +
> +diff --git a/getopt.c b/getopt.c
> +index 83ce628..82e983c 100644
> +--- a/getopt.c
> ++++ b/getopt.c
> +@@ -43,7 +43,7 @@ typedef int ssize_t;
> + char *optarg;
> + int optind = 1;
> + int opterr = 1;
> +-int optopt;
> ++int optoptc;
> +
> + static void
> + error(const char *s, int c)
> +@@ -69,7 +69,7 @@ error(const char *s, int c)
> + *bp++ = *s++;
> + while (*msg)
> + *bp++ = *msg++;
> +- *bp++ = optopt;
> ++ *bp++ = optoptc;
> + *bp++ = '\n';
> + write(2, buf, bp - buf);
> + ac_free(buf);
> +@@ -101,13 +101,13 @@ getopt(int argc, char *const argv[], const char *optstring)
> + }
> + curp = &argv[optind][1];
> + }
> +- optopt = curp[0] & 0377;
> ++ optoptc = curp[0] & 0377;
> + while (optstring[0]) {
> + if (optstring[0] == ':') {
> + optstring++;
> + continue;
> + }
> +- if ((optstring[0] & 0377) == optopt) {
> ++ if ((optstring[0] & 0377) == optoptc) {
> + if (optstring[1] == ':') {
> + if (curp[1] != '\0') {
> + optarg = (char *)&curp[1];
> +@@ -127,7 +127,7 @@ getopt(int argc, char *const argv[], const char *optstring)
> + optind++;
> + optarg = 0;
> + }
> +- return optopt;
> ++ return optoptc;
> + }
> + optstring++;
> + }
> diff --git a/package/heirloom-mailx/0002-Patched-out-SSL2-support-since-it-is-no-longer-suppo.patch b/package/heirloom-mailx/0002-Patched-out-SSL2-support-since-it-is-no-longer-suppo.patch
> new file mode 100644
> index 0000000000..156aea7a37
> --- /dev/null
> +++ b/package/heirloom-mailx/0002-Patched-out-SSL2-support-since-it-is-no-longer-suppo.patch
> @@ -0,0 +1,39 @@
> +From: Hilko Bengen <bengen@debian.org>
> +Date: Wed, 27 Apr 2011 00:18:42 +0200
> +Subject: Patched out SSL2 support since it is no longer supported by OpenSSL.
> +
> +Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0002-Patched-out-SSL2-support-since-it-is-no-longer-suppo.patch/
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> + mailx.1 | 2 +-
> + openssl.c | 4 +---
> + 2 files changed, 2 insertions(+), 4 deletions(-)
> +
> +diff --git a/mailx.1 b/mailx.1
> +index 417ea04..a02e430 100644
> +--- a/mailx.1
> ++++ b/mailx.1
> +@@ -3575,7 +3575,7 @@ Only applicable if SSL/TLS support is built using OpenSSL.
> + .TP
> + .B ssl-method
> + Selects a SSL/TLS protocol version;
> +-valid values are `ssl2', `ssl3', and `tls1'.
> ++valid values are `ssl3', and `tls1'.
> + If unset, the method is selected automatically,
> + if possible.
> + .TP
> +diff --git a/openssl.c b/openssl.c
> +index b4e33fc..44fe4e5 100644
> +--- a/openssl.c
> ++++ b/openssl.c
> +@@ -216,9 +216,7 @@ ssl_select_method(const char *uhp)
> +
> + cp = ssl_method_string(uhp);
> + if (cp != NULL) {
> +- if (equal(cp, "ssl2"))
> +- method = SSLv2_client_method();
> +- else if (equal(cp, "ssl3"))
> ++ if (equal(cp, "ssl3"))
> + method = SSLv3_client_method();
> + else if (equal(cp, "tls1"))
> + method = TLSv1_client_method();
> diff --git a/package/heirloom-mailx/0003-Fixed-Lintian-warning-warning-macro-N-not-defined.patch b/package/heirloom-mailx/0003-Fixed-Lintian-warning-warning-macro-N-not-defined.patch
> new file mode 100644
> index 0000000000..724f7c8b81
> --- /dev/null
> +++ b/package/heirloom-mailx/0003-Fixed-Lintian-warning-warning-macro-N-not-defined.patch
> @@ -0,0 +1,23 @@
> +From: Hilko Bengen <bengen@debian.org>
> +Date: Sat, 14 Apr 2012 20:22:43 +0200
> +Subject: Fixed Lintian warning (warning: macro `N' not defined)
> +
> +Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0003-Fixed-Lintian-warning-warning-macro-N-not-defined.patch/
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> + mailx.1 | 2 +-
> + 1 file changed, 1 insertion(+), 1 deletion(-)
> +
> +diff --git a/mailx.1 b/mailx.1
> +index a02e430..b0723bd 100644
> +--- a/mailx.1
> ++++ b/mailx.1
> +@@ -3781,7 +3781,7 @@ you could examine the first message by giving the command:
> + .sp
> + .fi
> + which might cause
> +-.N mailx
> ++.I mailx
> + to respond with, for example:
> + .nf
> + .sp
> diff --git a/package/heirloom-mailx/0011-outof-Introduce-expandaddr-flag.patch b/package/heirloom-mailx/0011-outof-Introduce-expandaddr-flag.patch
> new file mode 100644
> index 0000000000..7825b788bc
> --- /dev/null
> +++ b/package/heirloom-mailx/0011-outof-Introduce-expandaddr-flag.patch
> @@ -0,0 +1,69 @@
> +From 9984ae5cb0ea0d61df1612b06952a61323c083d9 Mon Sep 17 00:00:00 2001
> +From: Florian Weimer <fweimer@redhat.com>
> +Date: Mon, 17 Nov 2014 11:13:38 +0100
> +Subject: [PATCH] outof: Introduce expandaddr flag
> +
> +Document that address expansion is disabled unless the expandaddr
> +binary option is set.
> +
> +This has been assigned CVE-2014-7844 for BSD mailx, but it is not
> +a vulnerability in Heirloom mailx because this feature was documented.
> +
> +CVE: CVE-2014-7844
> +Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0011-outof-Introduce-expandaddr-flag.patch/
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> + mailx.1 | 14 ++++++++++++++
> + names.c | 3 +++
> + 2 files changed, 17 insertions(+)
> +
> +diff --git a/mailx.1 b/mailx.1
> +index 70a7859..22a171b 100644
> +--- a/mailx.1
> ++++ b/mailx.1
> +@@ -656,6 +656,14 @@ but any reply returned to the machine
> + will have the system wide alias expanded
> + as all mail goes through sendmail.
> + .SS "Recipient address specifications"
> ++If the
> ++.I expandaddr
> ++option is not set (the default), recipient addresses must be names of
> ++local mailboxes or Internet mail addresses.
> ++.PP
> ++If the
> ++.I expandaddr
> ++option is set, the following rules apply:
> + When an address is used to name a recipient
> + (in any of To, Cc, or Bcc),
> + names of local mail folders
> +@@ -2391,6 +2399,12 @@ and exits immediately.
> + If this option is set,
> + \fImailx\fR starts even with an empty mailbox.
> + .TP
> ++.B expandaddr
> ++Causes
> ++.I mailx
> ++to expand message recipient addresses, as explained in the section,
> ++Recipient address specifications.
> ++.TP
> + .B flipr
> + Exchanges the
> + .I Respond
> +diff --git a/names.c b/names.c
> +index 66e976b..c69560f 100644
> +--- a/names.c
> ++++ b/names.c
> +@@ -268,6 +268,9 @@ outof(struct name *names, FILE *fo, struct header *hp)
> + FILE *fout, *fin;
> + int ispipe;
> +
> ++ if (value("expandaddr") == NULL)
> ++ return names;
> ++
> + top = names;
> + np = names;
> + time(&now);
> +--
> +1.9.3
> +
> +
> diff --git a/package/heirloom-mailx/0012-unpack-Disable-option-processing-for-email-addresses.patch b/package/heirloom-mailx/0012-unpack-Disable-option-processing-for-email-addresses.patch
> new file mode 100644
> index 0000000000..64a1e7f246
> --- /dev/null
> +++ b/package/heirloom-mailx/0012-unpack-Disable-option-processing-for-email-addresses.patch
> @@ -0,0 +1,77 @@
> +From e34e2ac67b80497080ebecccec40c3b61456167d Mon Sep 17 00:00:00 2001
> +From: Florian Weimer <fweimer@redhat.com>
> +Date: Mon, 17 Nov 2014 11:14:06 +0100
> +Subject: [PATCH] unpack: Disable option processing for email addresses
> + when calling sendmail
> +
> +Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0012-unpack-Disable-option-processing-for-email-addresses.patch/
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> + extern.h | 2 +-
> + names.c | 8 ++++++--
> + sendout.c | 2 +-
> + 3 files changed, 8 insertions(+), 4 deletions(-)
> +
> +diff --git a/extern.h b/extern.h
> +index 6b85ba0..8873fe8 100644
> +--- a/extern.h
> ++++ b/extern.h
> +@@ -396,7 +396,7 @@ struct name *outof(struct name *names, FILE *fo, struct header *hp);
> + int is_fileaddr(char *name);
> + struct name *usermap(struct name *names);
> + struct name *cat(struct name *n1, struct name *n2);
> +-char **unpack(struct name *np);
> ++char **unpack(struct name *smopts, struct name *np);
> + struct name *elide(struct name *names);
> + int count(struct name *np);
> + struct name *delete_alternates(struct name *np);
> +diff --git a/names.c b/names.c
> +index c69560f..45bbaed 100644
> +--- a/names.c
> ++++ b/names.c
> +@@ -549,7 +549,7 @@ cat(struct name *n1, struct name *n2)
> + * Return an error if the name list won't fit.
> + */
> + char **
> +-unpack(struct name *np)
> ++unpack(struct name *smopts, struct name *np)
> + {
> + char **ap, **top;
> + struct name *n;
> +@@ -564,7 +564,7 @@ unpack(struct name *np)
> + * the terminating 0 pointer. Additional spots may be needed
> + * to pass along -f to the host mailer.
> + */
> +- extra = 2;
> ++ extra = 3 + count(smopts);
> + extra++;
> + metoo = value("metoo") != NULL;
> + if (metoo)
> +@@ -581,6 +581,10 @@ unpack(struct name *np)
> + *ap++ = "-m";
> + if (verbose)
> + *ap++ = "-v";
> ++ for (; smopts != NULL; smopts = smopts->n_flink)
> ++ if ((smopts->n_type & GDEL) == 0)
> ++ *ap++ = smopts->n_name;
> ++ *ap++ = "--";
> + for (; n != NULL; n = n->n_flink)
> + if ((n->n_type & GDEL) == 0)
> + *ap++ = n->n_name;
> +diff --git a/sendout.c b/sendout.c
> +index 7b7f2eb..c52f15d 100644
> +--- a/sendout.c
> ++++ b/sendout.c
> +@@ -835,7 +835,7 @@ start_mta(struct name *to, struct name *mailargs, FILE *input,
> + #endif /* HAVE_SOCKETS */
> +
> + if ((smtp = value("smtp")) == NULL) {
> +- args = unpack(cat(mailargs, to));
> ++ args = unpack(mailargs, to);
> + if (debug || value("debug")) {
> + printf(catgets(catd, CATSET, 181,
> + "Sendmail arguments:"));
> +--
> +1.9.3
> +
> +
> diff --git a/package/heirloom-mailx/0013-fio.c-Unconditionally-require-wordexp-support.patch b/package/heirloom-mailx/0013-fio.c-Unconditionally-require-wordexp-support.patch
> new file mode 100644
> index 0000000000..6938daec12
> --- /dev/null
> +++ b/package/heirloom-mailx/0013-fio.c-Unconditionally-require-wordexp-support.patch
> @@ -0,0 +1,111 @@
> +From 2bae8ecf04ec2ba6bb9f0af5b80485dd0edb427d Mon Sep 17 00:00:00 2001
> +From: Florian Weimer <fweimer@redhat.com>
> +Date: Mon, 17 Nov 2014 12:48:25 +0100
> +Subject: [PATCH] fio.c: Unconditionally require wordexp support
> +
> +Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0013-fio.c-Unconditionally-require-wordexp-support.patch/
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> + fio.c | 67 +++++--------------------------------------------------------------
> + 1 file changed, 5 insertions(+), 62 deletions(-)
> +
> +diff --git a/fio.c b/fio.c
> +index 65e8f10..1529236 100644
> +--- a/fio.c
> ++++ b/fio.c
> +@@ -43,12 +43,15 @@ static char sccsid[] = "@(#)fio.c 2.76 (gritter) 9/16/09";
> + #endif /* not lint */
> +
> + #include "rcv.h"
> ++
> ++#ifndef HAVE_WORDEXP
> ++#error wordexp support is required
> ++#endif
> ++
> + #include <sys/stat.h>
> + #include <sys/file.h>
> + #include <sys/wait.h>
> +-#ifdef HAVE_WORDEXP
> + #include <wordexp.h>
> +-#endif /* HAVE_WORDEXP */
> + #include <unistd.h>
> +
> + #if defined (USE_NSS)
> +@@ -481,7 +484,6 @@ next:
> + static char *
> + globname(char *name)
> + {
> +-#ifdef HAVE_WORDEXP
> + wordexp_t we;
> + char *cp;
> + sigset_t nset;
> +@@ -527,65 +529,6 @@ globname(char *name)
> + }
> + wordfree(&we);
> + return cp;
> +-#else /* !HAVE_WORDEXP */
> +- char xname[PATHSIZE];
> +- char cmdbuf[PATHSIZE]; /* also used for file names */
> +- int pid, l;
> +- char *cp, *shell;
> +- int pivec[2];
> +- extern int wait_status;
> +- struct stat sbuf;
> +-
> +- if (pipe(pivec) < 0) {
> +- perror("pipe");
> +- return name;
> +- }
> +- snprintf(cmdbuf, sizeof cmdbuf, "echo %s", name);
> +- if ((shell = value("SHELL")) == NULL)
> +- shell = SHELL;
> +- pid = start_command(shell, 0, -1, pivec[1], "-c", cmdbuf, NULL);
> +- if (pid < 0) {
> +- close(pivec[0]);
> +- close(pivec[1]);
> +- return NULL;
> +- }
> +- close(pivec[1]);
> +-again:
> +- l = read(pivec[0], xname, sizeof xname);
> +- if (l < 0) {
> +- if (errno == EINTR)
> +- goto again;
> +- perror("read");
> +- close(pivec[0]);
> +- return NULL;
> +- }
> +- close(pivec[0]);
> +- if (wait_child(pid) < 0 && WTERMSIG(wait_status) != SIGPIPE) {
> +- fprintf(stderr, catgets(catd, CATSET, 81,
> +- "\"%s\": Expansion failed.\n"), name);
> +- return NULL;
> +- }
> +- if (l == 0) {
> +- fprintf(stderr, catgets(catd, CATSET, 82,
> +- "\"%s\": No match.\n"), name);
> +- return NULL;
> +- }
> +- if (l == sizeof xname) {
> +- fprintf(stderr, catgets(catd, CATSET, 83,
> +- "\"%s\": Expansion buffer overflow.\n"), name);
> +- return NULL;
> +- }
> +- xname[l] = 0;
> +- for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--)
> +- ;
> +- cp[1] = '\0';
> +- if (strchr(xname, ' ') && stat(xname, &sbuf) < 0) {
> +- fprintf(stderr, catgets(catd, CATSET, 84,
> +- "\"%s\": Ambiguous.\n"), name);
> +- return NULL;
> +- }
> +- return savestr(xname);
> +-#endif /* !HAVE_WORDEXP */
> + }
> +
> + /*
> +--
> +1.9.3
> +
> +
> diff --git a/package/heirloom-mailx/0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch b/package/heirloom-mailx/0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch
> new file mode 100644
> index 0000000000..378b157d8a
> --- /dev/null
> +++ b/package/heirloom-mailx/0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch
> @@ -0,0 +1,29 @@
> +From 73fefa0c1ac70043ec84f2d8b8f9f683213f168d Mon Sep 17 00:00:00 2001
> +From: Florian Weimer <fweimer@redhat.com>
> +Date: Mon, 17 Nov 2014 13:11:32 +0100
> +Subject: [PATCH] globname: Invoke wordexp with WRDE_NOCMD (CVE-2004-2771)
> +
> +CVE: CVE-2004-2771
> +Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch/
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> + fio.c | 2 +-
> + 1 file changed, 1 insertion(+), 1 deletion(-)
> +
> +diff --git a/fio.c b/fio.c
> +index 1529236..774a204 100644
> +--- a/fio.c
> ++++ b/fio.c
> +@@ -497,7 +497,7 @@ globname(char *name)
> + sigemptyset(&nset);
> + sigaddset(&nset, SIGCHLD);
> + sigprocmask(SIG_BLOCK, &nset, NULL);
> +- i = wordexp(name, &we, 0);
> ++ i = wordexp(name, &we, WRDE_NOCMD);
> + sigprocmask(SIG_UNBLOCK, &nset, NULL);
> + switch (i) {
> + case 0:
> +--
> +1.9.3
> +
> +
> diff --git a/package/heirloom-mailx/0015-usr-sbin-sendmail.patch b/package/heirloom-mailx/0015-usr-sbin-sendmail.patch
> new file mode 100644
> index 0000000000..195b606c01
> --- /dev/null
> +++ b/package/heirloom-mailx/0015-usr-sbin-sendmail.patch
> @@ -0,0 +1,36 @@
> +Description: Sendmail is at /usr/sbin/sendmail
> + As per Debian Policy §11.6
> +Author: Ryan Kavanagh <rak@debian.org>
> +Origin: Debian
> +Forwarded: no
> +
> +Upstream: https://sources.debian.org/patches/heirloom-mailx/12.5-4/0015-usr-sbin-sendmail.patch/
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
> +Index: heirloom-mailx-12.5/Makefile
> +===================================================================
> +--- heirloom-mailx-12.5.orig/Makefile 2011-04-26 17:23:22.000000000 -0400
> ++++ heirloom-mailx-12.5/Makefile 2015-01-27 13:20:04.733542801 -0500
> +@@ -13,7 +13,7 @@
> +
> + MAILRC = $(SYSCONFDIR)/nail.rc
> + MAILSPOOL = /var/mail
> +-SENDMAIL = /usr/lib/sendmail
> ++SENDMAIL = /usr/sbin/sendmail
> +
> + DESTDIR =
> +
> +Index: heirloom-mailx-12.5/mailx.1
> +===================================================================
> +--- heirloom-mailx-12.5.orig/mailx.1 2015-01-27 13:18:49.000000000 -0500
> ++++ heirloom-mailx-12.5/mailx.1 2015-01-27 13:20:32.382336867 -0500
> +@@ -4922,7 +4922,7 @@
> + which just acts as a proxy.
> + .PP
> + \fIMailx\fR immediately contacts the SMTP server (or
> +-.IR \%/usr/lib/sendmail )
> ++.IR \%/usr/sbin/sendmail )
> + even when operating in
> + .I disconnected
> + mode.
> diff --git a/package/heirloom-mailx/0001-fix-libressl-support.patch b/package/heirloom-mailx/0101-fix-libressl-support.patch
> similarity index 99%
> rename from package/heirloom-mailx/0001-fix-libressl-support.patch
> rename to package/heirloom-mailx/0101-fix-libressl-support.patch
> index b54aaaf73c..25cc92d580 100644
> --- a/package/heirloom-mailx/0001-fix-libressl-support.patch
> +++ b/package/heirloom-mailx/0101-fix-libressl-support.patch
> @@ -10,6 +10,7 @@ heirloom-mailx has two small issues when compiling against LibreSSL:
> - SSLv3_client_method function is used (LibreSSL does not support SSLv3)
> Solution: "Guard" the code with #ifndef OPENSSL_NO_SSL3
>
> +Upstream: N/A
> Signed-off-by: Adam Duskett <aduskett@gmail.com>
> ---
> openssl.c | 7 +++++++
> diff --git a/package/heirloom-mailx/heirloom-mailx.mk b/package/heirloom-mailx/heirloom-mailx.mk
> index 063fccf5eb..075b5f6a59 100644
> --- a/package/heirloom-mailx/heirloom-mailx.mk
> +++ b/package/heirloom-mailx/heirloom-mailx.mk
> @@ -7,14 +7,13 @@
> HEIRLOOM_MAILX_VERSION = 12.5
> HEIRLOOM_MAILX_SOURCE = heirloom-mailx_$(HEIRLOOM_MAILX_VERSION).orig.tar.gz
> HEIRLOOM_MAILX_SITE = http://snapshot.debian.org/archive/debian/20150815T155609Z/pool/main/h/heirloom-mailx
> -HEIRLOOM_MAILX_PATCH = heirloom-mailx_$(HEIRLOOM_MAILX_VERSION)-5.debian.tar.xz
> HEIRLOOM_MAILX_LICENSE = BSD-4-Clause, Bellcore (base64), OpenVision (imap_gssapi), RSA Data Security (md5), Network Working Group (hmac), MPL-1.1 (nss)
> HEIRLOOM_MAILX_LICENSE_FILES = COPYING
> HEIRLOOM_MAILX_CPE_ID_VENDOR = heirloom
> HEIRLOOM_MAILX_CPE_ID_PRODUCT = mailx
> -# 0011-outof-Introduce-expandaddr-flag.patch in the Debian patches
> +# 0011-outof-Introduce-expandaddr-flag.patch
> HEIRLOOM_MAILX_IGNORE_CVES += CVE-2014-7844
> -# 0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch in the Debian patches
> +# 0014-globname-Invoke-wordexp-with-WRDE_NOCMD.patch
> HEIRLOOM_MAILX_IGNORE_CVES += CVE-2004-2771
>
> ifeq ($(BR2_PACKAGE_OPENSSL),y)
> --
> 2.52.0
>
> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Buildroot] [PATCH 4/4] package/libmad: add patch for CVE-2017-837{2, 3, 4}
2026-02-04 13:18 ` [Buildroot] [PATCH 4/4] package/libmad: add patch for CVE-2017-837{2, 3, 4} Thomas Perale via buildroot
@ 2026-06-05 12:49 ` Thomas Perale via buildroot
0 siblings, 0 replies; 9+ messages in thread
From: Thomas Perale via buildroot @ 2026-06-05 12:49 UTC (permalink / raw)
To: Thomas Perale; +Cc: buildroot
In reply of:
> The commit [1] introduced fixes for the following CVEs:
>
> - CVE-2017-8372: The mad_layer_III function in layer3.c in Underbit MAD
> libmad 0.15.1b, if NDEBUG is omitted, allows remote attackers to cause
> a denial of service (assertion failure and application exit) via a
> crafted audio file.
> - CVE-2017-8373: The mad_layer_III function in layer3.c in Underbit MAD
> libmad 0.15.1b allows remote attackers to cause a denial of service
> (heap-based buffer overflow and application crash) or possibly have
> unspecified other impact via a crafted audio file.
> - CVE-2017-8374: The mad_bit_skip function in bit.c in Underbit MAD
> libmad 0.15.1b allows remote attackers to cause a denial of service
> (heap-based buffer over-read and application crash) via a crafted
> audio file.
>
> In commit [2], the patches ended up not being applied anymore because
> the APPLY_PATCHES step was called before the patch content exists.
>
> This commit import the fixes in Buildroot.
>
> [1] 858df3643f package/libmad: switch to debian to fix CVEs
> [2] b21184a877 package/libmad: update the patches to be applied with fuzz 0
>
> Signed-off-by: Thomas Perale <thomas.perale@mind.be>
Applied to 2025.02.x & 2026.02.x. Thanks
> ---
> package/libmad/0004-md_size.patch | 63 ++
> package/libmad/0005-length-check.patch | 821 +++++++++++++++++++++++++
> package/libmad/libmad.mk | 6 +
> 3 files changed, 890 insertions(+)
> create mode 100644 package/libmad/0004-md_size.patch
> create mode 100644 package/libmad/0005-length-check.patch
>
> diff --git a/package/libmad/0004-md_size.patch b/package/libmad/0004-md_size.patch
> new file mode 100644
> index 0000000000..b2b3b99df2
> --- /dev/null
> +++ b/package/libmad/0004-md_size.patch
> @@ -0,0 +1,63 @@
> +From: Kurt Roeckx <kurt@roeckx.be>
> +Date: Sun, 28 Jan 2018 15:44:08 +0100
> +Subject: Check the size of the main data
> +
> +The main data to decode a frame can come from the current frame and part of the
> +previous frame, the so called bit reservoir. si.main_data_begin is the part of
> +the previous frame we need for this frame. frame_space is the amount of main
> +data that can be in this frame, and next_md_begin is the part of this frame that
> +is going to be used for the next frame.
> +
> +The maximum amount of data from a previous frame that the format allows is 511
> +bytes. The maximum frame size for the defined bitrates is at MPEG 2.5 layer 2
> +at 320 kbit/s and 8 kHz sample rate which gives 72 * (320000 / 8000) + 1 = 2881.
> +So those defines are not large enough:
> + # define MAD_BUFFER_GUARD 8
> + # define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD)
> +
> +There is also support for a "free" bitrate which allows you to create any frame
> +size, which can be larger than the buffer.
> +
> +Changing the defines is not an option since it's part of the ABI, so we check
> +that the main data fits in the bufer.
> +
> +The previous frame data is stored in *stream->main_data and contains
> +stream->md_len bytes. If stream->md_len is larger than the data we
> +need from the previous frame (si.main_data_begin) it still wouldn't fit
> +in the buffer, so just keep the data that we need.
> +
> +CVE: CVE-2017-8372
> +CVE: CVE-2017-8373
> +Upstream: http://snapshot.debian.org/archive/debian/20190310T213528Z/pool/main/libm/libmad/libmad_0.15.1b-10.diff.gz
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +Index: libmad-0.15.1b/layer3.c
> +===================================================================
> +--- libmad-0.15.1b.orig/layer3.c
> ++++ libmad-0.15.1b/layer3.c
> +@@ -2608,6 +2608,11 @@ int mad_layer_III(struct mad_stream *str
> + next_md_begin = 0;
> +
> + md_len = si.main_data_begin + frame_space - next_md_begin;
> ++ if (md_len + MAD_BUFFER_GUARD > MAD_BUFFER_MDLEN) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> +
> + frame_used = 0;
> +
> +@@ -2625,8 +2630,11 @@ int mad_layer_III(struct mad_stream *str
> + }
> + }
> + else {
> +- mad_bit_init(&ptr,
> +- *stream->main_data + stream->md_len - si.main_data_begin);
> ++ memmove(stream->main_data,
> ++ *stream->main_data + stream->md_len - si.main_data_begin,
> ++ si.main_data_begin);
> ++ stream->md_len = si.main_data_begin;
> ++ mad_bit_init(&ptr, *stream->main_data);
> +
> + if (md_len > si.main_data_begin) {
> + assert(stream->md_len + md_len -
> diff --git a/package/libmad/0005-length-check.patch b/package/libmad/0005-length-check.patch
> new file mode 100644
> index 0000000000..5c56849da7
> --- /dev/null
> +++ b/package/libmad/0005-length-check.patch
> @@ -0,0 +1,821 @@
> +From: Kurt Roeckx <kurt@roeckx.be>
> +Date: Sun, 28 Jan 2018 19:26:36 +0100
> +Subject: Check the size before reading with mad_bit_read
> +
> +There are various cases where it attemps to read past the end of the buffer
> +using mad_bit_read(). Most functions didn't even know the size of the buffer
> +they were reading from.
> +
> +CVE: CVE-2017-8374
> +Upstream: http://snapshot.debian.org/archive/debian/20190310T213528Z/pool/main/libm/libmad/libmad_0.15.1b-10.diff.gz
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +Index: libmad-0.15.1b/bit.c
> +===================================================================
> +--- libmad-0.15.1b.orig/bit.c
> ++++ libmad-0.15.1b/bit.c
> +@@ -138,6 +138,9 @@ unsigned long mad_bit_read(struct mad_bi
> + {
> + register unsigned long value;
> +
> ++ if (len == 0)
> ++ return 0;
> ++
> + if (bitptr->left == CHAR_BIT)
> + bitptr->cache = *bitptr->byte;
> +
> +Index: libmad-0.15.1b/frame.c
> +===================================================================
> +--- libmad-0.15.1b.orig/frame.c
> ++++ libmad-0.15.1b/frame.c
> +@@ -120,11 +120,18 @@ static
> + int decode_header(struct mad_header *header, struct mad_stream *stream)
> + {
> + unsigned int index;
> ++ struct mad_bitptr bufend_ptr;
> +
> + header->flags = 0;
> + header->private_bits = 0;
> +
> ++ mad_bit_init(&bufend_ptr, stream->bufend);
> ++
> + /* header() */
> ++ if (mad_bit_length(&stream->ptr, &bufend_ptr) < 32) {
> ++ stream->error = MAD_ERROR_BUFLEN;
> ++ return -1;
> ++ }
> +
> + /* syncword */
> + mad_bit_skip(&stream->ptr, 11);
> +@@ -225,8 +232,13 @@ int decode_header(struct mad_header *hea
> + /* error_check() */
> +
> + /* crc_check */
> +- if (header->flags & MAD_FLAG_PROTECTION)
> ++ if (header->flags & MAD_FLAG_PROTECTION) {
> ++ if (mad_bit_length(&stream->ptr, &bufend_ptr) < 16) {
> ++ stream->error = MAD_ERROR_BUFLEN;
> ++ return -1;
> ++ }
> + header->crc_target = mad_bit_read(&stream->ptr, 16);
> ++ }
> +
> + return 0;
> + }
> +@@ -338,7 +350,7 @@ int mad_header_decode(struct mad_header
> + stream->error = MAD_ERROR_BUFLEN;
> + goto fail;
> + }
> +- else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
> ++ else if ((end - ptr >= 2) && !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
> + /* mark point where frame sync word was expected */
> + stream->this_frame = ptr;
> + stream->next_frame = ptr + 1;
> +@@ -361,6 +373,8 @@ int mad_header_decode(struct mad_header
> + ptr = mad_bit_nextbyte(&stream->ptr);
> + }
> +
> ++ stream->error = MAD_ERROR_NONE;
> ++
> + /* begin processing */
> + stream->this_frame = ptr;
> + stream->next_frame = ptr + 1; /* possibly bogus sync word */
> +@@ -413,7 +427,7 @@ int mad_header_decode(struct mad_header
> + /* check that a valid frame header follows this frame */
> +
> + ptr = stream->next_frame;
> +- if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
> ++ if ((end - ptr >= 2) && !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
> + ptr = stream->next_frame = stream->this_frame + 1;
> + goto sync;
> + }
> +Index: libmad-0.15.1b/layer12.c
> +===================================================================
> +--- libmad-0.15.1b.orig/layer12.c
> ++++ libmad-0.15.1b/layer12.c
> +@@ -72,10 +72,18 @@ mad_fixed_t const linear_table[14] = {
> + * DESCRIPTION: decode one requantized Layer I sample from a bitstream
> + */
> + static
> +-mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb)
> ++mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb, struct mad_stream *stream)
> + {
> + mad_fixed_t sample;
> ++ struct mad_bitptr frameend_ptr;
> +
> ++ mad_bit_init(&frameend_ptr, stream->next_frame);
> ++
> ++ if (mad_bit_length(ptr, &frameend_ptr) < nb) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return 0;
> ++ }
> + sample = mad_bit_read(ptr, nb);
> +
> + /* invert most significant bit, extend sign, then scale to fixed format */
> +@@ -106,6 +114,10 @@ int mad_layer_I(struct mad_stream *strea
> + struct mad_header *header = &frame->header;
> + unsigned int nch, bound, ch, s, sb, nb;
> + unsigned char allocation[2][32], scalefactor[2][32];
> ++ struct mad_bitptr bufend_ptr, frameend_ptr;
> ++
> ++ mad_bit_init(&bufend_ptr, stream->bufend);
> ++ mad_bit_init(&frameend_ptr, stream->next_frame);
> +
> + nch = MAD_NCHANNELS(header);
> +
> +@@ -118,6 +130,11 @@ int mad_layer_I(struct mad_stream *strea
> + /* check CRC word */
> +
> + if (header->flags & MAD_FLAG_PROTECTION) {
> ++ if (mad_bit_length(&stream->ptr, &bufend_ptr)
> ++ < 4 * (bound * nch + (32 - bound))) {
> ++ stream->error = MAD_ERROR_BADCRC;
> ++ return -1;
> ++ }
> + header->crc_check =
> + mad_bit_crc(stream->ptr, 4 * (bound * nch + (32 - bound)),
> + header->crc_check);
> +@@ -133,6 +150,11 @@ int mad_layer_I(struct mad_stream *strea
> +
> + for (sb = 0; sb < bound; ++sb) {
> + for (ch = 0; ch < nch; ++ch) {
> ++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 4) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> + nb = mad_bit_read(&stream->ptr, 4);
> +
> + if (nb == 15) {
> +@@ -145,6 +167,11 @@ int mad_layer_I(struct mad_stream *strea
> + }
> +
> + for (sb = bound; sb < 32; ++sb) {
> ++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 4) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> + nb = mad_bit_read(&stream->ptr, 4);
> +
> + if (nb == 15) {
> +@@ -161,6 +188,11 @@ int mad_layer_I(struct mad_stream *strea
> + for (sb = 0; sb < 32; ++sb) {
> + for (ch = 0; ch < nch; ++ch) {
> + if (allocation[ch][sb]) {
> ++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 6) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> + scalefactor[ch][sb] = mad_bit_read(&stream->ptr, 6);
> +
> + # if defined(OPT_STRICT)
> +@@ -185,8 +217,10 @@ int mad_layer_I(struct mad_stream *strea
> + for (ch = 0; ch < nch; ++ch) {
> + nb = allocation[ch][sb];
> + frame->sbsample[ch][s][sb] = nb ?
> +- mad_f_mul(I_sample(&stream->ptr, nb),
> ++ mad_f_mul(I_sample(&stream->ptr, nb, stream),
> + sf_table[scalefactor[ch][sb]]) : 0;
> ++ if (stream->error != 0)
> ++ return -1;
> + }
> + }
> +
> +@@ -194,7 +228,14 @@ int mad_layer_I(struct mad_stream *strea
> + if ((nb = allocation[0][sb])) {
> + mad_fixed_t sample;
> +
> +- sample = I_sample(&stream->ptr, nb);
> ++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < nb) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> ++ sample = I_sample(&stream->ptr, nb, stream);
> ++ if (stream->error != 0)
> ++ return -1;
> +
> + for (ch = 0; ch < nch; ++ch) {
> + frame->sbsample[ch][s][sb] =
> +@@ -280,13 +321,21 @@ struct quantclass {
> + static
> + void II_samples(struct mad_bitptr *ptr,
> + struct quantclass const *quantclass,
> +- mad_fixed_t output[3])
> ++ mad_fixed_t output[3], struct mad_stream *stream)
> + {
> + unsigned int nb, s, sample[3];
> ++ struct mad_bitptr frameend_ptr;
> ++
> ++ mad_bit_init(&frameend_ptr, stream->next_frame);
> +
> + if ((nb = quantclass->group)) {
> + unsigned int c, nlevels;
> +
> ++ if (mad_bit_length(ptr, &frameend_ptr) < quantclass->bits) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return;
> ++ }
> + /* degrouping */
> + c = mad_bit_read(ptr, quantclass->bits);
> + nlevels = quantclass->nlevels;
> +@@ -299,8 +348,14 @@ void II_samples(struct mad_bitptr *ptr,
> + else {
> + nb = quantclass->bits;
> +
> +- for (s = 0; s < 3; ++s)
> ++ for (s = 0; s < 3; ++s) {
> ++ if (mad_bit_length(ptr, &frameend_ptr) < nb) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return;
> ++ }
> + sample[s] = mad_bit_read(ptr, nb);
> ++ }
> + }
> +
> + for (s = 0; s < 3; ++s) {
> +@@ -336,6 +391,9 @@ int mad_layer_II(struct mad_stream *stre
> + unsigned char const *offsets;
> + unsigned char allocation[2][32], scfsi[2][32], scalefactor[2][32][3];
> + mad_fixed_t samples[3];
> ++ struct mad_bitptr frameend_ptr;
> ++
> ++ mad_bit_init(&frameend_ptr, stream->next_frame);
> +
> + nch = MAD_NCHANNELS(header);
> +
> +@@ -402,13 +460,24 @@ int mad_layer_II(struct mad_stream *stre
> + for (sb = 0; sb < bound; ++sb) {
> + nbal = bitalloc_table[offsets[sb]].nbal;
> +
> +- for (ch = 0; ch < nch; ++ch)
> ++ for (ch = 0; ch < nch; ++ch) {
> ++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < nbal) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> + allocation[ch][sb] = mad_bit_read(&stream->ptr, nbal);
> ++ }
> + }
> +
> + for (sb = bound; sb < sblimit; ++sb) {
> + nbal = bitalloc_table[offsets[sb]].nbal;
> +
> ++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < nbal) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> + allocation[0][sb] =
> + allocation[1][sb] = mad_bit_read(&stream->ptr, nbal);
> + }
> +@@ -417,8 +486,14 @@ int mad_layer_II(struct mad_stream *stre
> +
> + for (sb = 0; sb < sblimit; ++sb) {
> + for (ch = 0; ch < nch; ++ch) {
> +- if (allocation[ch][sb])
> ++ if (allocation[ch][sb]) {
> ++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 2) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> + scfsi[ch][sb] = mad_bit_read(&stream->ptr, 2);
> ++ }
> + }
> + }
> +
> +@@ -441,6 +516,11 @@ int mad_layer_II(struct mad_stream *stre
> + for (sb = 0; sb < sblimit; ++sb) {
> + for (ch = 0; ch < nch; ++ch) {
> + if (allocation[ch][sb]) {
> ++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 6) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> + scalefactor[ch][sb][0] = mad_bit_read(&stream->ptr, 6);
> +
> + switch (scfsi[ch][sb]) {
> +@@ -451,11 +531,21 @@ int mad_layer_II(struct mad_stream *stre
> + break;
> +
> + case 0:
> ++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 6) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> + scalefactor[ch][sb][1] = mad_bit_read(&stream->ptr, 6);
> + /* fall through */
> +
> + case 1:
> + case 3:
> ++ if (mad_bit_length(&stream->ptr, &frameend_ptr) < 6) {
> ++ stream->error = MAD_ERROR_LOSTSYNC;
> ++ stream->sync = 0;
> ++ return -1;
> ++ }
> + scalefactor[ch][sb][2] = mad_bit_read(&stream->ptr, 6);
> + }
> +
> +@@ -487,7 +577,9 @@ int mad_layer_II(struct mad_stream *stre
> + if ((index = allocation[ch][sb])) {
> + index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
> +
> +- II_samples(&stream->ptr, &qc_table[index], samples);
> ++ II_samples(&stream->ptr, &qc_table[index], samples, stream);
> ++ if (stream->error != 0)
> ++ return -1;
> +
> + for (s = 0; s < 3; ++s) {
> + frame->sbsample[ch][3 * gr + s][sb] =
> +@@ -505,7 +597,9 @@ int mad_layer_II(struct mad_stream *stre
> + if ((index = allocation[0][sb])) {
> + index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
> +
> +- II_samples(&stream->ptr, &qc_table[index], samples);
> ++ II_samples(&stream->ptr, &qc_table[index], samples, stream);
> ++ if (stream->error != 0)
> ++ return -1;
> +
> + for (ch = 0; ch < nch; ++ch) {
> + for (s = 0; s < 3; ++s) {
> +Index: libmad-0.15.1b/layer3.c
> +===================================================================
> +--- libmad-0.15.1b.orig/layer3.c
> ++++ libmad-0.15.1b/layer3.c
> +@@ -598,7 +598,8 @@ enum mad_error III_sideinfo(struct mad_b
> + static
> + unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr,
> + struct channel *channel,
> +- struct channel *gr1ch, int mode_extension)
> ++ struct channel *gr1ch, int mode_extension,
> ++ unsigned int bits_left, unsigned int *part2_length)
> + {
> + struct mad_bitptr start;
> + unsigned int scalefac_compress, index, slen[4], part, n, i;
> +@@ -644,8 +645,12 @@ unsigned int III_scalefactors_lsf(struct
> +
> + n = 0;
> + for (part = 0; part < 4; ++part) {
> +- for (i = 0; i < nsfb[part]; ++i)
> ++ for (i = 0; i < nsfb[part]; ++i) {
> ++ if (bits_left < slen[part])
> ++ return MAD_ERROR_BADSCFSI;
> + channel->scalefac[n++] = mad_bit_read(ptr, slen[part]);
> ++ bits_left -= slen[part];
> ++ }
> + }
> +
> + while (n < 39)
> +@@ -690,7 +695,10 @@ unsigned int III_scalefactors_lsf(struct
> + max = (1 << slen[part]) - 1;
> +
> + for (i = 0; i < nsfb[part]; ++i) {
> ++ if (bits_left < slen[part])
> ++ return MAD_ERROR_BADSCFSI;
> + is_pos = mad_bit_read(ptr, slen[part]);
> ++ bits_left -= slen[part];
> +
> + channel->scalefac[n] = is_pos;
> + gr1ch->scalefac[n++] = (is_pos == max);
> +@@ -703,7 +711,8 @@ unsigned int III_scalefactors_lsf(struct
> + }
> + }
> +
> +- return mad_bit_length(&start, ptr);
> ++ *part2_length = mad_bit_length(&start, ptr);
> ++ return MAD_ERROR_NONE;
> + }
> +
> + /*
> +@@ -712,7 +721,8 @@ unsigned int III_scalefactors_lsf(struct
> + */
> + static
> + unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel,
> +- struct channel const *gr0ch, unsigned int scfsi)
> ++ struct channel const *gr0ch, unsigned int scfsi,
> ++ unsigned int bits_left, unsigned int *part2_length)
> + {
> + struct mad_bitptr start;
> + unsigned int slen1, slen2, sfbi;
> +@@ -728,12 +738,20 @@ unsigned int III_scalefactors(struct mad
> + sfbi = 0;
> +
> + nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3;
> +- while (nsfb--)
> ++ while (nsfb--) {
> ++ if (bits_left < slen1)
> ++ return MAD_ERROR_BADSCFSI;
> + channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1);
> ++ bits_left -= slen1;
> ++ }
> +
> + nsfb = 6 * 3;
> +- while (nsfb--)
> ++ while (nsfb--) {
> ++ if (bits_left < slen2)
> ++ return MAD_ERROR_BADSCFSI;
> + channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2);
> ++ bits_left -= slen2;
> ++ }
> +
> + nsfb = 1 * 3;
> + while (nsfb--)
> +@@ -745,8 +763,12 @@ unsigned int III_scalefactors(struct mad
> + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
> + }
> + else {
> +- for (sfbi = 0; sfbi < 6; ++sfbi)
> ++ for (sfbi = 0; sfbi < 6; ++sfbi) {
> ++ if (bits_left < slen1)
> ++ return MAD_ERROR_BADSCFSI;
> + channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
> ++ bits_left -= slen1;
> ++ }
> + }
> +
> + if (scfsi & 0x4) {
> +@@ -754,8 +776,12 @@ unsigned int III_scalefactors(struct mad
> + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
> + }
> + else {
> +- for (sfbi = 6; sfbi < 11; ++sfbi)
> ++ for (sfbi = 6; sfbi < 11; ++sfbi) {
> ++ if (bits_left < slen1)
> ++ return MAD_ERROR_BADSCFSI;
> + channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
> ++ bits_left -= slen1;
> ++ }
> + }
> +
> + if (scfsi & 0x2) {
> +@@ -763,8 +789,12 @@ unsigned int III_scalefactors(struct mad
> + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
> + }
> + else {
> +- for (sfbi = 11; sfbi < 16; ++sfbi)
> ++ for (sfbi = 11; sfbi < 16; ++sfbi) {
> ++ if (bits_left < slen2)
> ++ return MAD_ERROR_BADSCFSI;
> + channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
> ++ bits_left -= slen2;
> ++ }
> + }
> +
> + if (scfsi & 0x1) {
> +@@ -772,14 +802,19 @@ unsigned int III_scalefactors(struct mad
> + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
> + }
> + else {
> +- for (sfbi = 16; sfbi < 21; ++sfbi)
> ++ for (sfbi = 16; sfbi < 21; ++sfbi) {
> ++ if (bits_left < slen2)
> ++ return MAD_ERROR_BADSCFSI;
> + channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
> ++ bits_left -= slen2;
> ++ }
> + }
> +
> + channel->scalefac[21] = 0;
> + }
> +
> +- return mad_bit_length(&start, ptr);
> ++ *part2_length = mad_bit_length(&start, ptr);
> ++ return MAD_ERROR_NONE;
> + }
> +
> + /*
> +@@ -933,19 +968,17 @@ static
> + enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576],
> + struct channel *channel,
> + unsigned char const *sfbwidth,
> +- unsigned int part2_length)
> ++ signed int part3_length)
> + {
> + signed int exponents[39], exp;
> + signed int const *expptr;
> + struct mad_bitptr peek;
> +- signed int bits_left, cachesz;
> ++ signed int bits_left, cachesz, fakebits;
> + register mad_fixed_t *xrptr;
> + mad_fixed_t const *sfbound;
> + register unsigned long bitcache;
> +
> +- bits_left = (signed) channel->part2_3_length - (signed) part2_length;
> +- if (bits_left < 0)
> +- return MAD_ERROR_BADPART3LEN;
> ++ bits_left = part3_length;
> +
> + III_exponents(channel, sfbwidth, exponents);
> +
> +@@ -956,8 +989,12 @@ enum mad_error III_huffdecode(struct mad
> + cachesz = mad_bit_bitsleft(&peek);
> + cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7;
> +
> ++ if (bits_left < cachesz) {
> ++ cachesz = bits_left;
> ++ }
> + bitcache = mad_bit_read(&peek, cachesz);
> + bits_left -= cachesz;
> ++ fakebits = 0;
> +
> + xrptr = &xr[0];
> +
> +@@ -986,7 +1023,7 @@ enum mad_error III_huffdecode(struct mad
> +
> + big_values = channel->big_values;
> +
> +- while (big_values-- && cachesz + bits_left > 0) {
> ++ while (big_values-- && cachesz + bits_left - fakebits > 0) {
> + union huffpair const *pair;
> + unsigned int clumpsz, value;
> + register mad_fixed_t requantized;
> +@@ -1023,10 +1060,19 @@ enum mad_error III_huffdecode(struct mad
> + unsigned int bits;
> +
> + bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7;
> ++ if (bits_left < bits) {
> ++ bits = bits_left;
> ++ }
> + bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
> + cachesz += bits;
> + bits_left -= bits;
> + }
> ++ if (cachesz < 21) {
> ++ unsigned int bits = 21 - cachesz;
> ++ bitcache <<= bits;
> ++ cachesz += bits;
> ++ fakebits += bits;
> ++ }
> +
> + /* hcod (0..19) */
> +
> +@@ -1041,6 +1087,8 @@ enum mad_error III_huffdecode(struct mad
> + }
> +
> + cachesz -= pair->value.hlen;
> ++ if (cachesz < fakebits)
> ++ return MAD_ERROR_BADHUFFDATA;
> +
> + if (linbits) {
> + /* x (0..14) */
> +@@ -1054,10 +1102,15 @@ enum mad_error III_huffdecode(struct mad
> +
> + case 15:
> + if (cachesz < linbits + 2) {
> +- bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
> +- cachesz += 16;
> +- bits_left -= 16;
> ++ unsigned int bits = 16;
> ++ if (bits_left < 16)
> ++ bits = bits_left;
> ++ bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
> ++ cachesz += bits;
> ++ bits_left -= bits;
> + }
> ++ if (cachesz - fakebits < linbits)
> ++ return MAD_ERROR_BADHUFFDATA;
> +
> + value += MASK(bitcache, cachesz, linbits);
> + cachesz -= linbits;
> +@@ -1074,6 +1127,8 @@ enum mad_error III_huffdecode(struct mad
> + }
> +
> + x_final:
> ++ if (cachesz - fakebits < 1)
> ++ return MAD_ERROR_BADHUFFDATA;
> + xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
> + -requantized : requantized;
> + }
> +@@ -1089,10 +1144,15 @@ enum mad_error III_huffdecode(struct mad
> +
> + case 15:
> + if (cachesz < linbits + 1) {
> +- bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
> +- cachesz += 16;
> +- bits_left -= 16;
> ++ unsigned int bits = 16;
> ++ if (bits_left < 16)
> ++ bits = bits_left;
> ++ bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
> ++ cachesz += bits;
> ++ bits_left -= bits;
> + }
> ++ if (cachesz - fakebits < linbits)
> ++ return MAD_ERROR_BADHUFFDATA;
> +
> + value += MASK(bitcache, cachesz, linbits);
> + cachesz -= linbits;
> +@@ -1109,6 +1169,8 @@ enum mad_error III_huffdecode(struct mad
> + }
> +
> + y_final:
> ++ if (cachesz - fakebits < 1)
> ++ return MAD_ERROR_BADHUFFDATA;
> + xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
> + -requantized : requantized;
> + }
> +@@ -1128,6 +1190,8 @@ enum mad_error III_huffdecode(struct mad
> + requantized = reqcache[value] = III_requantize(value, exp);
> + }
> +
> ++ if (cachesz - fakebits < 1)
> ++ return MAD_ERROR_BADHUFFDATA;
> + xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
> + -requantized : requantized;
> + }
> +@@ -1146,6 +1210,8 @@ enum mad_error III_huffdecode(struct mad
> + requantized = reqcache[value] = III_requantize(value, exp);
> + }
> +
> ++ if (cachesz - fakebits < 1)
> ++ return MAD_ERROR_BADHUFFDATA;
> + xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
> + -requantized : requantized;
> + }
> +@@ -1155,9 +1221,6 @@ enum mad_error III_huffdecode(struct mad
> + }
> + }
> +
> +- if (cachesz + bits_left < 0)
> +- return MAD_ERROR_BADHUFFDATA; /* big_values overrun */
> +-
> + /* count1 */
> + {
> + union huffquad const *table;
> +@@ -1167,15 +1230,24 @@ enum mad_error III_huffdecode(struct mad
> +
> + requantized = III_requantize(1, exp);
> +
> +- while (cachesz + bits_left > 0 && xrptr <= &xr[572]) {
> ++ while (cachesz + bits_left - fakebits > 0 && xrptr <= &xr[572]) {
> + union huffquad const *quad;
> +
> + /* hcod (1..6) */
> +
> + if (cachesz < 10) {
> +- bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
> +- cachesz += 16;
> +- bits_left -= 16;
> ++ unsigned int bits = 16;
> ++ if (bits_left < 16)
> ++ bits = bits_left;
> ++ bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
> ++ cachesz += bits;
> ++ bits_left -= bits;
> ++ }
> ++ if (cachesz < 10) {
> ++ unsigned int bits = 10 - cachesz;
> ++ bitcache <<= bits;
> ++ cachesz += bits;
> ++ fakebits += bits;
> + }
> +
> + quad = &table[MASK(bitcache, cachesz, 4)];
> +@@ -1188,6 +1260,11 @@ enum mad_error III_huffdecode(struct mad
> + MASK(bitcache, cachesz, quad->ptr.bits)];
> + }
> +
> ++ if (cachesz - fakebits < quad->value.hlen + quad->value.v
> ++ + quad->value.w + quad->value.x + quad->value.y)
> ++ /* We don't have enough bits to read one more entry, consider them
> ++ * stuffing bits. */
> ++ break;
> + cachesz -= quad->value.hlen;
> +
> + if (xrptr == sfbound) {
> +@@ -1236,22 +1313,8 @@ enum mad_error III_huffdecode(struct mad
> +
> + xrptr += 2;
> + }
> +-
> +- if (cachesz + bits_left < 0) {
> +-# if 0 && defined(DEBUG)
> +- fprintf(stderr, "huffman count1 overrun (%d bits)\n",
> +- -(cachesz + bits_left));
> +-# endif
> +-
> +- /* technically the bitstream is misformatted, but apparently
> +- some encoders are just a bit sloppy with stuffing bits */
> +-
> +- xrptr -= 4;
> +- }
> + }
> +
> +- assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);
> +-
> + # if 0 && defined(DEBUG)
> + if (bits_left < 0)
> + fprintf(stderr, "read %d bits too many\n", -bits_left);
> +@@ -2348,10 +2411,11 @@ void III_freqinver(mad_fixed_t sample[18
> + */
> + static
> + enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame,
> +- struct sideinfo *si, unsigned int nch)
> ++ struct sideinfo *si, unsigned int nch, unsigned int md_len)
> + {
> + struct mad_header *header = &frame->header;
> + unsigned int sfreqi, ngr, gr;
> ++ int bits_left = md_len * CHAR_BIT;
> +
> + {
> + unsigned int sfreq;
> +@@ -2383,6 +2447,7 @@ enum mad_error III_decode(struct mad_bit
> + for (ch = 0; ch < nch; ++ch) {
> + struct channel *channel = &granule->ch[ch];
> + unsigned int part2_length;
> ++ unsigned int part3_length;
> +
> + sfbwidth[ch] = sfbwidth_table[sfreqi].l;
> + if (channel->block_type == 2) {
> +@@ -2391,18 +2456,30 @@ enum mad_error III_decode(struct mad_bit
> + }
> +
> + if (header->flags & MAD_FLAG_LSF_EXT) {
> +- part2_length = III_scalefactors_lsf(ptr, channel,
> ++ error = III_scalefactors_lsf(ptr, channel,
> + ch == 0 ? 0 : &si->gr[1].ch[1],
> +- header->mode_extension);
> ++ header->mode_extension, bits_left, &part2_length);
> + }
> + else {
> +- part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],
> +- gr == 0 ? 0 : si->scfsi[ch]);
> ++ error = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],
> ++ gr == 0 ? 0 : si->scfsi[ch], bits_left, &part2_length);
> + }
> ++ if (error)
> ++ return error;
> ++
> ++ bits_left -= part2_length;
> +
> +- error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length);
> ++ if (part2_length > channel->part2_3_length)
> ++ return MAD_ERROR_BADPART3LEN;
> ++
> ++ part3_length = channel->part2_3_length - part2_length;
> ++ if (part3_length > bits_left)
> ++ return MAD_ERROR_BADPART3LEN;
> ++
> ++ error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part3_length);
> + if (error)
> + return error;
> ++ bits_left -= part3_length;
> + }
> +
> + /* joint stereo processing */
> +@@ -2519,11 +2596,13 @@ int mad_layer_III(struct mad_stream *str
> + unsigned int nch, priv_bitlen, next_md_begin = 0;
> + unsigned int si_len, data_bitlen, md_len;
> + unsigned int frame_space, frame_used, frame_free;
> +- struct mad_bitptr ptr;
> ++ struct mad_bitptr ptr, bufend_ptr;
> + struct sideinfo si;
> + enum mad_error error;
> + int result = 0;
> +
> ++ mad_bit_init(&bufend_ptr, stream->bufend);
> ++
> + /* allocate Layer III dynamic structures */
> +
> + if (stream->main_data == 0) {
> +@@ -2587,14 +2666,15 @@ int mad_layer_III(struct mad_stream *str
> + unsigned long header;
> +
> + mad_bit_init(&peek, stream->next_frame);
> ++ if (mad_bit_length(&peek, &bufend_ptr) >= 57) {
> ++ header = mad_bit_read(&peek, 32);
> ++ if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) {
> ++ if (!(header & 0x00010000L)) /* protection_bit */
> ++ mad_bit_skip(&peek, 16); /* crc_check */
> +
> +- header = mad_bit_read(&peek, 32);
> +- if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) {
> +- if (!(header & 0x00010000L)) /* protection_bit */
> +- mad_bit_skip(&peek, 16); /* crc_check */
> +-
> +- next_md_begin =
> +- mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8);
> ++ next_md_begin =
> ++ mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8);
> ++ }
> + }
> +
> + mad_bit_finish(&peek);
> +@@ -2653,7 +2733,7 @@ int mad_layer_III(struct mad_stream *str
> + /* decode main_data */
> +
> + if (result == 0) {
> +- error = III_decode(&ptr, frame, &si, nch);
> ++ error = III_decode(&ptr, frame, &si, nch, md_len);
> + if (error) {
> + stream->error = error;
> + result = -1;
> diff --git a/package/libmad/libmad.mk b/package/libmad/libmad.mk
> index 611f13eb67..d69adcc1d5 100644
> --- a/package/libmad/libmad.mk
> +++ b/package/libmad/libmad.mk
> @@ -12,6 +12,12 @@ LIBMAD_INSTALL_STAGING = YES
> LIBMAD_LICENSE = GPL-2.0+
> LIBMAD_LICENSE_FILES = COPYING
>
> +# 0004-md_size.patch
> +LIBMAD_IGNORE_CVES += CVE-2017-8372 CVE-2017-8373
> +
> +# 0005-length-check.patch
> +LIBMAD_IGNORE_CVES += CVE-2017-8374
> +
> # Force autoreconf to be able to use a more recent libtool script, that
> # is able to properly behave in the face of a missing C++ compiler.
> LIBMAD_AUTORECONF = YES
> --
> 2.52.0
>
> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Buildroot] [PATCH 3/4] package/libmad: remove Debian patches
2026-02-04 13:18 ` [Buildroot] [PATCH 3/4] package/libmad: remove Debian patches Thomas Perale via buildroot
@ 2026-06-05 12:49 ` Thomas Perale via buildroot
0 siblings, 0 replies; 9+ messages in thread
From: Thomas Perale via buildroot @ 2026-06-05 12:49 UTC (permalink / raw)
To: Thomas Perale; +Cc: buildroot
In reply of:
> In Buildroot there are multiple way to apply patches on a package [1]
>
> - Adding `.patch` file in the package directory.
> - Define `<pkg>_PATCH` variable with the location of the patch tar.gz.
> It used to download Debian patches tarball.
> - Implement custom patching logic with `PRE`/`POST` patches hooks.
>
> The libmad package is downloading a diff file from the Debian
> mirror with the `<pkg>_PATCH` method [2] and then apply that diff to
> create a directory containing patches. The patches are then applied in
> the `PRE_PATCH_HOOK`.
>
> The Debian patches were integrated in commit [4], in commit [5] the
> application of the patches was moved to the PRE_PATCH_HOOK.
> The problem is that in the PRE_PATCH step the `_PATCH` downloaded from
> Debian don't exist yet and end up not being applied at all.
>
> Since this is not used, remove the Debian patches.
>
> [1] https://buildroot.org/downloads/manual/manual.html#patch-policy
> [2] http://snapshot.debian.org/archive/debian/20190310T213528Z/pool/main/libm/libmad/libmad_0.15.1b-10.diff.gz
> [3] 1167d0ff3d docs/manual: mention CVE trailer
> [4] 858df3643f package/libmad: switch to debian to fix CVEs
> [5] b21184a877 package/libmad: update the patches to be applied with fuzz 0
>
> Signed-off-by: Thomas Perale <thomas.perale@mind.be>
Applied to 2025.02.x & 2026.02.x. Thanks
> ---
> package/libmad/libmad.mk | 15 ---------------
> 1 file changed, 15 deletions(-)
>
> diff --git a/package/libmad/libmad.mk b/package/libmad/libmad.mk
> index db04d22e92..611f13eb67 100644
> --- a/package/libmad/libmad.mk
> +++ b/package/libmad/libmad.mk
> @@ -5,7 +5,6 @@
> ################################################################################
>
> LIBMAD_VERSION = 0.15.1b
> -LIBMAD_PATCH = libmad_$(LIBMAD_VERSION)-10.diff.gz
> LIBMAD_SOURCE = libmad_$(LIBMAD_VERSION).orig.tar.gz
> LIBMAD_SITE = \
> http://snapshot.debian.org/archive/debian/20190310T213528Z/pool/main/libm/libmad
> @@ -13,20 +12,6 @@ LIBMAD_INSTALL_STAGING = YES
> LIBMAD_LICENSE = GPL-2.0+
> LIBMAD_LICENSE_FILES = COPYING
>
> -define LIBMAD_APPLY_DEBIAN_PATCHES
> - if [ -d $(@D)/debian/patches ]; then \
> - $(APPLY_PATCHES) $(@D) $(@D)/debian/patches *.patch; \
> - fi
> -endef
> -
> -LIBMAD_PRE_PATCH_HOOKS += LIBMAD_APPLY_DEBIAN_PATCHES
> -
> -# debian/patches/md_size.diff
> -LIBMAD_IGNORE_CVES += CVE-2017-8372 CVE-2017-8373
> -
> -# debian/patches/length-check.patch
> -LIBMAD_IGNORE_CVES += CVE-2017-8374
> -
> # Force autoreconf to be able to use a more recent libtool script, that
> # is able to properly behave in the face of a missing C++ compiler.
> LIBMAD_AUTORECONF = YES
> --
> 2.52.0
>
> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian
2026-02-04 13:18 [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian Thomas Perale via buildroot
` (3 preceding siblings ...)
2026-05-29 9:45 ` [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian Thomas Petazzoni via buildroot
@ 2026-06-05 12:49 ` Thomas Perale via buildroot
4 siblings, 0 replies; 9+ messages in thread
From: Thomas Perale via buildroot @ 2026-06-05 12:49 UTC (permalink / raw)
To: Thomas Perale; +Cc: buildroot
In reply of:
> In Buildroot there are multiple way to apply patches on a package [1]
>
> - Adding `.patch` file in the package directory.
> - Define `<pkg>_PATCH` variable with the location of the patch tar.gz.
> It used to download Debian patches tarball.
> - Implement custom patching logic with `PRE`/`POST` patches hooks.
>
> To make the CycloneDX SBOM generation not dependant on downloading the
> packages, the two last options have the downside of not appearing on the
> generated SBOM.
>
> The unzip package is downloading a tarball from the Debian mirror with
> the `<pkg>_PATCH` method [2].
>
> To improve the tracking of the patched vulnerabilities for the unzip
> package this commit import the patches previously downloaded with the
> `_PATCH` variable in the Buildroot tree.
> This allows to add the `CVE:` trailer [3] on the patches that fix
> vulnerabilities to better track which patch is fixing the vulnerability.
>
> [1] https://buildroot.org/downloads/manual/manual.html#patch-policy
> [2] https://snapshot.debian.org/archive/debian/20250311T215724Z/pool/main/u/unzip/unzip_6.0-29.debian.tar.xz
> [3] 1167d0ff3d docs/manual: mention CVE trailer
>
> Signed-off-by: Thomas Perale <thomas.perale@mind.be>
Applied to 2025.02.x & 2026.02.x. Thanks
> ---
> .checkpackageignore | 1 -
> ...pages-in-section-1-not-in-section-1l.patch | 297 +++++++++++++++
> package/unzip/0002-this-is-debian-unzip.patch | 18 +
> .../0003-include-unistd-for-kfreebsd.patch | 17 +
> .../0004-handle-pkware-verification-bit.patch | 23 ++
> package/unzip/0005-fix-uid-gid-handling.patch | 31 ++
> .../0006-initialize-the-symlink-flag.patch | 22 ++
> .../0007-increase-size-of-cfactorstr.patch | 19 +
> .../0008-allow-greater-hostver-values.patch | 16 +
> .../0009-cve-2014-8139-crc-overflow.patch | 56 +++
> .../0010-cve-2014-8140-test-compr-eb.patch | 30 ++
> .../0011-cve-2014-8141-getzip64data.patch | 140 ++++++++
> .../0012-cve-2014-9636-test-compr-eb.patch | 44 +++
> package/unzip/0013-remove-build-date.patch | 20 ++
> package/unzip/0014-cve-2015-7696.patch | 35 ++
> package/unzip/0015-cve-2015-7697.patch | 29 ++
> ...fix-integer-underflow-csiz-decrypted.patch | 34 ++
> ...7-restore-unix-timestamps-accurately.patch | 43 +++
> ...-cve-2014-9913-unzip-buffer-overflow.patch | 32 ++
> ...ve-2016-9844-zipinfo-buffer-overflow.patch | 31 ++
> ...e-2018-1000035-unzip-buffer-overflow.patch | 39 ++
> ...21-fix-warning-messages-on-big-files.patch | 16 +
> ...-2019-13232-fix-bug-in-undefer-input.patch | 25 ++
> ...232-zip-bomb-with-overlapped-entries.patch | 338 ++++++++++++++++++
> ...lert-for-misplaced-central-directory.patch | 106 ++++++
> ...-cve-2019-13232-fix-bug-in-uzbunzip2.patch | 26 ++
> ...-cve-2019-13232-fix-bug-in-uzinflate.patch | 26 ++
> .../0027-zipgrep-avoid-test-errors.patch | 17 +
> ...0028-cve-2022-0529-and-cve-2022-0530.patch | 177 +++++++++
> .../0029-handle-windows-zip64-files.patch | 21 ++
> .../0030-drop-conflicting-declarations.patch | 18 +
> package/unzip/0031-fix-zipgrep.patch | 20 ++
> ...eFile.txt-to-ease-cross-compilation.patch} | 1 +
> package/unzip/unzip.mk | 55 ++-
> 34 files changed, 1806 insertions(+), 17 deletions(-)
> create mode 100644 package/unzip/0001-manpages-in-section-1-not-in-section-1l.patch
> create mode 100644 package/unzip/0002-this-is-debian-unzip.patch
> create mode 100644 package/unzip/0003-include-unistd-for-kfreebsd.patch
> create mode 100644 package/unzip/0004-handle-pkware-verification-bit.patch
> create mode 100644 package/unzip/0005-fix-uid-gid-handling.patch
> create mode 100644 package/unzip/0006-initialize-the-symlink-flag.patch
> create mode 100644 package/unzip/0007-increase-size-of-cfactorstr.patch
> create mode 100644 package/unzip/0008-allow-greater-hostver-values.patch
> create mode 100644 package/unzip/0009-cve-2014-8139-crc-overflow.patch
> create mode 100644 package/unzip/0010-cve-2014-8140-test-compr-eb.patch
> create mode 100644 package/unzip/0011-cve-2014-8141-getzip64data.patch
> create mode 100644 package/unzip/0012-cve-2014-9636-test-compr-eb.patch
> create mode 100644 package/unzip/0013-remove-build-date.patch
> create mode 100644 package/unzip/0014-cve-2015-7696.patch
> create mode 100644 package/unzip/0015-cve-2015-7697.patch
> create mode 100644 package/unzip/0016-fix-integer-underflow-csiz-decrypted.patch
> create mode 100644 package/unzip/0017-restore-unix-timestamps-accurately.patch
> create mode 100644 package/unzip/0018-cve-2014-9913-unzip-buffer-overflow.patch
> create mode 100644 package/unzip/0019-cve-2016-9844-zipinfo-buffer-overflow.patch
> create mode 100644 package/unzip/0020-cve-2018-1000035-unzip-buffer-overflow.patch
> create mode 100644 package/unzip/0021-fix-warning-messages-on-big-files.patch
> create mode 100644 package/unzip/0022-cve-2019-13232-fix-bug-in-undefer-input.patch
> create mode 100644 package/unzip/0023-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
> create mode 100644 package/unzip/0024-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
> create mode 100644 package/unzip/0025-cve-2019-13232-fix-bug-in-uzbunzip2.patch
> create mode 100644 package/unzip/0026-cve-2019-13232-fix-bug-in-uzinflate.patch
> create mode 100644 package/unzip/0027-zipgrep-avoid-test-errors.patch
> create mode 100644 package/unzip/0028-cve-2022-0529-and-cve-2022-0530.patch
> create mode 100644 package/unzip/0029-handle-windows-zip64-files.patch
> create mode 100644 package/unzip/0030-drop-conflicting-declarations.patch
> create mode 100644 package/unzip/0031-fix-zipgrep.patch
> rename package/unzip/{0001-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch => 0101-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch} (99%)
>
> diff --git a/.checkpackageignore b/.checkpackageignore
> index a04e96ac00..8e0a283441 100644
> --- a/.checkpackageignore
> +++ b/.checkpackageignore
> @@ -967,7 +967,6 @@ package/uhttpd/0002-Fix-TCP_FASTOPEN-related-compile-error.patch lib_patch.Upstr
> package/unbound/S70unbound Shellcheck
> package/unifdef/0001-Makefile-fix-error-on-install.patch lib_patch.Upstream
> package/unscd/S46unscd Shellcheck lib_sysv.Indent lib_sysv.Variables
> -package/unzip/0001-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch lib_patch.Upstream
> package/upmpdcli/S99upmpdcli Shellcheck lib_sysv.Indent lib_sysv.Variables
> package/urg/0001-select-h.patch lib_patch.Upstream
> package/urg/0002-urg-gcc6-fix-narrowing-conversion.patch lib_patch.Upstream
> diff --git a/package/unzip/0001-manpages-in-section-1-not-in-section-1l.patch b/package/unzip/0001-manpages-in-section-1-not-in-section-1l.patch
> new file mode 100644
> index 0000000000..9d8f3ef241
> --- /dev/null
> +++ b/package/unzip/0001-manpages-in-section-1-not-in-section-1l.patch
> @@ -0,0 +1,297 @@
> +From: Santiago Vila <sanvila@debian.org>
> +Subject: In Debian, manpages are in section 1, not in section 1L
> +X-Debian-version: 5.52-3
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/01-manpages-in-section-1-not-in-section-1l.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/man/funzip.1
> ++++ b/man/funzip.1
> +@@ -20,7 +20,7 @@
> + .in -4n
> + ..
> + .\" =========================================================================
> +-.TH FUNZIP 1L "20 April 2009 (v3.95)" "Info-ZIP"
> ++.TH FUNZIP 1 "20 April 2009 (v3.95)" "Info-ZIP"
> + .SH NAME
> + funzip \- filter for extracting from a ZIP archive in a pipe
> + .PD
> +@@ -78,7 +78,7 @@
> + .EE
> + .PP
> + To use \fIzip\fP and \fIfunzip\fP in place of \fIcompress\fP(1) and
> +-\fIzcat\fP(1) (or \fIgzip\fP(1L) and \fIgzcat\fP(1L)) for tape backups:
> ++\fIzcat\fP(1) (or \fIgzip\fP(1) and \fIgzcat\fP(1)) for tape backups:
> + .PP
> + .EX
> + tar cf \- . | zip \-7 | dd of=/dev/nrst0 obs=8k
> +@@ -108,8 +108,8 @@
> + .PD
> + .\" =========================================================================
> + .SH "SEE ALSO"
> +-\fIgzip\fP(1L), \fIunzip\fP(1L), \fIunzipsfx\fP(1L), \fIzip\fP(1L),
> +-\fIzipcloak\fP(1L), \fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
> ++\fIgzip\fP(1), \fIunzip\fP(1), \fIunzipsfx\fP(1), \fIzip\fP(1),
> ++\fIzipcloak\fP(1), \fIzipinfo\fP(1), \fIzipnote\fP(1), \fIzipsplit\fP(1)
> + .PD
> + .\" =========================================================================
> + .SH URL
> +--- a/man/unzip.1
> ++++ b/man/unzip.1
> +@@ -20,7 +20,7 @@
> + .in -4n
> + ..
> + .\" =========================================================================
> +-.TH UNZIP 1L "20 April 2009 (v6.0)" "Info-ZIP"
> ++.TH UNZIP 1 "20 April 2009 (v6.0)" "Info-ZIP"
> + .SH NAME
> + unzip \- list, test and extract compressed files in a ZIP archive
> + .PD
> +@@ -34,7 +34,7 @@
> + \fIunzip\fP will list, test, or extract files from a ZIP archive, commonly
> + found on MS-DOS systems. The default behavior (with no options) is to extract
> + into the current directory (and subdirectories below it) all files from the
> +-specified ZIP archive. A companion program, \fIzip\fP(1L), creates ZIP
> ++specified ZIP archive. A companion program, \fIzip\fP(1), creates ZIP
> + archives; both programs are compatible with archives created by PKWARE's
> + \fIPKZIP\fP and \fIPKUNZIP\fP for MS-DOS, but in many cases the program
> + options or default behaviors differ.
> +@@ -105,8 +105,8 @@
> + list of all possible flags. The exhaustive list follows:
> + .TP
> + .B \-Z
> +-\fIzipinfo\fP(1L) mode. If the first option on the command line is \fB\-Z\fP,
> +-the remaining options are taken to be \fIzipinfo\fP(1L) options. See the
> ++\fIzipinfo\fP(1) mode. If the first option on the command line is \fB\-Z\fP,
> ++the remaining options are taken to be \fIzipinfo\fP(1) options. See the
> + appropriate manual page for a description of these options.
> + .TP
> + .B \-A
> +@@ -178,7 +178,7 @@
> + compressed size and compression ratio figures are independent of the entry's
> + encryption status and show the correct compression performance. (The complete
> + size of the encrypted compressed data stream for zipfile entries is reported
> +-by the more verbose \fIzipinfo\fP(1L) reports, see the separate manual.)
> ++by the more verbose \fIzipinfo\fP(1) reports, see the separate manual.)
> + When no zipfile is specified (that is, the complete command is simply
> + ``\fCunzip \-v\fR''), a diagnostic screen is printed. In addition to
> + the normal header with release date and version, \fIunzip\fP lists the
> +@@ -379,8 +379,8 @@
> + .TP
> + .B \-N
> + [Amiga] extract file comments as Amiga filenotes. File comments are created
> +-with the \-c option of \fIzip\fP(1L), or with the \-N option of the Amiga port
> +-of \fIzip\fP(1L), which stores filenotes as comments.
> ++with the \-c option of \fIzip\fP(1), or with the \-N option of the Amiga port
> ++of \fIzip\fP(1), which stores filenotes as comments.
> + .TP
> + .B \-o
> + overwrite existing files without prompting. This is a dangerous option, so
> +@@ -598,7 +598,7 @@
> + As suggested by the examples above, the default variable names are UNZIP_OPTS
> + for VMS (where the symbol used to install \fIunzip\fP as a foreign command
> + would otherwise be confused with the environment variable), and UNZIP
> +-for all other operating systems. For compatibility with \fIzip\fP(1L),
> ++for all other operating systems. For compatibility with \fIzip\fP(1),
> + UNZIPOPT is also accepted (don't ask). If both UNZIP and UNZIPOPT
> + are defined, however, UNZIP takes precedence. \fIunzip\fP's diagnostic
> + option (\fB\-v\fP with no zipfile name) can be used to check the values
> +@@ -648,8 +648,8 @@
> + a password is not known, entering a null password (that is, just a carriage
> + return or ``Enter'') is taken as a signal to skip all further prompting.
> + Only unencrypted files in the archive(s) will thereafter be extracted. (In
> +-fact, that's not quite true; older versions of \fIzip\fP(1L) and
> +-\fIzipcloak\fP(1L) allowed null passwords, so \fIunzip\fP checks each encrypted
> ++fact, that's not quite true; older versions of \fIzip\fP(1) and
> ++\fIzipcloak\fP(1) allowed null passwords, so \fIunzip\fP checks each encrypted
> + file to see if the null password works. This may result in ``false positives''
> + and extraction errors, as noted above.)
> + .PP
> +@@ -943,8 +943,8 @@
> + .PD
> + .\" =========================================================================
> + .SH "SEE ALSO"
> +-\fIfunzip\fP(1L), \fIzip\fP(1L), \fIzipcloak\fP(1L), \fIzipgrep\fP(1L),
> +-\fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
> ++\fIfunzip\fP(1), \fIzip\fP(1), \fIzipcloak\fP(1), \fIzipgrep\fP(1),
> ++\fIzipinfo\fP(1), \fIzipnote\fP(1), \fIzipsplit\fP(1)
> + .PD
> + .\" =========================================================================
> + .SH URL
> +--- a/man/unzipsfx.1
> ++++ b/man/unzipsfx.1
> +@@ -20,7 +20,7 @@
> + .in -4n
> + ..
> + .\" =========================================================================
> +-.TH UNZIPSFX 1L "20 April 2009 (v6.0)" "Info-ZIP"
> ++.TH UNZIPSFX 1 "20 April 2009 (v6.0)" "Info-ZIP"
> + .SH NAME
> + unzipsfx \- self-extracting stub for prepending to ZIP archives
> + .PD
> +@@ -30,7 +30,7 @@
> + .PD
> + .\" =========================================================================
> + .SH DESCRIPTION
> +-\fIunzipsfx\fP is a modified version of \fIunzip\fP(1L) designed to be
> ++\fIunzipsfx\fP is a modified version of \fIunzip\fP(1) designed to be
> + prepended to existing ZIP archives in order to form self-extracting archives.
> + Instead of taking its first non-flag argument to be the zipfile(s) to be
> + extracted, \fIunzipsfx\fP seeks itself under the name by which it was invoked
> +@@ -109,7 +109,7 @@
> + .PD
> + .\" =========================================================================
> + .SH OPTIONS
> +-\fIunzipsfx\fP supports the following \fIunzip\fP(1L) options: \fB\-c\fP
> ++\fIunzipsfx\fP supports the following \fIunzip\fP(1) options: \fB\-c\fP
> + and \fB\-p\fP (extract to standard output/screen), \fB\-f\fP and \fB\-u\fP
> + (freshen and update existing files upon extraction), \fB\-t\fP (test
> + archive) and \fB\-z\fP (print archive comment). All normal listing options
> +@@ -118,11 +118,11 @@
> + those creating self-extracting archives may wish to include a short listing
> + in the zipfile comment.
> + .PP
> +-See \fIunzip\fP(1L) for a more complete description of these options.
> ++See \fIunzip\fP(1) for a more complete description of these options.
> + .PD
> + .\" =========================================================================
> + .SH MODIFIERS
> +-\fIunzipsfx\fP currently supports all \fIunzip\fP(1L) modifiers: \fB\-a\fP
> ++\fIunzipsfx\fP currently supports all \fIunzip\fP(1) modifiers: \fB\-a\fP
> + (convert text files), \fB\-n\fP (never overwrite), \fB\-o\fP (overwrite
> + without prompting), \fB\-q\fP (operate quietly), \fB\-C\fP (match names
> + case-insensitively), \fB\-L\fP (convert uppercase-OS names to lowercase),
> +@@ -137,18 +137,18 @@
> + of course continue to be supported since the zipfile format implies ASCII
> + storage of text files.)
> + .PP
> +-See \fIunzip\fP(1L) for a more complete description of these modifiers.
> ++See \fIunzip\fP(1) for a more complete description of these modifiers.
> + .PD
> + .\" =========================================================================
> + .SH "ENVIRONMENT OPTIONS"
> +-\fIunzipsfx\fP uses the same environment variables as \fIunzip\fP(1L) does,
> ++\fIunzipsfx\fP uses the same environment variables as \fIunzip\fP(1) does,
> + although this is likely to be an issue only for the person creating and
> +-testing the self-extracting archive. See \fIunzip\fP(1L) for details.
> ++testing the self-extracting archive. See \fIunzip\fP(1) for details.
> + .PD
> + .\" =========================================================================
> + .SH DECRYPTION
> +-Decryption is supported exactly as in \fIunzip\fP(1L); that is, interactively
> +-with a non-echoing prompt for the password(s). See \fIunzip\fP(1L) for
> ++Decryption is supported exactly as in \fIunzip\fP(1); that is, interactively
> ++with a non-echoing prompt for the password(s). See \fIunzip\fP(1) for
> + details. Once again, note that if the archive has no encrypted files there
> + is no reason to use a version of \fIunzipsfx\fP with decryption support;
> + that only adds to the size of the archive.
> +@@ -286,7 +286,7 @@
> + from anywhere in the user's path. The situation is not known for AmigaDOS,
> + Atari TOS, MacOS, etc.
> + .PP
> +-As noted above, a number of the normal \fIunzip\fP(1L) functions have
> ++As noted above, a number of the normal \fIunzip\fP(1) functions have
> + been removed in order to make \fIunzipsfx\fP smaller: usage and diagnostic
> + info, listing functions and extraction to other directories. Also, only
> + stored and deflated files are supported. The latter limitation is mainly
> +@@ -303,17 +303,17 @@
> + defined as a ``debug hunk.'') There may be compatibility problems between
> + the ROM levels of older Amigas and newer ones.
> + .PP
> +-All current bugs in \fIunzip\fP(1L) exist in \fIunzipsfx\fP as well.
> ++All current bugs in \fIunzip\fP(1) exist in \fIunzipsfx\fP as well.
> + .PD
> + .\" =========================================================================
> + .SH DIAGNOSTICS
> + \fIunzipsfx\fP's exit status (error level) is identical to that of
> +-\fIunzip\fP(1L); see the corresponding man page.
> ++\fIunzip\fP(1); see the corresponding man page.
> + .PD
> + .\" =========================================================================
> + .SH "SEE ALSO"
> +-\fIfunzip\fP(1L), \fIunzip\fP(1L), \fIzip\fP(1L), \fIzipcloak\fP(1L),
> +-\fIzipgrep\fP(1L), \fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
> ++\fIfunzip\fP(1), \fIunzip\fP(1), \fIzip\fP(1), \fIzipcloak\fP(1),
> ++\fIzipgrep\fP(1), \fIzipinfo\fP(1), \fIzipnote\fP(1), \fIzipsplit\fP(1)
> + .PD
> + .PD
> + .\" =========================================================================
> +@@ -330,7 +330,7 @@
> + .\" =========================================================================
> + .SH AUTHORS
> + Greg Roelofs was responsible for the basic modifications to UnZip necessary
> +-to create UnZipSFX. See \fIunzip\fP(1L) for the current list of Zip-Bugs
> ++to create UnZipSFX. See \fIunzip\fP(1) for the current list of Zip-Bugs
> + authors, or the file CONTRIBS in the UnZip source distribution for the
> + full list of Info-ZIP contributors.
> + .PD
> +--- a/man/zipgrep.1
> ++++ b/man/zipgrep.1
> +@@ -8,7 +8,7 @@
> + .\" zipgrep.1 by Greg Roelofs.
> + .\"
> + .\" =========================================================================
> +-.TH ZIPGREP 1L "20 April 2009" "Info-ZIP"
> ++.TH ZIPGREP 1 "20 April 2009" "Info-ZIP"
> + .SH NAME
> + zipgrep \- search files in a ZIP archive for lines matching a pattern
> + .PD
> +@@ -21,7 +21,7 @@
> + .SH DESCRIPTION
> + \fIzipgrep\fP will search files within a ZIP archive for lines matching
> + the given string or pattern. \fIzipgrep\fP is a shell script and requires
> +-\fIegrep\fP(1) and \fIunzip\fP(1L) to function. Its output is identical to
> ++\fIegrep\fP(1) and \fIunzip\fP(1) to function. Its output is identical to
> + that of \fIegrep\fP(1).
> + .PD
> + .\" =========================================================================
> +@@ -69,8 +69,8 @@
> + .PD
> + .\" =========================================================================
> + .SH "SEE ALSO"
> +-\fIegrep\fP(1), \fIunzip\fP(1L), \fIzip\fP(1L), \fIfunzip\fP(1L),
> +-\fIzipcloak\fP(1L), \fIzipinfo\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
> ++\fIegrep\fP(1), \fIunzip\fP(1), \fIzip\fP(1), \fIfunzip\fP(1),
> ++\fIzipcloak\fP(1), \fIzipinfo\fP(1), \fIzipnote\fP(1), \fIzipsplit\fP(1)
> + .PD
> + .\" =========================================================================
> + .SH URL
> +--- a/man/zipinfo.1
> ++++ b/man/zipinfo.1
> +@@ -34,7 +34,7 @@
> + .in -4n
> + ..
> + .\" =========================================================================
> +-.TH ZIPINFO 1L "20 April 2009 (v3.0)" "Info-ZIP"
> ++.TH ZIPINFO 1 "20 April 2009 (v3.0)" "Info-ZIP"
> + .SH NAME
> + zipinfo \- list detailed information about a ZIP archive
> + .PD
> +@@ -272,7 +272,7 @@
> + Note that because of limitations in the MS-DOS format used to store file
> + times, the seconds field is always rounded to the nearest even second.
> + For Unix files this is expected to change in the next major releases of
> +-\fIzip\fP(1L) and \fIunzip\fP.
> ++\fIzip\fP(1) and \fIunzip\fP.
> + .PP
> + In addition to individual file information, a default zipfile listing
> + also includes header and trailer lines:
> +@@ -361,7 +361,7 @@
> + As suggested above, the default variable names are ZIPINFO_OPTS for VMS
> + (where the symbol used to install \fIzipinfo\fP as a foreign command
> + would otherwise be confused with the environment variable), and ZIPINFO
> +-for all other operating systems. For compatibility with \fIzip\fP(1L),
> ++for all other operating systems. For compatibility with \fIzip\fP(1),
> + ZIPINFOOPT is also accepted (don't ask). If both ZIPINFO and ZIPINFOOPT
> + are defined, however, ZIPINFO takes precedence. \fIunzip\fP's diagnostic
> + option (\fB\-v\fP with no zipfile name) can be used to check the values
> +@@ -496,8 +496,8 @@
> + .PP
> + .\" =========================================================================
> + .SH "SEE ALSO"
> +-\fIls\fP(1), \fIfunzip\fP(1L), \fIunzip\fP(1L), \fIunzipsfx\fP(1L),
> +-\fIzip\fP(1L), \fIzipcloak\fP(1L), \fIzipnote\fP(1L), \fIzipsplit\fP(1L)
> ++\fIls\fP(1), \fIfunzip\fP(1), \fIunzip\fP(1), \fIunzipsfx\fP(1),
> ++\fIzip\fP(1), \fIzipcloak\fP(1), \fIzipnote\fP(1), \fIzipsplit\fP(1)
> + .PD
> + .\" =========================================================================
> + .SH URL
> diff --git a/package/unzip/0002-this-is-debian-unzip.patch b/package/unzip/0002-this-is-debian-unzip.patch
> new file mode 100644
> index 0000000000..8a9bd69a23
> --- /dev/null
> +++ b/package/unzip/0002-this-is-debian-unzip.patch
> @@ -0,0 +1,18 @@
> +From: Santiago Vila <sanvila@debian.org>
> +Subject: "Branding patch": UnZip by Debian. Original by Info-ZIP.
> +X-Debian-version: 5.52-5
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/02-this-is-debian-unzip.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/unzip.c
> ++++ b/unzip.c
> +@@ -570,8 +570,7 @@
> + #else /* !VMS */
> + # ifdef COPYRIGHT_CLEAN
> + static ZCONST char Far UnzipUsageLine1[] = "\
> +-UnZip %d.%d%d%s of %s, by Info-ZIP. Maintained by C. Spieler. Send\n\
> +-bug reports using http://www.info-zip.org/zip-bug.html; see README for details.\
> ++UnZip %d.%d%d%s of %s, by Debian. Original by Info-ZIP.\
> + \n\n";
> + # else
> + static ZCONST char Far UnzipUsageLine1[] = "\
> diff --git a/package/unzip/0003-include-unistd-for-kfreebsd.patch b/package/unzip/0003-include-unistd-for-kfreebsd.patch
> new file mode 100644
> index 0000000000..419c5954c1
> --- /dev/null
> +++ b/package/unzip/0003-include-unistd-for-kfreebsd.patch
> @@ -0,0 +1,17 @@
> +From: Aurelien Jarno <aurel32@debian.org>
> +Subject: #include <unistd.h> for kFreeBSD
> +Bug-Debian: https://bugs.debian.org/340693
> +X-Debian-version: 5.52-8
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/03-include-unistd-for-kfreebsd.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/unix/unxcfg.h
> ++++ b/unix/unxcfg.h
> +@@ -52,6 +52,7 @@
> +
> + #include <sys/types.h> /* off_t, time_t, dev_t, ... */
> + #include <sys/stat.h>
> ++#include <unistd.h>
> +
> + #ifdef NO_OFF_T
> + typedef long zoff_t;
> diff --git a/package/unzip/0004-handle-pkware-verification-bit.patch b/package/unzip/0004-handle-pkware-verification-bit.patch
> new file mode 100644
> index 0000000000..58a3f2092e
> --- /dev/null
> +++ b/package/unzip/0004-handle-pkware-verification-bit.patch
> @@ -0,0 +1,23 @@
> +From: "Steven M. Schweda" <sms@antinode.info>
> +Subject: Handle the PKWare verification bit of internal attributes
> +Bug-Debian: https://bugs.debian.org/630078
> +X-Debian-version: 6.0-5
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/04-handle-pkware-verification-bit.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/process.c
> ++++ b/process.c
> +@@ -1729,6 +1729,13 @@
> + else if (uO.L_flag > 1) /* let -LL force lower case for all names */
> + G.pInfo->lcflag = 1;
> +
> ++ /* Handle the PKWare verification bit, bit 2 (0x0004) of internal
> ++ attributes. If this is set, then a verification checksum is in the
> ++ first 3 bytes of the external attributes. In this case all we can use
> ++ for setting file attributes is the last external attributes byte. */
> ++ if (G.crec.internal_file_attributes & 0x0004)
> ++ G.crec.external_file_attributes &= (ulg)0xff;
> ++
> + /* do Amigas (AMIGA_) also have volume labels? */
> + if (IS_VOLID(G.crec.external_file_attributes) &&
> + (G.pInfo->hostnum == FS_FAT_ || G.pInfo->hostnum == FS_HPFS_ ||
> diff --git a/package/unzip/0005-fix-uid-gid-handling.patch b/package/unzip/0005-fix-uid-gid-handling.patch
> new file mode 100644
> index 0000000000..eb229f5f2a
> --- /dev/null
> +++ b/package/unzip/0005-fix-uid-gid-handling.patch
> @@ -0,0 +1,31 @@
> +From: "Steven M. Schweda" <sms@antinode.info>
> +Subject: Restore uid and gid information when requested
> +Bug-Debian: https://bugs.debian.org/689212
> +X-Debian-version: 6.0-8
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/05-fix-uid-gid-handling.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/process.c
> ++++ b/process.c
> +@@ -2904,7 +2904,7 @@
> + #ifdef IZ_HAVE_UXUIDGID
> + if (eb_len >= EB_UX3_MINLEN
> + && z_uidgid != NULL
> +- && (*((EB_HEADSIZE + 0) + ef_buf) == 1)
> ++ && (*((EB_HEADSIZE + 0) + ef_buf) == 1))
> + /* only know about version 1 */
> + {
> + uch uid_size;
> +@@ -2916,10 +2916,10 @@
> + flags &= ~0x0ff; /* ignore any previous UNIX field */
> +
> + if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
> +- uid_size, z_uidgid[0])
> ++ uid_size, &z_uidgid[0])
> + &&
> + read_ux3_value((EB_HEADSIZE + uid_size + 3) + ef_buf,
> +- gid_size, z_uidgid[1]) )
> ++ gid_size, &z_uidgid[1]) )
> + {
> + flags |= EB_UX2_VALID; /* signal success */
> + }
> diff --git a/package/unzip/0006-initialize-the-symlink-flag.patch b/package/unzip/0006-initialize-the-symlink-flag.patch
> new file mode 100644
> index 0000000000..70c02edaef
> --- /dev/null
> +++ b/package/unzip/0006-initialize-the-symlink-flag.patch
> @@ -0,0 +1,22 @@
> +From: Andreas Schwab <schwab@linux-m68k.org>
> +Subject: Initialize the symlink flag
> +Bug-Debian: https://bugs.debian.org/717029
> +X-Debian-version: 6.0-10
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/06-initialize-the-symlink-flag.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/process.c
> ++++ b/process.c
> +@@ -1758,6 +1758,12 @@
> + = (G.crec.general_purpose_bit_flag & (1 << 11)) == (1 << 11);
> + #endif
> +
> ++#ifdef SYMLINKS
> ++ /* Initialize the symlink flag, may be set by the platform-specific
> ++ mapattr function. */
> ++ G.pInfo->symlink = 0;
> ++#endif
> ++
> + return PK_COOL;
> +
> + } /* end function process_cdir_file_hdr() */
> diff --git a/package/unzip/0007-increase-size-of-cfactorstr.patch b/package/unzip/0007-increase-size-of-cfactorstr.patch
> new file mode 100644
> index 0000000000..2d13962f7f
> --- /dev/null
> +++ b/package/unzip/0007-increase-size-of-cfactorstr.patch
> @@ -0,0 +1,19 @@
> +From: "Steven M. Schweda" <sms@antinode.info>
> +Subject: Increase size of cfactorstr array to avoid buffer overflow
> +Bug-Debian: https://bugs.debian.org/741384
> +X-Debian-version: 6.0-11
> +CVE: CVE-2018-18384
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/07-increase-size-of-cfactorstr.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/list.c
> ++++ b/list.c
> +@@ -97,7 +97,7 @@
> + {
> + int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
> + #ifndef WINDLL
> +- char sgn, cfactorstr[10];
> ++ char sgn, cfactorstr[12];
> + int longhdr=(uO.vflag>1);
> + #endif
> + int date_format;
> diff --git a/package/unzip/0008-allow-greater-hostver-values.patch b/package/unzip/0008-allow-greater-hostver-values.patch
> new file mode 100644
> index 0000000000..10038cfed6
> --- /dev/null
> +++ b/package/unzip/0008-allow-greater-hostver-values.patch
> @@ -0,0 +1,16 @@
> +From: Santiago Vila <sanvila@debian.org>
> +Subject: zipinfo.c: Do not crash when hostver byte is >= 100
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/08-allow-greater-hostver-values.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/zipinfo.c
> ++++ b/zipinfo.c
> +@@ -2114,7 +2114,7 @@
> + else
> + attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T==undefined */
> +
> +- sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
> ++ sprintf(&attribs[11], "%2u.%u", hostver/10, hostver%10);
> + break;
> +
> + } /* end switch (hostnum: external attributes format) */
> diff --git a/package/unzip/0009-cve-2014-8139-crc-overflow.patch b/package/unzip/0009-cve-2014-8139-crc-overflow.patch
> new file mode 100644
> index 0000000000..5ff301a344
> --- /dev/null
> +++ b/package/unzip/0009-cve-2014-8139-crc-overflow.patch
> @@ -0,0 +1,56 @@
> +From: "Steven M. Schweda" <sms@antinode.info>
> +Subject: Fix CVE-2014-8139: CRC32 verification heap-based overflow
> +Bug-Debian: https://bugs.debian.org/773722
> +CVE: CVE-2014-8139
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/09-cve-2014-8139-crc-overflow.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/extract.c
> ++++ b/extract.c
> +@@ -1,5 +1,5 @@
> + /*
> +- Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
> ++ Copyright (c) 1990-2014 Info-ZIP. All rights reserved.
> +
> + See the accompanying file LICENSE, version 2009-Jan-02 or later
> + (the contents of which are also included in unzip.h) for terms of use.
> +@@ -298,6 +298,8 @@
> + #ifndef SFX
> + static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
> + EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
> ++ static ZCONST char Far TooSmallEBlength[] = "bad extra-field entry:\n \
> ++ EF block length (%u bytes) invalid (< %d)\n";
> + static ZCONST char Far InvalidComprDataEAs[] =
> + " invalid compressed data for EAs\n";
> + # if (defined(WIN32) && defined(NTSD_EAS))
> +@@ -2023,7 +2025,8 @@
> + ebID = makeword(ef);
> + ebLen = (unsigned)makeword(ef+EB_LEN);
> +
> +- if (ebLen > (ef_len - EB_HEADSIZE)) {
> ++ if (ebLen > (ef_len - EB_HEADSIZE))
> ++ {
> + /* Discovered some extra field inconsistency! */
> + if (uO.qflag)
> + Info(slide, 1, ((char *)slide, "%-22s ",
> +@@ -2158,11 +2161,19 @@
> + }
> + break;
> + case EF_PKVMS:
> +- if (makelong(ef+EB_HEADSIZE) !=
> ++ if (ebLen < 4)
> ++ {
> ++ Info(slide, 1,
> ++ ((char *)slide, LoadFarString(TooSmallEBlength),
> ++ ebLen, 4));
> ++ }
> ++ else if (makelong(ef+EB_HEADSIZE) !=
> + crc32(CRCVAL_INITIAL, ef+(EB_HEADSIZE+4),
> + (extent)(ebLen-4)))
> ++ {
> + Info(slide, 1, ((char *)slide,
> + LoadFarString(BadCRC_EAs)));
> ++ }
> + break;
> + case EF_PKW32:
> + case EF_PKUNIX:
> diff --git a/package/unzip/0010-cve-2014-8140-test-compr-eb.patch b/package/unzip/0010-cve-2014-8140-test-compr-eb.patch
> new file mode 100644
> index 0000000000..046efca3b5
> --- /dev/null
> +++ b/package/unzip/0010-cve-2014-8140-test-compr-eb.patch
> @@ -0,0 +1,30 @@
> +From: "Steven M. Schweda" <sms@antinode.info>
> +Subject: Fix CVE-2014-8140: out-of-bounds write issue in test_compr_eb()
> +Bug-Debian: https://bugs.debian.org/773722
> +CVE: CVE-2014-8140
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/10-cve-2014-8140-test-compr-eb.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/extract.c
> ++++ b/extract.c
> +@@ -2232,10 +2232,17 @@
> + if (compr_offset < 4) /* field is not compressed: */
> + return PK_OK; /* do nothing and signal OK */
> +
> ++ /* Return no/bad-data error status if any problem is found:
> ++ * 1. eb_size is too small to hold the uncompressed size
> ++ * (eb_ucsize). (Else extract eb_ucsize.)
> ++ * 2. eb_ucsize is zero (invalid). 2014-12-04 SMS.
> ++ * 3. eb_ucsize is positive, but eb_size is too small to hold
> ++ * the compressed data header.
> ++ */
> + if ((eb_size < (EB_UCSIZE_P + 4)) ||
> +- ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
> +- eb_size <= (compr_offset + EB_CMPRHEADLEN)))
> +- return IZ_EF_TRUNC; /* no compressed data! */
> ++ ((eb_ucsize = makelong( eb+ (EB_HEADSIZE+ EB_UCSIZE_P))) == 0L) ||
> ++ ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
> ++ return IZ_EF_TRUNC; /* no/bad compressed data! */
> +
> + if (
> + #ifdef INT_16BIT
> diff --git a/package/unzip/0011-cve-2014-8141-getzip64data.patch b/package/unzip/0011-cve-2014-8141-getzip64data.patch
> new file mode 100644
> index 0000000000..6e1835bda2
> --- /dev/null
> +++ b/package/unzip/0011-cve-2014-8141-getzip64data.patch
> @@ -0,0 +1,140 @@
> +From: "Steven M. Schweda" <sms@antinode.info>
> +Subject: Fix CVE-2014-8141: out-of-bounds read issues in getZip64Data()
> +Bug-Debian: https://bugs.debian.org/773722
> +CVE: CVE-2014-8141
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/11-cve-2014-8141-getzip64data.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/fileio.c
> ++++ b/fileio.c
> +@@ -176,6 +176,8 @@
> + #endif
> + static ZCONST char Far ExtraFieldTooLong[] =
> + "warning: extra field too long (%d). Ignoring...\n";
> ++static ZCONST char Far ExtraFieldCorrupt[] =
> ++ "warning: extra field (type: 0x%04x) corrupt. Continuing...\n";
> +
> + #ifdef WINDLL
> + static ZCONST char Far DiskFullQuery[] =
> +@@ -2295,7 +2297,12 @@
> + if (readbuf(__G__ (char *)G.extra_field, length) == 0)
> + return PK_EOF;
> + /* Looks like here is where extra fields are read */
> +- getZip64Data(__G__ G.extra_field, length);
> ++ if (getZip64Data(__G__ G.extra_field, length) != PK_COOL)
> ++ {
> ++ Info(slide, 0x401, ((char *)slide,
> ++ LoadFarString( ExtraFieldCorrupt), EF_PKSZ64));
> ++ error = PK_WARN;
> ++ }
> + #ifdef UNICODE_SUPPORT
> + G.unipath_filename = NULL;
> + if (G.UzO.U_flag < 2) {
> +--- a/process.c
> ++++ b/process.c
> +@@ -1,5 +1,5 @@
> + /*
> +- Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
> ++ Copyright (c) 1990-2014 Info-ZIP. All rights reserved.
> +
> + See the accompanying file LICENSE, version 2009-Jan-02 or later
> + (the contents of which are also included in unzip.h) for terms of use.
> +@@ -1901,48 +1901,82 @@
> + and a 4-byte version of disk start number.
> + Sets both local header and central header fields. Not terribly clever,
> + but it means that this procedure is only called in one place.
> ++
> ++ 2014-12-05 SMS.
> ++ Added checks to ensure that enough data are available before calling
> ++ makeint64() or makelong(). Replaced various sizeof() values with
> ++ simple ("4" or "8") constants. (The Zip64 structures do not depend
> ++ on our variable sizes.) Error handling is crude, but we should now
> ++ stay within the buffer.
> + ---------------------------------------------------------------------------*/
> +
> ++#define Z64FLGS 0xffff
> ++#define Z64FLGL 0xffffffff
> ++
> + if (ef_len == 0 || ef_buf == NULL)
> + return PK_COOL;
> +
> + Trace((stderr,"\ngetZip64Data: scanning extra field of length %u\n",
> + ef_len));
> +
> +- while (ef_len >= EB_HEADSIZE) {
> ++ while (ef_len >= EB_HEADSIZE)
> ++ {
> + eb_id = makeword(EB_ID + ef_buf);
> + eb_len = makeword(EB_LEN + ef_buf);
> +
> +- if (eb_len > (ef_len - EB_HEADSIZE)) {
> +- /* discovered some extra field inconsistency! */
> ++ if (eb_len > (ef_len - EB_HEADSIZE))
> ++ {
> ++ /* Extra block length exceeds remaining extra field length. */
> + Trace((stderr,
> + "getZip64Data: block length %u > rest ef_size %u\n", eb_len,
> + ef_len - EB_HEADSIZE));
> + break;
> + }
> +- if (eb_id == EF_PKSZ64) {
> +-
> ++ if (eb_id == EF_PKSZ64)
> ++ {
> + int offset = EB_HEADSIZE;
> +
> +- if (G.crec.ucsize == 0xffffffff || G.lrec.ucsize == 0xffffffff){
> +- G.lrec.ucsize = G.crec.ucsize = makeint64(offset + ef_buf);
> +- offset += sizeof(G.crec.ucsize);
> ++ if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
> ++ {
> ++ if (offset+ 8 > ef_len)
> ++ return PK_ERR;
> ++
> ++ G.crec.ucsize = G.lrec.ucsize = makeint64(offset + ef_buf);
> ++ offset += 8;
> + }
> +- if (G.crec.csize == 0xffffffff || G.lrec.csize == 0xffffffff){
> +- G.csize = G.lrec.csize = G.crec.csize = makeint64(offset + ef_buf);
> +- offset += sizeof(G.crec.csize);
> ++
> ++ if ((G.crec.csize == Z64FLGL) || (G.lrec.csize == Z64FLGL))
> ++ {
> ++ if (offset+ 8 > ef_len)
> ++ return PK_ERR;
> ++
> ++ G.csize = G.crec.csize = G.lrec.csize = makeint64(offset + ef_buf);
> ++ offset += 8;
> + }
> +- if (G.crec.relative_offset_local_header == 0xffffffff){
> ++
> ++ if (G.crec.relative_offset_local_header == Z64FLGL)
> ++ {
> ++ if (offset+ 8 > ef_len)
> ++ return PK_ERR;
> ++
> + G.crec.relative_offset_local_header = makeint64(offset + ef_buf);
> +- offset += sizeof(G.crec.relative_offset_local_header);
> ++ offset += 8;
> + }
> +- if (G.crec.disk_number_start == 0xffff){
> ++
> ++ if (G.crec.disk_number_start == Z64FLGS)
> ++ {
> ++ if (offset+ 4 > ef_len)
> ++ return PK_ERR;
> ++
> + G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf);
> +- offset += sizeof(G.crec.disk_number_start);
> ++ offset += 4;
> + }
> ++#if 0
> ++ break; /* Expect only one EF_PKSZ64 block. */
> ++#endif /* 0 */
> + }
> +
> +- /* Skip this extra field block */
> ++ /* Skip this extra field block. */
> + ef_buf += (eb_len + EB_HEADSIZE);
> + ef_len -= (eb_len + EB_HEADSIZE);
> + }
> diff --git a/package/unzip/0012-cve-2014-9636-test-compr-eb.patch b/package/unzip/0012-cve-2014-9636-test-compr-eb.patch
> new file mode 100644
> index 0000000000..a68a249e2b
> --- /dev/null
> +++ b/package/unzip/0012-cve-2014-9636-test-compr-eb.patch
> @@ -0,0 +1,44 @@
> +From: mancha <mancha1 AT zoho DOT com>
> +Date: Wed, 11 Feb 2015
> +Subject: Info-ZIP UnZip buffer overflow
> +Bug-Debian: https://bugs.debian.org/776589
> +
> +By carefully crafting a corrupt ZIP archive with "extra fields" that
> +purport to have compressed blocks larger than the corresponding
> +uncompressed blocks in STORED no-compression mode, an attacker can
> +trigger a heap overflow that can result in application crash or
> +possibly have other unspecified impact.
> +
> +This patch ensures that when extra fields use STORED mode, the
> +"compressed" and uncompressed block sizes match.
> +
> +CVE: CVE-2014-9636
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/12-cve-2014-9636-test-compr-eb.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/extract.c
> ++++ b/extract.c
> +@@ -2228,6 +2228,7 @@
> + ulg eb_ucsize;
> + uch *eb_ucptr;
> + int r;
> ++ ush eb_compr_method;
> +
> + if (compr_offset < 4) /* field is not compressed: */
> + return PK_OK; /* do nothing and signal OK */
> +@@ -2244,6 +2245,15 @@
> + ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
> + return IZ_EF_TRUNC; /* no/bad compressed data! */
> +
> ++ /* 2015-02-10 Mancha(?), Michal Zalewski, Tomas Hoger, SMS.
> ++ * For STORE method, compressed and uncompressed sizes must agree.
> ++ * http://www.info-zip.org/phpBB3/viewtopic.php?f=7&t=450
> ++ */
> ++ eb_compr_method = makeword( eb + (EB_HEADSIZE + compr_offset));
> ++ if ((eb_compr_method == STORED) &&
> ++ (eb_size != compr_offset + EB_CMPRHEADLEN + eb_ucsize))
> ++ return PK_ERR;
> ++
> + if (
> + #ifdef INT_16BIT
> + (((ulg)(extent)eb_ucsize) != eb_ucsize) ||
> diff --git a/package/unzip/0013-remove-build-date.patch b/package/unzip/0013-remove-build-date.patch
> new file mode 100644
> index 0000000000..48353aa8d4
> --- /dev/null
> +++ b/package/unzip/0013-remove-build-date.patch
> @@ -0,0 +1,20 @@
> +From: Jérémy Bobbio <lunar@debian.org>
> +Subject: Remove build date
> +Bug-Debian: https://bugs.debian.org/782851
> + In order to make unzip build reproducibly, we remove the
> + (already optional) build date from the binary.
> +
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/13-remove-build-date.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +
> +--- a/unix/unix.c
> ++++ b/unix/unix.c
> +@@ -1705,7 +1705,7 @@
> + #endif /* Sun */
> + #endif /* SGI */
> +
> +-#ifdef __DATE__
> ++#if 0
> + " on ", __DATE__
> + #else
> + "", ""
> diff --git a/package/unzip/0014-cve-2015-7696.patch b/package/unzip/0014-cve-2015-7696.patch
> new file mode 100644
> index 0000000000..b64b2b829a
> --- /dev/null
> +++ b/package/unzip/0014-cve-2015-7696.patch
> @@ -0,0 +1,35 @@
> +From: Petr Stodulka <pstodulk@redhat.com>
> +Date: Mon, 14 Sep 2015 18:23:17 +0200
> +Subject: Upstream fix for heap overflow
> +Bug-Debian: https://bugs.debian.org/802162
> +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1260944
> +Origin: https://bugzilla.redhat.com/attachment.cgi?id=1073002
> +Forwarded: yes
> +CVE: CVE-2015-7696
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/14-cve-2015-7696.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> + crypt.c | 12 +++++++++++-
> + 1 file changed, 11 insertions(+), 1 deletion(-)
> +
> +--- a/crypt.c
> ++++ b/crypt.c
> +@@ -465,7 +465,17 @@
> + GLOBAL(pInfo->encrypted) = FALSE;
> + defer_leftover_input(__G);
> + for (n = 0; n < RAND_HEAD_LEN; n++) {
> +- b = NEXTBYTE;
> ++ /* 2012-11-23 SMS. (OUSPG report.)
> ++ * Quit early if compressed size < HEAD_LEN. The resulting
> ++ * error message ("unable to get password") could be improved,
> ++ * but it's better than trying to read nonexistent data, and
> ++ * then continuing with a negative G.csize. (See
> ++ * fileio.c:readbyte()).
> ++ */
> ++ if ((b = NEXTBYTE) == (ush)EOF)
> ++ {
> ++ return PK_ERR;
> ++ }
> + h[n] = (uch)b;
> + Trace((stdout, " (%02x)", h[n]));
> + }
> diff --git a/package/unzip/0015-cve-2015-7697.patch b/package/unzip/0015-cve-2015-7697.patch
> new file mode 100644
> index 0000000000..e60b40cdeb
> --- /dev/null
> +++ b/package/unzip/0015-cve-2015-7697.patch
> @@ -0,0 +1,29 @@
> +From: Kamil Dudka <kdudka@redhat.com>
> +Date: Mon, 14 Sep 2015 18:24:56 +0200
> +Subject: fix infinite loop when extracting empty bzip2 data
> +Bug-Debian: https://bugs.debian.org/802160
> +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1260944
> +Origin: other, https://bugzilla.redhat.com/attachment.cgi?id=1073339
> +
> +CVE: CVE-2015-7697
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/15-cve-2015-7697.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> + extract.c | 6 ++++++
> + 1 file changed, 6 insertions(+)
> +
> +--- a/extract.c
> ++++ b/extract.c
> +@@ -2729,6 +2729,12 @@
> + int repeated_buf_err;
> + bz_stream bstrm;
> +
> ++ if (G.incnt <= 0 && G.csize <= 0L) {
> ++ /* avoid an infinite loop */
> ++ Trace((stderr, "UZbunzip2() got empty input\n"));
> ++ return 2;
> ++ }
> ++
> + #if (defined(DLL) && !defined(NO_SLIDE_REDIR))
> + if (G.redirect_slide)
> + wsize = G.redirect_size, redirSlide = G.redirect_buffer;
> diff --git a/package/unzip/0016-fix-integer-underflow-csiz-decrypted.patch b/package/unzip/0016-fix-integer-underflow-csiz-decrypted.patch
> new file mode 100644
> index 0000000000..bc01506c50
> --- /dev/null
> +++ b/package/unzip/0016-fix-integer-underflow-csiz-decrypted.patch
> @@ -0,0 +1,34 @@
> +From: Kamil Dudka <kdudka@redhat.com>
> +Date: Tue, 22 Sep 2015 18:52:23 +0200
> +Subject: [PATCH] extract: prevent unsigned overflow on invalid input
> +Origin: other, https://bugzilla.redhat.com/attachment.cgi?id=1075942
> +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1260944
> +
> +Suggested-by: Stefan Cornelius
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/16-fix-integer-underflow-csiz-decrypted.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +---
> + extract.c | 11 ++++++++++-
> + 1 file changed, 10 insertions(+), 1 deletion(-)
> +
> +--- a/extract.c
> ++++ b/extract.c
> +@@ -1257,8 +1257,17 @@
> + if (G.lrec.compression_method == STORED) {
> + zusz_t csiz_decrypted = G.lrec.csize;
> +
> +- if (G.pInfo->encrypted)
> ++ if (G.pInfo->encrypted) {
> ++ if (csiz_decrypted < 12) {
> ++ /* handle the error now to prevent unsigned overflow */
> ++ Info(slide, 0x401, ((char *)slide,
> ++ LoadFarStringSmall(ErrUnzipNoFile),
> ++ LoadFarString(InvalidComprData),
> ++ LoadFarStringSmall2(Inflate)));
> ++ return PK_ERR;
> ++ }
> + csiz_decrypted -= 12;
> ++ }
> + if (G.lrec.ucsize != csiz_decrypted) {
> + Info(slide, 0x401, ((char *)slide,
> + LoadFarStringSmall2(WrnStorUCSizCSizDiff),
> diff --git a/package/unzip/0017-restore-unix-timestamps-accurately.patch b/package/unzip/0017-restore-unix-timestamps-accurately.patch
> new file mode 100644
> index 0000000000..484fa2df9c
> --- /dev/null
> +++ b/package/unzip/0017-restore-unix-timestamps-accurately.patch
> @@ -0,0 +1,43 @@
> +From: "Steven M. Schweda" <sms@antinode.info>
> +Subject: Do not ignore extra fields containing Unix Timestamps
> +Bug-Debian: https://bugs.debian.org/842993
> +X-Debian-version: 6.0-21
> +
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/17-restore-unix-timestamps-accurately.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/process.c
> ++++ b/process.c
> +@@ -2914,10 +2914,13 @@
> + break;
> +
> + case EF_IZUNIX2:
> +- if (have_new_type_eb == 0) {
> +- flags &= ~0x0ff; /* ignore any previous IZUNIX field */
> ++ if (have_new_type_eb == 0) { /* (< 1) */
> + have_new_type_eb = 1;
> + }
> ++ if (have_new_type_eb <= 1) {
> ++ /* Ignore any prior (EF_IZUNIX/EF_PKUNIX) UID/GID. */
> ++ flags &= 0x0ff;
> ++ }
> + #ifdef IZ_HAVE_UXUIDGID
> + if (have_new_type_eb > 1)
> + break; /* IZUNIX3 overrides IZUNIX2 e.f. block ! */
> +@@ -2933,6 +2936,8 @@
> + /* new 3rd generation Unix ef */
> + have_new_type_eb = 2;
> +
> ++ /* Ignore any prior EF_IZUNIX/EF_PKUNIX/EF_IZUNIX2 UID/GID. */
> ++ flags &= 0x0ff;
> + /*
> + Version 1 byte version of this extra field, currently 1
> + UIDSize 1 byte Size of UID field
> +@@ -2953,8 +2958,6 @@
> + uid_size = *((EB_HEADSIZE + 1) + ef_buf);
> + gid_size = *((EB_HEADSIZE + uid_size + 2) + ef_buf);
> +
> +- flags &= ~0x0ff; /* ignore any previous UNIX field */
> +-
> + if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
> + uid_size, &z_uidgid[0])
> + &&
> diff --git a/package/unzip/0018-cve-2014-9913-unzip-buffer-overflow.patch b/package/unzip/0018-cve-2014-9913-unzip-buffer-overflow.patch
> new file mode 100644
> index 0000000000..5be35bc084
> --- /dev/null
> +++ b/package/unzip/0018-cve-2014-9913-unzip-buffer-overflow.patch
> @@ -0,0 +1,32 @@
> +From: "Steven M. Schweda" <sms@antinode.info>
> +Subject: Fix CVE-2014-9913, buffer overflow in unzip
> +Bug: https://sourceforge.net/p/infozip/bugs/27/
> +Bug-Debian: https://bugs.debian.org/847485
> +Bug-Ubuntu: https://launchpad.net/bugs/387350
> +X-Debian-version: 6.0-21
> +
> +CVE: CVE-2014-9913
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/18-cve-2014-9913-unzip-buffer-overflow.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/list.c
> ++++ b/list.c
> +@@ -339,7 +339,18 @@
> + G.crec.compression_method == ENHDEFLATED) {
> + methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3];
> + } else if (methnum >= NUM_METHODS) {
> +- sprintf(&methbuf[4], "%03u", G.crec.compression_method);
> ++ /* 2013-02-26 SMS.
> ++ * http://sourceforge.net/p/infozip/bugs/27/ CVE-2014-9913.
> ++ * Unexpectedly large compression methods overflow
> ++ * &methbuf[]. Use the old, three-digit decimal format
> ++ * for values which fit. Otherwise, sacrifice the
> ++ * colon, and use four-digit hexadecimal.
> ++ */
> ++ if (G.crec.compression_method <= 999) {
> ++ sprintf( &methbuf[ 4], "%03u", G.crec.compression_method);
> ++ } else {
> ++ sprintf( &methbuf[ 3], "%04X", G.crec.compression_method);
> ++ }
> + }
> +
> + #if 0 /* GRR/Euro: add this? */
> diff --git a/package/unzip/0019-cve-2016-9844-zipinfo-buffer-overflow.patch b/package/unzip/0019-cve-2016-9844-zipinfo-buffer-overflow.patch
> new file mode 100644
> index 0000000000..9760e6a3bb
> --- /dev/null
> +++ b/package/unzip/0019-cve-2016-9844-zipinfo-buffer-overflow.patch
> @@ -0,0 +1,31 @@
> +From: "Steven M. Schweda" <sms@antinode.info>
> +Subject: Fix CVE-2016-9844, buffer overflow in zipinfo
> +Bug-Debian: https://bugs.debian.org/847486
> +Bug-Ubuntu: https://launchpad.net/bugs/1643750
> +X-Debian-version: 6.0-21
> +
> +CVE: CVE-2016-9844
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/19-cve-2016-9844-zipinfo-buffer-overflow.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/zipinfo.c
> ++++ b/zipinfo.c
> +@@ -1921,7 +1921,18 @@
> + ush dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
> + methbuf[3] = dtype[dnum];
> + } else if (methnum >= NUM_METHODS) { /* unknown */
> +- sprintf(&methbuf[1], "%03u", G.crec.compression_method);
> ++ /* 2016-12-05 SMS.
> ++ * https://launchpad.net/bugs/1643750
> ++ * Unexpectedly large compression methods overflow
> ++ * &methbuf[]. Use the old, three-digit decimal format
> ++ * for values which fit. Otherwise, sacrifice the "u",
> ++ * and use four-digit hexadecimal.
> ++ */
> ++ if (G.crec.compression_method <= 999) {
> ++ sprintf( &methbuf[ 1], "%03u", G.crec.compression_method);
> ++ } else {
> ++ sprintf( &methbuf[ 0], "%04X", G.crec.compression_method);
> ++ }
> + }
> +
> + for (k = 0; k < 15; ++k)
> diff --git a/package/unzip/0020-cve-2018-1000035-unzip-buffer-overflow.patch b/package/unzip/0020-cve-2018-1000035-unzip-buffer-overflow.patch
> new file mode 100644
> index 0000000000..e105ae86df
> --- /dev/null
> +++ b/package/unzip/0020-cve-2018-1000035-unzip-buffer-overflow.patch
> @@ -0,0 +1,39 @@
> +From: Karol Babioch <kbabioch@suse.com>
> +Subject: Fix buffer overflow in password protected zip archives
> +Bug-Debian: https://bugs.debian.org/889838
> +Origin: https://bugzilla.novell.com/attachment.cgi?id=759406
> +X-Debian-version: 6.0-22
> +
> +CVE: CVE-2018-1000035
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/20-cve-2018-1000035-unzip-buffer-overflow.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/fileio.c
> ++++ b/fileio.c
> +@@ -1582,6 +1582,10 @@
> + int r = IZ_PW_ENTERED;
> + char *m;
> + char *prompt;
> ++ char *zfnf;
> ++ char *efnf;
> ++ size_t zfnfl;
> ++ int isOverflow;
> +
> + #ifndef REENTRANT
> + /* tell picky compilers to shut up about "unused variable" warnings */
> +@@ -1590,7 +1594,15 @@
> +
> + if (*rcnt == 0) { /* First call for current entry */
> + *rcnt = 2;
> +- if ((prompt = (char *)malloc(2*FILNAMSIZ + 15)) != (char *)NULL) {
> ++ zfnf = FnFilter1(zfn);
> ++ efnf = FnFilter2(efn);
> ++ zfnfl = strlen(zfnf);
> ++ isOverflow = TRUE;
> ++ if (2*FILNAMSIZ >= zfnfl && (2*FILNAMSIZ - zfnfl) >= strlen(efnf))
> ++ {
> ++ isOverflow = FALSE;
> ++ }
> ++ if ((isOverflow == FALSE) && ((prompt = (char *)malloc(2*FILNAMSIZ + 15)) != (char *)NULL)) {
> + sprintf(prompt, LoadFarString(PasswPrompt),
> + FnFilter1(zfn), FnFilter2(efn));
> + m = prompt;
> diff --git a/package/unzip/0021-fix-warning-messages-on-big-files.patch b/package/unzip/0021-fix-warning-messages-on-big-files.patch
> new file mode 100644
> index 0000000000..fd9cb49f9c
> --- /dev/null
> +++ b/package/unzip/0021-fix-warning-messages-on-big-files.patch
> @@ -0,0 +1,16 @@
> +From: "Steven M. Schweda" <sms@antinode.info>
> +Subject: Fix lame code in fileio.c
> +Bug-Debian: https://bugs.debian.org/929502
> +X-Debian-version: 6.0-23
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/21-fix-warning-messages-on-big-files.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/fileio.c
> ++++ b/fileio.c
> +@@ -2477,6 +2477,7 @@
> + */
> + return (((zusz_t)sig[7]) << 56)
> + + (((zusz_t)sig[6]) << 48)
> ++ + (((zusz_t)sig[5]) << 40)
> + + (((zusz_t)sig[4]) << 32)
> + + (zusz_t)((((ulg)sig[3]) << 24)
> + + (((ulg)sig[2]) << 16)
> diff --git a/package/unzip/0022-cve-2019-13232-fix-bug-in-undefer-input.patch b/package/unzip/0022-cve-2019-13232-fix-bug-in-undefer-input.patch
> new file mode 100644
> index 0000000000..529ddf9aa9
> --- /dev/null
> +++ b/package/unzip/0022-cve-2019-13232-fix-bug-in-undefer-input.patch
> @@ -0,0 +1,25 @@
> +From: Mark Adler <madler@alumni.caltech.edu>
> +Subject: Fix bug in undefer_input() that misplaced the input state.
> +Origin: https://github.com/madler/unzip/commit/41beb477c5744bc396fa1162ee0c14218ec12213
> +Bug-Debian: https://bugs.debian.org/931433
> +X-Debian-version: 6.0-24
> +
> + Fix bug in undefer_input() that misplaced the input state.
> +
> +CVE: CVE-2019-13232
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/22-cve-2019-13232-fix-bug-in-undefer-input.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/fileio.c
> ++++ b/fileio.c
> +@@ -532,8 +532,10 @@
> + * This condition was checked when G.incnt_leftover was set > 0 in
> + * defer_leftover_input(), and it is NOT allowed to touch G.csize
> + * before calling undefer_input() when (G.incnt_leftover > 0)
> +- * (single exception: see read_byte()'s "G.csize <= 0" handling) !!
> ++ * (single exception: see readbyte()'s "G.csize <= 0" handling) !!
> + */
> ++ if (G.csize < 0L)
> ++ G.csize = 0L;
> + G.incnt = G.incnt_leftover + (int)G.csize;
> + G.inptr = G.inptr_leftover - (int)G.csize;
> + G.incnt_leftover = 0;
> diff --git a/package/unzip/0023-cve-2019-13232-zip-bomb-with-overlapped-entries.patch b/package/unzip/0023-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
> new file mode 100644
> index 0000000000..60b218262a
> --- /dev/null
> +++ b/package/unzip/0023-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
> @@ -0,0 +1,338 @@
> +From: Mark Adler <madler@alumni.caltech.edu>
> +Subject: Detect and reject a zip bomb using overlapped entries.
> +Origin: https://github.com/madler/unzip/commit/47b3ceae397d21bf822bc2ac73052a4b1daf8e1c
> +Bug-Debian: https://bugs.debian.org/931433
> +X-Debian-version: 6.0-24
> +
> + Detect and reject a zip bomb using overlapped entries.
> +
> + This detects an invalid zip file that has at least one entry that
> + overlaps with another entry or with the central directory to the
> + end of the file. A Fifield zip bomb uses overlapped local entries
> + to vastly increase the potential inflation ratio. Such an invalid
> + zip file is rejected.
> +
> + See https://www.bamsoftware.com/hacks/zipbomb/ for David Fifield's
> + analysis, construction, and examples of such zip bombs.
> +
> + The detection maintains a list of covered spans of the zip files
> + so far, where the central directory to the end of the file and any
> + bytes preceding the first entry at zip file offset zero are
> + considered covered initially. Then as each entry is decompressed
> + or tested, it is considered covered. When a new entry is about to
> + be processed, its initial offset is checked to see if it is
> + contained by a covered span. If so, the zip file is rejected as
> + invalid.
> +
> + This commit depends on a preceding commit: "Fix bug in
> + undefer_input() that misplaced the input state."
> +
> +CVE: CVE-2019-13232
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/23-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/extract.c
> ++++ b/extract.c
> +@@ -321,6 +321,125 @@
> + "\nerror: unsupported extra-field compression type (%u)--skipping\n";
> + static ZCONST char Far BadExtraFieldCRC[] =
> + "error [%s]: bad extra-field CRC %08lx (should be %08lx)\n";
> ++static ZCONST char Far NotEnoughMemCover[] =
> ++ "error: not enough memory for bomb detection\n";
> ++static ZCONST char Far OverlappedComponents[] =
> ++ "error: invalid zip file with overlapped components (possible zip bomb)\n";
> ++
> ++
> ++
> ++
> ++
> ++/* A growable list of spans. */
> ++typedef zoff_t bound_t;
> ++typedef struct {
> ++ bound_t beg; /* start of the span */
> ++ bound_t end; /* one past the end of the span */
> ++} span_t;
> ++typedef struct {
> ++ span_t *span; /* allocated, distinct, and sorted list of spans */
> ++ size_t num; /* number of spans in the list */
> ++ size_t max; /* allocated number of spans (num <= max) */
> ++} cover_t;
> ++
> ++/*
> ++ * Return the index of the first span in cover whose beg is greater than val.
> ++ * If there is no such span, then cover->num is returned.
> ++ */
> ++static size_t cover_find(cover, val)
> ++ cover_t *cover;
> ++ bound_t val;
> ++{
> ++ size_t lo = 0, hi = cover->num;
> ++ while (lo < hi) {
> ++ size_t mid = (lo + hi) >> 1;
> ++ if (val < cover->span[mid].beg)
> ++ hi = mid;
> ++ else
> ++ lo = mid + 1;
> ++ }
> ++ return hi;
> ++}
> ++
> ++/* Return true if val lies within any one of the spans in cover. */
> ++static int cover_within(cover, val)
> ++ cover_t *cover;
> ++ bound_t val;
> ++{
> ++ size_t pos = cover_find(cover, val);
> ++ return pos > 0 && val < cover->span[pos - 1].end;
> ++}
> ++
> ++/*
> ++ * Add a new span to the list, but only if the new span does not overlap any
> ++ * spans already in the list. The new span covers the values beg..end-1. beg
> ++ * must be less than end.
> ++ *
> ++ * Keep the list sorted and merge adjacent spans. Grow the allocated space for
> ++ * the list as needed. On success, 0 is returned. If the new span overlaps any
> ++ * existing spans, then 1 is returned and the new span is not added to the
> ++ * list. If the new span is invalid because beg is greater than or equal to
> ++ * end, then -1 is returned. If the list needs to be grown but the memory
> ++ * allocation fails, then -2 is returned.
> ++ */
> ++static int cover_add(cover, beg, end)
> ++ cover_t *cover;
> ++ bound_t beg;
> ++ bound_t end;
> ++{
> ++ size_t pos;
> ++ int prec, foll;
> ++
> ++ if (beg >= end)
> ++ /* The new span is invalid. */
> ++ return -1;
> ++
> ++ /* Find where the new span should go, and make sure that it does not
> ++ overlap with any existing spans. */
> ++ pos = cover_find(cover, beg);
> ++ if ((pos > 0 && beg < cover->span[pos - 1].end) ||
> ++ (pos < cover->num && end > cover->span[pos].beg))
> ++ return 1;
> ++
> ++ /* Check for adjacencies. */
> ++ prec = pos > 0 && beg == cover->span[pos - 1].end;
> ++ foll = pos < cover->num && end == cover->span[pos].beg;
> ++ if (prec && foll) {
> ++ /* The new span connects the preceding and following spans. Merge the
> ++ following span into the preceding span, and delete the following
> ++ span. */
> ++ cover->span[pos - 1].end = cover->span[pos].end;
> ++ cover->num--;
> ++ memmove(cover->span + pos, cover->span + pos + 1,
> ++ (cover->num - pos) * sizeof(span_t));
> ++ }
> ++ else if (prec)
> ++ /* The new span is adjacent only to the preceding span. Extend the end
> ++ of the preceding span. */
> ++ cover->span[pos - 1].end = end;
> ++ else if (foll)
> ++ /* The new span is adjacent only to the following span. Extend the
> ++ beginning of the following span. */
> ++ cover->span[pos].beg = beg;
> ++ else {
> ++ /* The new span has gaps between both the preceding and the following
> ++ spans. Assure that there is room and insert the span. */
> ++ if (cover->num == cover->max) {
> ++ size_t max = cover->max == 0 ? 16 : cover->max << 1;
> ++ span_t *span = realloc(cover->span, max * sizeof(span_t));
> ++ if (span == NULL)
> ++ return -2;
> ++ cover->span = span;
> ++ cover->max = max;
> ++ }
> ++ memmove(cover->span + pos + 1, cover->span + pos,
> ++ (cover->num - pos) * sizeof(span_t));
> ++ cover->num++;
> ++ cover->span[pos].beg = beg;
> ++ cover->span[pos].end = end;
> ++ }
> ++ return 0;
> ++}
> +
> +
> +
> +@@ -376,6 +495,29 @@
> + }
> + #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. */
> ++ if (G.cover == NULL) {
> ++ G.cover = malloc(sizeof(cover_t));
> ++ if (G.cover == NULL) {
> ++ Info(slide, 0x401, ((char *)slide,
> ++ LoadFarString(NotEnoughMemCover)));
> ++ return PK_MEM;
> ++ }
> ++ ((cover_t *)G.cover)->span = NULL;
> ++ ((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,
> ++ G.extra_bytes + G.ecrec.offset_start_central_directory,
> ++ G.ziplen) != 0) {
> ++ Info(slide, 0x401, ((char *)slide,
> ++ LoadFarString(NotEnoughMemCover)));
> ++ return PK_MEM;
> ++ }
> ++
> + /*---------------------------------------------------------------------------
> + The basic idea of this function is as follows. Since the central di-
> + rectory lies at the end of the zipfile and the member files lie at the
> +@@ -593,7 +735,8 @@
> + if (error > error_in_archive)
> + error_in_archive = error;
> + /* ...and keep going (unless disk full or user break) */
> +- if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
> ++ if (G.disk_full > 1 || error_in_archive == IZ_CTRLC ||
> ++ error == PK_BOMB) {
> + /* clear reached_end to signal premature stop ... */
> + reached_end = FALSE;
> + /* ... and cancel scanning the central directory */
> +@@ -1062,6 +1205,11 @@
> +
> + /* seek_zipf(__G__ pInfo->offset); */
> + request = G.pInfo->offset + G.extra_bytes;
> ++ if (cover_within((cover_t *)G.cover, request)) {
> ++ Info(slide, 0x401, ((char *)slide,
> ++ LoadFarString(OverlappedComponents)));
> ++ return PK_BOMB;
> ++ }
> + inbuf_offset = request % INBUFSIZ;
> + bufstart = request - inbuf_offset;
> +
> +@@ -1602,6 +1750,18 @@
> + return IZ_CTRLC; /* cancel operation by user request */
> + }
> + #endif
> ++ error = cover_add((cover_t *)G.cover, request,
> ++ G.cur_zipfile_bufstart + (G.inptr - G.inbuf));
> ++ if (error < 0) {
> ++ Info(slide, 0x401, ((char *)slide,
> ++ LoadFarString(NotEnoughMemCover)));
> ++ return PK_MEM;
> ++ }
> ++ if (error != 0) {
> ++ Info(slide, 0x401, ((char *)slide,
> ++ LoadFarString(OverlappedComponents)));
> ++ return PK_BOMB;
> ++ }
> + #ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
> + UserStop();
> + #endif
> +@@ -2003,6 +2163,34 @@
> + }
> +
> + undefer_input(__G);
> ++
> ++ if ((G.lrec.general_purpose_bit_flag & 8) != 0) {
> ++ /* skip over data descriptor (harder than it sounds, due to signature
> ++ * ambiguity)
> ++ */
> ++# define SIG 0x08074b50
> ++# define LOW 0xffffffff
> ++ uch buf[12];
> ++ unsigned shy = 12 - readbuf((char *)buf, 12);
> ++ ulg crc = shy ? 0 : makelong(buf);
> ++ ulg clen = shy ? 0 : makelong(buf + 4);
> ++ ulg ulen = shy ? 0 : makelong(buf + 8); /* or high clen if ZIP64 */
> ++ if (crc == SIG && /* if not SIG, no signature */
> ++ (G.lrec.crc32 != SIG || /* if not SIG, have signature */
> ++ (clen == SIG && /* if not SIG, no signature */
> ++ ((G.lrec.csize & LOW) != SIG || /* if not SIG, have signature */
> ++ (ulen == SIG && /* if not SIG, no signature */
> ++ (G.zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG
> ++ /* if not SIG, have signature */
> ++ )))))
> ++ /* skip four more bytes to account for signature */
> ++ shy += 4 - readbuf((char *)buf, 4);
> ++ if (G.zip64)
> ++ shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */
> ++ if (shy)
> ++ error = PK_ERR;
> ++ }
> ++
> + return error;
> +
> + } /* end function extract_or_test_member() */
> +--- a/globals.c
> ++++ b/globals.c
> +@@ -181,6 +181,7 @@
> + # if (!defined(NO_TIMESTAMPS))
> + uO.D_flag=1; /* default to '-D', no restoration of dir timestamps */
> + # endif
> ++ G.cover = NULL; /* not allocated yet */
> + #endif
> +
> + uO.lflag=(-1);
> +--- a/globals.h
> ++++ b/globals.h
> +@@ -260,12 +260,15 @@
> + ecdir_rec ecrec; /* used in unzip.c, extract.c */
> + z_stat statbuf; /* used by main, mapname, check_for_newer */
> +
> ++ int zip64; /* true if Zip64 info in extra field */
> ++
> + int mem_mode;
> + uch *outbufptr; /* extract.c static */
> + ulg outsize; /* extract.c static */
> + int reported_backslash; /* extract.c static */
> + int disk_full;
> + int newfile;
> ++ void **cover; /* used in extract.c for bomb detection */
> +
> + int didCRlast; /* fileio static */
> + ulg numlines; /* fileio static: number of lines printed */
> +--- a/process.c
> ++++ b/process.c
> +@@ -637,6 +637,13 @@
> + }
> + #endif
> +
> ++ /* Free the cover span list and the cover structure. */
> ++ if (G.cover != NULL) {
> ++ free(*(G.cover));
> ++ free(G.cover);
> ++ G.cover = NULL;
> ++ }
> ++
> + } /* end function free_G_buffers() */
> +
> +
> +@@ -1913,6 +1920,8 @@
> + #define Z64FLGS 0xffff
> + #define Z64FLGL 0xffffffff
> +
> ++ G.zip64 = FALSE;
> ++
> + if (ef_len == 0 || ef_buf == NULL)
> + return PK_COOL;
> +
> +@@ -2084,6 +2093,8 @@
> + (ZCONST char *)(offset + ef_buf), ULen);
> + G.unipath_filename[ULen] = '\0';
> + }
> ++
> ++ G.zip64 = TRUE;
> + }
> +
> + /* Skip this extra field block */
> +--- a/unzip.h
> ++++ b/unzip.h
> +@@ -645,6 +645,7 @@
> + #define PK_NOZIP 9 /* zipfile not found */
> + #define PK_PARAM 10 /* bad or illegal parameters specified */
> + #define PK_FIND 11 /* no files found */
> ++#define PK_BOMB 12 /* likely zip bomb */
> + #define PK_DISK 50 /* disk full */
> + #define PK_EOF 51 /* unexpected EOF */
> +
> diff --git a/package/unzip/0024-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch b/package/unzip/0024-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
> new file mode 100644
> index 0000000000..7b2092f1c5
> --- /dev/null
> +++ b/package/unzip/0024-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
> @@ -0,0 +1,106 @@
> +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.
> +
> +CVE: CVE-2019-13232
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/24-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- 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;
> +
> +
> diff --git a/package/unzip/0025-cve-2019-13232-fix-bug-in-uzbunzip2.patch b/package/unzip/0025-cve-2019-13232-fix-bug-in-uzbunzip2.patch
> new file mode 100644
> index 0000000000..c743faa342
> --- /dev/null
> +++ b/package/unzip/0025-cve-2019-13232-fix-bug-in-uzbunzip2.patch
> @@ -0,0 +1,26 @@
> +From: Mark Adler <madler@alumni.caltech.edu>
> +Subject: Fix bug in UZbunzip2() that incorrectly updated G.incnt
> +Origin: https://github.com/madler/unzip/commit/5e2efcd633a4a1fb95a129a75508e7d769e767be
> +Bug-Debian: https://bugs.debian.org/963996
> +X-Debian-version: 6.0-26
> +
> + Fix bug in UZbunzip2() that incorrectly updated G.incnt.
> +
> + The update assumed a full buffer, which is not always full. This
> + could result in a false overlapped element detection when a small
> + bzip2-compressed file was unzipped. This commit remedies that.
> +
> +CVE: CVE-2019-13232
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/25-cve-2019-13232-fix-bug-in-uzbunzip2.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/extract.c
> ++++ b/extract.c
> +@@ -3052,7 +3052,7 @@
> + #endif
> +
> + G.inptr = (uch *)bstrm.next_in;
> +- G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */
> ++ G.incnt -= G.inptr - G.inbuf; /* reset for other routines */
> +
> + uzbunzip_cleanup_exit:
> + err = BZ2_bzDecompressEnd(&bstrm);
> diff --git a/package/unzip/0026-cve-2019-13232-fix-bug-in-uzinflate.patch b/package/unzip/0026-cve-2019-13232-fix-bug-in-uzinflate.patch
> new file mode 100644
> index 0000000000..822e800a6e
> --- /dev/null
> +++ b/package/unzip/0026-cve-2019-13232-fix-bug-in-uzinflate.patch
> @@ -0,0 +1,26 @@
> +From: Mark Adler <madler@alumni.caltech.edu>
> +Subject: Fix bug in UZinflate() that incorrectly updated G.incnt.
> +Origin: https://github.com/madler/unzip/commit/5c572555cf5d80309a07c30cf7a54b2501493720
> +X-Debian-version: 6.0-26
> +
> + Fix bug in UZinflate() that incorrectly updated G.incnt.
> +
> + The update assumed a full buffer, which is not always full. This
> + could result in a false overlapped element detection when a small
> + deflate-compressed file was unzipped using an old zlib. This
> + commit remedies that.
> +
> +CVE: CVE-2019-13232
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/26-cve-2019-13232-fix-bug-in-uzinflate.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/inflate.c
> ++++ b/inflate.c
> +@@ -700,7 +700,7 @@
> + G.dstrm.total_out));
> +
> + G.inptr = (uch *)G.dstrm.next_in;
> +- G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */
> ++ G.incnt -= G.inptr - G.inbuf; /* reset for other routines */
> +
> + uzinflate_cleanup_exit:
> + err = inflateReset(&G.dstrm);
> diff --git a/package/unzip/0027-zipgrep-avoid-test-errors.patch b/package/unzip/0027-zipgrep-avoid-test-errors.patch
> new file mode 100644
> index 0000000000..ac53dcd016
> --- /dev/null
> +++ b/package/unzip/0027-zipgrep-avoid-test-errors.patch
> @@ -0,0 +1,17 @@
> +From: Kevin Locke <kevin@kevinlocke.name>
> +Subject: zipgrep: Avoid test errors when no members present
> +Bug-Debian: https://bugs.debian.org/972233
> +X-Debian-version: 6.0-26
> +
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/27-zipgrep-avoid-test-errors.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/unix/zipgrep
> ++++ b/unix/zipgrep
> +@@ -44,6 +44,7 @@
> + opt="-$opt"
> + fi
> +
> ++sts=0
> + status_grep_global=1
> + IFS='
> + '
> diff --git a/package/unzip/0028-cve-2022-0529-and-cve-2022-0530.patch b/package/unzip/0028-cve-2022-0529-and-cve-2022-0530.patch
> new file mode 100644
> index 0000000000..2a36b65b3c
> --- /dev/null
> +++ b/package/unzip/0028-cve-2022-0529-and-cve-2022-0530.patch
> @@ -0,0 +1,177 @@
> +From: Steven M. Schweda <sms@antinode.info>
> +Subject: Fix for CVE-2022-0529 and CVE-2022-0530
> +Bug-Debian: https://bugs.debian.org/1010355
> +X-Debian-version: 6.0-27
> +
> +CVE: CVE-2022-0529
> +CVE: CVE-2022-0530
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/28-cve-2022-0529-and-cve-2022-0530.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/fileio.c
> ++++ b/fileio.c
> +@@ -171,8 +171,10 @@
> + static ZCONST char Far FilenameTooLongTrunc[] =
> + "warning: filename too long--truncating.\n";
> + #ifdef UNICODE_SUPPORT
> ++ static ZCONST char Far UFilenameCorrupt[] =
> ++ "error: Unicode filename corrupt.\n";
> + static ZCONST char Far UFilenameTooLongTrunc[] =
> +- "warning: Converted unicode filename too long--truncating.\n";
> ++ "warning: Converted Unicode filename too long--truncating.\n";
> + #endif
> + static ZCONST char Far ExtraFieldTooLong[] =
> + "warning: extra field too long (%d). Ignoring...\n";
> +@@ -2361,16 +2363,30 @@
> + /* convert UTF-8 to local character set */
> + fn = utf8_to_local_string(G.unipath_filename,
> + G.unicode_escape_all);
> +- /* make sure filename is short enough */
> +- if (strlen(fn) >= FILNAMSIZ) {
> +- fn[FILNAMSIZ - 1] = '\0';
> ++
> ++ /* 2022-07-22 SMS, et al. CVE-2022-0530
> ++ * Detect conversion failure, emit message.
> ++ * Continue with unconverted name.
> ++ */
> ++ if (fn == NULL)
> ++ {
> + Info(slide, 0x401, ((char *)slide,
> +- LoadFarString(UFilenameTooLongTrunc)));
> +- error = PK_WARN;
> ++ LoadFarString(UFilenameCorrupt)));
> ++ error = PK_ERR;
> ++ }
> ++ else
> ++ {
> ++ /* make sure filename is short enough */
> ++ if (strlen(fn) >= FILNAMSIZ) {
> ++ fn[FILNAMSIZ - 1] = '\0';
> ++ Info(slide, 0x401, ((char *)slide,
> ++ LoadFarString(UFilenameTooLongTrunc)));
> ++ error = PK_WARN;
> ++ }
> ++ /* replace filename with converted UTF-8 */
> ++ strcpy(G.filename, fn);
> ++ free(fn);
> + }
> +- /* replace filename with converted UTF-8 */
> +- strcpy(G.filename, fn);
> +- free(fn);
> + }
> + # endif /* UNICODE_WCHAR */
> + if (G.unipath_filename != G.filename_full)
> +--- a/process.c
> ++++ b/process.c
> +@@ -222,6 +222,8 @@
> + "\nwarning: Unicode Path version > 1\n";
> + static ZCONST char Far UnicodeMismatchError[] =
> + "\nwarning: Unicode Path checksum invalid\n";
> ++ static ZCONST char Far UFilenameTooLongTrunc[] =
> ++ "warning: filename too long (P1) -- truncating.\n";
> + #endif
> +
> +
> +@@ -1915,7 +1917,7 @@
> + Sets both local header and central header fields. Not terribly clever,
> + but it means that this procedure is only called in one place.
> +
> +- 2014-12-05 SMS.
> ++ 2014-12-05 SMS. (oCERT.org report.) CVE-2014-8141.
> + Added checks to ensure that enough data are available before calling
> + makeint64() or makelong(). Replaced various sizeof() values with
> + simple ("4" or "8") constants. (The Zip64 structures do not depend
> +@@ -1947,9 +1949,10 @@
> + ef_len - EB_HEADSIZE));
> + break;
> + }
> ++
> + if (eb_id == EF_PKSZ64)
> + {
> +- int offset = EB_HEADSIZE;
> ++ unsigned offset = EB_HEADSIZE;
> +
> + if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
> + {
> +@@ -2046,7 +2049,7 @@
> + }
> + if (eb_id == EF_UNIPATH) {
> +
> +- int offset = EB_HEADSIZE;
> ++ unsigned offset = EB_HEADSIZE;
> + ush ULen = eb_len - 5;
> + ulg chksum = CRCVAL_INITIAL;
> +
> +@@ -2504,16 +2507,17 @@
> + int state_dependent;
> + int wsize = 0;
> + int max_bytes = MB_CUR_MAX;
> +- char buf[9];
> ++ char buf[ MB_CUR_MAX+ 1]; /* ("+1" not really needed?) */
> + char *buffer = NULL;
> + char *local_string = NULL;
> ++ size_t buffer_size; /* CVE-2022-0529 */
> +
> + for (wsize = 0; wide_string[wsize]; wsize++) ;
> +
> + if (max_bytes < MAX_ESCAPE_BYTES)
> + max_bytes = MAX_ESCAPE_BYTES;
> +-
> +- if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) {
> ++ buffer_size = wsize * max_bytes + 1; /* Reused below. */
> ++ if ((buffer = (char *)malloc( buffer_size)) == NULL) {
> + return NULL;
> + }
> +
> +@@ -2551,8 +2555,28 @@
> + } else {
> + /* no MB for this wide */
> + /* use escape for wide character */
> +- char *escape_string = wide_to_escape_string(wide_string[i]);
> +- strcat(buffer, escape_string);
> ++ size_t buffer_len;
> ++ size_t escape_string_len;
> ++ char *escape_string;
> ++ int err_msg = 0;
> ++
> ++ escape_string = wide_to_escape_string(wide_string[i]);
> ++ buffer_len = strlen( buffer);
> ++ escape_string_len = strlen( escape_string);
> ++
> ++ /* Append escape string, as space allows. */
> ++ /* 2022-07-18 SMS, et al. CVE-2022-0529 */
> ++ if (escape_string_len > buffer_size- buffer_len- 1)
> ++ {
> ++ escape_string_len = buffer_size- buffer_len- 1;
> ++ if (err_msg == 0)
> ++ {
> ++ err_msg = 1;
> ++ Info(slide, 0x401, ((char *)slide,
> ++ LoadFarString( UFilenameTooLongTrunc)));
> ++ }
> ++ }
> ++ strncat( buffer, escape_string, escape_string_len);
> + free(escape_string);
> + }
> + }
> +@@ -2604,9 +2628,18 @@
> + ZCONST char *utf8_string;
> + int escape_all;
> + {
> +- zwchar *wide = utf8_to_wide_string(utf8_string);
> +- char *loc = wide_to_local_string(wide, escape_all);
> +- free(wide);
> ++ zwchar *wide;
> ++ char *loc = NULL;
> ++
> ++ wide = utf8_to_wide_string( utf8_string);
> ++
> ++ /* 2022-07-25 SMS, et al. CVE-2022-0530 */
> ++ if (wide != NULL)
> ++ {
> ++ loc = wide_to_local_string( wide, escape_all);
> ++ free( wide);
> ++ }
> ++
> + return loc;
> + }
> +
> diff --git a/package/unzip/0029-handle-windows-zip64-files.patch b/package/unzip/0029-handle-windows-zip64-files.patch
> new file mode 100644
> index 0000000000..c4cd35fd0c
> --- /dev/null
> +++ b/package/unzip/0029-handle-windows-zip64-files.patch
> @@ -0,0 +1,21 @@
> +From: Roy Tam
> +Subject: Handle Microsoft ZIP64 files by ignoring invalid "Total number of disks" field
> +Origin: https://sourceforge.net/p/infozip/bugs/42/
> +Bug: https://sourceforge.net/p/infozip/bugs/42/
> +Bug-Debian: https://bugs.debian.org/1064000
> +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/unzip/+bug/2051952
> +X-Debian-version: 6.0-29
> +
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/29-handle-windows-zip64-files.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/process.c
> ++++ b/process.c
> +@@ -1281,7 +1281,7 @@
> + fprintf(stdout,"\nnumber of disks (ECR) %u, (ECLOC64) %lu\n",
> + G.ecrec.number_this_disk, ecloc64_total_disks); fflush(stdout);
> + #endif
> +- if ((G.ecrec.number_this_disk != 0xFFFF) &&
> ++ if ((G.ecrec.number_this_disk != 0xFFFF) && ecloc64_total_disks &&
> + (G.ecrec.number_this_disk != ecloc64_total_disks - 1)) {
> + /* Note: For some unknown reason, the developers at PKWARE decided to
> + store the "zip64 total disks" value as a counter starting from 1,
> diff --git a/package/unzip/0030-drop-conflicting-declarations.patch b/package/unzip/0030-drop-conflicting-declarations.patch
> new file mode 100644
> index 0000000000..ff32e04d2d
> --- /dev/null
> +++ b/package/unzip/0030-drop-conflicting-declarations.patch
> @@ -0,0 +1,18 @@
> +From: Santiago Vila <sanvila@debian.org>
> +Subject: Drop conflicting declarations of gmtime() and localtime()
> +Bug-Debian: https://bugs.debian.org/1098043
> +X-Debian-version: 6.0-29
> +
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/30-drop-conflicting-declarations.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/unix/unxcfg.h
> ++++ b/unix/unxcfg.h
> +@@ -118,7 +118,7 @@
> + # endif
> + #else
> + # include <time.h>
> +- struct tm *gmtime(), *localtime();
> ++/* struct tm *gmtime(), *localtime(); */
> + #endif
> +
> + #if (defined(BSD4_4) || (defined(SYSV) && defined(MODERN)))
> diff --git a/package/unzip/0031-fix-zipgrep.patch b/package/unzip/0031-fix-zipgrep.patch
> new file mode 100644
> index 0000000000..374ca06f12
> --- /dev/null
> +++ b/package/unzip/0031-fix-zipgrep.patch
> @@ -0,0 +1,20 @@
> +From: Vincent Lefevre <vincent@vinc17.net>
> +Subject: Do not escape shell-special characters in "pat"
> +Bug-Debian: https://bugs.debian.org/1054628
> +X-Debian-version: 6.0-29
> +
> +Upstream: https://sources.debian.org/src/unzip/6.0-29/debian/patches/31-fix-zipgrep.patch
> +Signed-off-by: Thomas Perale <thomas.perale@mind.be>
> +--- a/unix/zipgrep
> ++++ b/unix/zipgrep
> +@@ -49,10 +49,6 @@
> + IFS='
> + '
> +
> +-# Escape shell-special characters in "pat".
> +-pat=` echo "$pat" | \
> +- sed -e 's/\\\\/\\\\\\\\/g' -e 's/|/\\\|/g' -e 's/&/\\\&/g' `
> +-
> + # Use "unzip -Z1" to get a listing of the specified members from the
> + # specified archive. Escape any backslashes in a file name.
> + for i in `unzip -Z1 "$zipfile" ${1+"$@"} | sed -e 's/\\\\/\\\\\\\\/g' `; do
> diff --git a/package/unzip/0001-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch b/package/unzip/0101-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch
> similarity index 99%
> rename from package/unzip/0001-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch
> rename to package/unzip/0101-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch
> index bdb3eae6af..3c4c60f01d 100644
> --- a/package/unzip/0001-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch
> +++ b/package/unzip/0101-Add-a-CMakeFile.txt-to-ease-cross-compilation.patch
> @@ -19,6 +19,7 @@ build options and flags as the original Makefile does.
>
> [0] http://git.buildroot.net/buildroot/tree/package/infozip?id=2015.11-rc3
>
> +Upstream: N/A
> Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
> ---
> CMakeLists.txt | 17 +++++++++++++++++
> diff --git a/package/unzip/unzip.mk b/package/unzip/unzip.mk
> index 8dccaf6ce3..5436c7a46c 100644
> --- a/package/unzip/unzip.mk
> +++ b/package/unzip/unzip.mk
> @@ -6,27 +6,50 @@
>
> UNZIP_VERSION = 6.0
> UNZIP_SOURCE = unzip_$(UNZIP_VERSION).orig.tar.gz
> -UNZIP_PATCH = unzip_$(UNZIP_VERSION)-29.debian.tar.xz
> UNZIP_SITE = https://snapshot.debian.org/archive/debian/20250311T215724Z/pool/main/u/unzip
> UNZIP_LICENSE = Info-ZIP
> UNZIP_LICENSE_FILES = LICENSE
> UNZIP_CPE_ID_VALID = YES
>
> -# unzip_$(UNZIP_VERSION)-29.debian.tar.xz has patches to fix:
> -UNZIP_IGNORE_CVES = \
> - CVE-2014-8139 \
> - CVE-2014-8140 \
> - CVE-2014-8141 \
> - CVE-2014-9636 \
> - CVE-2014-9913 \
> - CVE-2015-7696 \
> - CVE-2015-7697 \
> - CVE-2016-9844 \
> - CVE-2018-18384 \
> - CVE-2018-1000035 \
> - CVE-2019-13232 \
> - CVE-2022-0529 \
> - CVE-2022-0530
> +# 0009-cve-2014-8139-crc-overflow.patch
> +UNZIP_IGNORE_CVES += CVE-2014-8139
> +
> +# 0010-cve-2014-8140-test-compr-eb.patch
> +UNZIP_IGNORE_CVES += CVE-2014-8140
> +
> +# 0011-cve-2014-8141-getzip64data.patch
> +UNZIP_IGNORE_CVES += CVE-2014-8141
> +
> +# 0012-cve-2014-9636-test-compr-eb.patch
> +UNZIP_IGNORE_CVES += CVE-2014-9636
> +
> +# 0018-cve-2014-9913-unzip-buffer-overflow.patch
> +UNZIP_IGNORE_CVES += CVE-2014-9913
> +
> +# 0014-cve-2015-7696.patch
> +UNZIP_IGNORE_CVES += CVE-2015-7696
> +
> +# 0015-cve-2015-7697.patch
> +UNZIP_IGNORE_CVES += CVE-2015-7697
> +
> +# 0019-cve-2016-9844-zipinfo-buffer-overflow.patch
> +UNZIP_IGNORE_CVES += CVE-2016-9844
> +
> +# 0007-increase-size-of-cfactorstr.patch
> +UNZIP_IGNORE_CVES += CVE-2018-18384
> +
> +# 0020-cve-2018-1000035-unzip-buffer-overflow.patch
> +UNZIP_IGNORE_CVES += CVE-2018-1000035
> +
> +# 0022-cve-2019-13232-fix-bug-in-undefer-input.patch
> +# 0023-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
> +# 0024-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
> +# 0025-cve-2019-13232-fix-bug-in-uzbunzip2.patch
> +# 0026-cve-2019-13232-fix-bug-in-uzinflate.patch
> +UNZIP_IGNORE_CVES += CVE-2019-13232
> +
> +# 0028-cve-2022-0529-and-cve-2022-0530.patch
> +UNZIP_IGNORE_CVES += CVE-2022-0529 CVE-2022-0530
>
> # unzip already defines _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE when
> # necessary, redefining it on the command line causes some warnings.
> --
> 2.52.0
>
> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-06-05 12:50 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-04 13:18 [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian Thomas Perale via buildroot
2026-02-04 13:18 ` [Buildroot] [PATCH 2/4] package/heirloom-mailx: " Thomas Perale via buildroot
2026-06-05 12:49 ` Thomas Perale via buildroot
2026-02-04 13:18 ` [Buildroot] [PATCH 3/4] package/libmad: remove Debian patches Thomas Perale via buildroot
2026-06-05 12:49 ` Thomas Perale via buildroot
2026-02-04 13:18 ` [Buildroot] [PATCH 4/4] package/libmad: add patch for CVE-2017-837{2, 3, 4} Thomas Perale via buildroot
2026-06-05 12:49 ` Thomas Perale via buildroot
2026-05-29 9:45 ` [Buildroot] [PATCH 1/4] package/unzip: import patches from Debian Thomas Petazzoni via buildroot
2026-06-05 12:49 ` Thomas Perale via buildroot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox