gnu: libarchive: Replace with libarchive 3.3.3 and fix CVE-2018-{1000877,1000878,1000880}.

* gnu/packages/backup.scm (libarchive)[source, home-page]: Use HTTPS.
[replacement]: New field.
(libarchive-3.3.3): New variable.
* gnu/packages/patches/libarchive-CVE-2018-1000877.patch,
gnu/packages/patches/libarchive-CVE-2018-1000878.patch,
gnu/packages/patches/libarchive-CVE-2018-1000880.patch: New files.
* gnu/local.mk (dist_patch_DATA): Add them.
This commit is contained in:
Alex Vong 2019-01-05 23:20:41 +08:00
parent b7ec276e57
commit c824dedf71
No known key found for this signature in database
GPG Key ID: 61EF502EF60252F2
5 changed files with 206 additions and 3 deletions

View File

@ -9,7 +9,7 @@
# Copyright © 2016 Adonay "adfeno" Felipe Nogueira <https://libreplanet.org/wiki/User:Adfeno> <adfeno@openmailbox.org>
# Copyright © 2016, 2017, 2018 Ricardo Wurmus <rekado@elephly.net>
# Copyright © 2016 Ben Woodcroft <donttrustben@gmail.com>
# Copyright © 2016, 2017, 2018 Alex Vong <alexvong1995@gmail.com>
# Copyright © 2016, 2017, 2018, 2019 Alex Vong <alexvong1995@gmail.com>
# Copyright © 2016, 2017 Efraim Flashner <efraim@flashner.co.il>
# Copyright © 2016, 2017 Jan Nieuwenhuizen <janneke@gnu.org>
# Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
@ -879,6 +879,9 @@ dist_patch_DATA = \
%D%/packages/patches/liba52-use-mtune-not-mcpu.patch \
%D%/packages/patches/libarchive-CVE-2017-14166.patch \
%D%/packages/patches/libarchive-CVE-2017-14502.patch \
%D%/packages/patches/libarchive-CVE-2018-1000877.patch \
%D%/packages/patches/libarchive-CVE-2018-1000878.patch \
%D%/packages/patches/libarchive-CVE-2018-1000880.patch \
%D%/packages/patches/libbase-fix-includes.patch \
%D%/packages/patches/libbase-use-own-logging.patch \
%D%/packages/patches/libbonobo-activation-test-race.patch \

View File

@ -12,6 +12,7 @@
;;; Copyright © 2018 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>
;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2019 Alex Vong <alexvong1995@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@ -194,11 +195,12 @@ backups (called chunks) to allow easy burning to CD/DVD.")
(define-public libarchive
(package
(name "libarchive")
(replacement libarchive-3.3.3)
(version "3.3.2")
(source
(origin
(method url-fetch)
(uri (string-append "http://libarchive.org/downloads/libarchive-"
(uri (string-append "https://libarchive.org/downloads/libarchive-"
version ".tar.gz"))
(patches (search-patches "libarchive-CVE-2017-14166.patch"
"libarchive-CVE-2017-14502.patch"))
@ -258,7 +260,7 @@ backups (called chunks) to allow easy burning to CD/DVD.")
;; libarchive/test/test_write_format_gnutar_filenames.c needs to be
;; compiled with C99 or C11 or a gnu variant.
#:configure-flags '("CFLAGS=-O2 -g -std=c99")))
(home-page "http://libarchive.org/")
(home-page "https://libarchive.org/")
(synopsis "Multi-format archive and compression library")
(description
"Libarchive provides a flexible interface for reading and writing
@ -270,6 +272,22 @@ archive. In particular, note that there is currently no built-in support for
random access nor for in-place modification.")
(license license:bsd-2)))
(define-public libarchive-3.3.3
(package
(inherit libarchive)
(version "3.3.3")
(source
(origin
(method url-fetch)
(uri (string-append "https://libarchive.org/downloads/libarchive-"
version ".tar.gz"))
(patches (search-patches "libarchive-CVE-2018-1000877.patch"
"libarchive-CVE-2018-1000878.patch"
"libarchive-CVE-2018-1000880.patch"))
(sha256
(base32
"0bhfncid058p7n1n8v29l6wxm3mhdqfassscihbsxfwz3iwb2zms"))))))
(define-public rdup
(package
(name "rdup")

View File

@ -0,0 +1,45 @@
Fix CVE-2018-1000877:
https://bugs.launchpad.net/ubuntu/+source/libarchive/+bug/1794909
https://github.com/libarchive/libarchive/pull/1105
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1000877
https://security-tracker.debian.org/tracker/CVE-2018-1000877
Patch copied from upstream source repository:
https://github.com/libarchive/libarchive/commit/021efa522ad729ff0f5806c4ce53e4a6cc1daa31
From 021efa522ad729ff0f5806c4ce53e4a6cc1daa31 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 20 Nov 2018 17:56:29 +1100
Subject: [PATCH] Avoid a double-free when a window size of 0 is specified
new_size can be 0 with a malicious or corrupted RAR archive.
realloc(area, 0) is equivalent to free(area), so the region would
be free()d here and the free()d again in the cleanup function.
Found with a setup running AFL, afl-rb, and qsym.
---
libarchive/archive_read_support_format_rar.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
index 23452222..6f419c27 100644
--- a/libarchive/archive_read_support_format_rar.c
+++ b/libarchive/archive_read_support_format_rar.c
@@ -2300,6 +2300,11 @@ parse_codes(struct archive_read *a)
new_size = DICTIONARY_MAX_SIZE;
else
new_size = rar_fls((unsigned int)rar->unp_size) << 1;
+ if (new_size == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Zero window size is invalid.");
+ return (ARCHIVE_FATAL);
+ }
new_window = realloc(rar->lzss.window, new_size);
if (new_window == NULL) {
archive_set_error(&a->archive, ENOMEM,
--
2.20.1

View File

@ -0,0 +1,86 @@
Fix CVE-2018-1000878:
https://bugs.launchpad.net/ubuntu/+source/libarchive/+bug/1794909
https://github.com/libarchive/libarchive/pull/1105
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1000878
https://security-tracker.debian.org/tracker/CVE-2018-1000878
Patch copied from upstream source repository:
https://github.com/libarchive/libarchive/commit/bfcfe6f04ed20db2504db8a254d1f40a1d84eb28
From bfcfe6f04ed20db2504db8a254d1f40a1d84eb28 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 4 Dec 2018 00:55:22 +1100
Subject: [PATCH] rar: file split across multi-part archives must match
Fuzzing uncovered some UAF and memory overrun bugs where a file in a
single file archive reported that it was split across multiple
volumes. This was caused by ppmd7 operations calling
rar_br_fillup. This would invoke rar_read_ahead, which would in some
situations invoke archive_read_format_rar_read_header. That would
check the new file name against the old file name, and if they didn't
match up it would free the ppmd7 buffer and allocate a new
one. However, because the ppmd7 decoder wasn't actually done with the
buffer, it would continue to used the freed buffer. Both reads and
writes to the freed region can be observed.
This is quite tricky to solve: once the buffer has been freed it is
too late, as the ppmd7 decoder functions almost universally assume
success - there's no way for ppmd_read to signal error, nor are there
good ways for functions like Range_Normalise to propagate them. So we
can't detect after the fact that we're in an invalid state - e.g. by
checking rar->cursor, we have to prevent ourselves from ever ending up
there. So, when we are in the dangerous part or rar_read_ahead that
assumes a valid split, we set a flag force read_header to either go
down the path for split files or bail. This means that the ppmd7
decoder keeps a valid buffer and just runs out of data.
Found with a combination of AFL, afl-rb and qsym.
---
libarchive/archive_read_support_format_rar.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
index 6f419c27..a8cc5c94 100644
--- a/libarchive/archive_read_support_format_rar.c
+++ b/libarchive/archive_read_support_format_rar.c
@@ -258,6 +258,7 @@ struct rar
struct data_block_offsets *dbo;
unsigned int cursor;
unsigned int nodes;
+ char filename_must_match;
/* LZSS members */
struct huffman_code maincode;
@@ -1560,6 +1561,12 @@ read_header(struct archive_read *a, struct archive_entry *entry,
}
return ret;
}
+ else if (rar->filename_must_match)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Mismatch of file parts split across multi-volume archive");
+ return (ARCHIVE_FATAL);
+ }
rar->filename_save = (char*)realloc(rar->filename_save,
filename_size + 1);
@@ -2933,12 +2940,14 @@ rar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
else if (*avail == 0 && rar->main_flags & MHD_VOLUME &&
rar->file_flags & FHD_SPLIT_AFTER)
{
+ rar->filename_must_match = 1;
ret = archive_read_format_rar_read_header(a, a->entry);
if (ret == (ARCHIVE_EOF))
{
rar->has_endarc_header = 1;
ret = archive_read_format_rar_read_header(a, a->entry);
}
+ rar->filename_must_match = 0;
if (ret != (ARCHIVE_OK))
return NULL;
return rar_read_ahead(a, min, avail);
--
2.20.1

View File

@ -0,0 +1,51 @@
Fix CVE-2018-1000880:
https://bugs.launchpad.net/ubuntu/+source/libarchive/+bug/1794909
https://github.com/libarchive/libarchive/pull/1105
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1000880
https://security-tracker.debian.org/tracker/CVE-2018-1000880
Patch copied from upstream source repository:
https://github.com/libarchive/libarchive/commit/9c84b7426660c09c18cc349f6d70b5f8168b5680
From 9c84b7426660c09c18cc349f6d70b5f8168b5680 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 4 Dec 2018 16:33:42 +1100
Subject: [PATCH] warc: consume data once read
The warc decoder only used read ahead, it wouldn't actually consume
data that had previously been printed. This means that if you specify
an invalid content length, it will just reprint the same data over
and over and over again until it hits the desired length.
This means that a WARC resource with e.g.
Content-Length: 666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666665
but only a few hundred bytes of data, causes a quasi-infinite loop.
Consume data in subsequent calls to _warc_read.
Found with an AFL + afl-rb + qsym setup.
---
libarchive/archive_read_support_format_warc.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/libarchive/archive_read_support_format_warc.c b/libarchive/archive_read_support_format_warc.c
index e8753853..e8fc8428 100644
--- a/libarchive/archive_read_support_format_warc.c
+++ b/libarchive/archive_read_support_format_warc.c
@@ -386,6 +386,11 @@ _warc_read(struct archive_read *a, const void **buf, size_t *bsz, int64_t *off)
return (ARCHIVE_EOF);
}
+ if (w->unconsumed) {
+ __archive_read_consume(a, w->unconsumed);
+ w->unconsumed = 0U;
+ }
+
rab = __archive_read_ahead(a, 1U, &nrd);
if (nrd < 0) {
*bsz = 0U;
--
2.20.1