diff options
Diffstat (limited to 'meta/recipes-extended/libarchive/libarchive')
8 files changed, 985 insertions, 0 deletions
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-23177.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-23177.patch new file mode 100644 index 0000000000..555c7a47f7 --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-23177.patch | |||
@@ -0,0 +1,183 @@ | |||
1 | Description: Fix handling of symbolic link ACLs | ||
2 | Published as CVE-2021-23177 | ||
3 | Origin: upstream, https://github.com/libarchive/libarchive/commit/fba4f123cc456d2b2538f811bb831483bf336bad | ||
4 | Bug-Debian: https://bugs.debian.org/1001986 | ||
5 | Author: Martin Matuska <martin@matuska.org> | ||
6 | Last-Updated: 2021-12-20 | ||
7 | |||
8 | CVE: CVE-2021-23177 | ||
9 | Upstream-Status: Backport [http://deb.debian.org/debian/pool/main/liba/libarchive/libarchive_3.4.3-2+deb11u1.debian.tar.xz] | ||
10 | Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> | ||
11 | |||
12 | --- a/libarchive/archive_disk_acl_freebsd.c | ||
13 | +++ b/libarchive/archive_disk_acl_freebsd.c | ||
14 | @@ -319,7 +319,7 @@ | ||
15 | |||
16 | static int | ||
17 | set_acl(struct archive *a, int fd, const char *name, | ||
18 | - struct archive_acl *abstract_acl, | ||
19 | + struct archive_acl *abstract_acl, __LA_MODE_T mode, | ||
20 | int ae_requested_type, const char *tname) | ||
21 | { | ||
22 | int acl_type = 0; | ||
23 | @@ -364,6 +364,13 @@ | ||
24 | return (ARCHIVE_FAILED); | ||
25 | } | ||
26 | |||
27 | + if (acl_type == ACL_TYPE_DEFAULT && !S_ISDIR(mode)) { | ||
28 | + errno = EINVAL; | ||
29 | + archive_set_error(a, errno, | ||
30 | + "Cannot set default ACL on non-directory"); | ||
31 | + return (ARCHIVE_WARN); | ||
32 | + } | ||
33 | + | ||
34 | acl = acl_init(entries); | ||
35 | if (acl == (acl_t)NULL) { | ||
36 | archive_set_error(a, errno, | ||
37 | @@ -542,7 +549,10 @@ | ||
38 | else if (acl_set_link_np(name, acl_type, acl) != 0) | ||
39 | #else | ||
40 | /* FreeBSD older than 8.0 */ | ||
41 | - else if (acl_set_file(name, acl_type, acl) != 0) | ||
42 | + else if (S_ISLNK(mode)) { | ||
43 | + /* acl_set_file() follows symbolic links, skip */ | ||
44 | + ret = ARCHIVE_OK; | ||
45 | + } else if (acl_set_file(name, acl_type, acl) != 0) | ||
46 | #endif | ||
47 | { | ||
48 | if (errno == EOPNOTSUPP) { | ||
49 | @@ -677,14 +687,14 @@ | ||
50 | & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) { | ||
51 | if ((archive_acl_types(abstract_acl) | ||
52 | & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { | ||
53 | - ret = set_acl(a, fd, name, abstract_acl, | ||
54 | + ret = set_acl(a, fd, name, abstract_acl, mode, | ||
55 | ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access"); | ||
56 | if (ret != ARCHIVE_OK) | ||
57 | return (ret); | ||
58 | } | ||
59 | if ((archive_acl_types(abstract_acl) | ||
60 | & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) | ||
61 | - ret = set_acl(a, fd, name, abstract_acl, | ||
62 | + ret = set_acl(a, fd, name, abstract_acl, mode, | ||
63 | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default"); | ||
64 | |||
65 | /* Simultaneous POSIX.1e and NFSv4 is not supported */ | ||
66 | @@ -693,7 +703,7 @@ | ||
67 | #if ARCHIVE_ACL_FREEBSD_NFS4 | ||
68 | else if ((archive_acl_types(abstract_acl) & | ||
69 | ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { | ||
70 | - ret = set_acl(a, fd, name, abstract_acl, | ||
71 | + ret = set_acl(a, fd, name, abstract_acl, mode, | ||
72 | ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4"); | ||
73 | } | ||
74 | #endif | ||
75 | --- a/libarchive/archive_disk_acl_linux.c | ||
76 | +++ b/libarchive/archive_disk_acl_linux.c | ||
77 | @@ -343,6 +343,11 @@ | ||
78 | return (ARCHIVE_FAILED); | ||
79 | } | ||
80 | |||
81 | + if (S_ISLNK(mode)) { | ||
82 | + /* Linux does not support RichACLs on symbolic links */ | ||
83 | + return (ARCHIVE_OK); | ||
84 | + } | ||
85 | + | ||
86 | richacl = richacl_alloc(entries); | ||
87 | if (richacl == NULL) { | ||
88 | archive_set_error(a, errno, | ||
89 | @@ -455,7 +460,7 @@ | ||
90 | #if ARCHIVE_ACL_LIBACL | ||
91 | static int | ||
92 | set_acl(struct archive *a, int fd, const char *name, | ||
93 | - struct archive_acl *abstract_acl, | ||
94 | + struct archive_acl *abstract_acl, __LA_MODE_T mode, | ||
95 | int ae_requested_type, const char *tname) | ||
96 | { | ||
97 | int acl_type = 0; | ||
98 | @@ -488,6 +493,18 @@ | ||
99 | return (ARCHIVE_FAILED); | ||
100 | } | ||
101 | |||
102 | + if (S_ISLNK(mode)) { | ||
103 | + /* Linux does not support ACLs on symbolic links */ | ||
104 | + return (ARCHIVE_OK); | ||
105 | + } | ||
106 | + | ||
107 | + if (acl_type == ACL_TYPE_DEFAULT && !S_ISDIR(mode)) { | ||
108 | + errno = EINVAL; | ||
109 | + archive_set_error(a, errno, | ||
110 | + "Cannot set default ACL on non-directory"); | ||
111 | + return (ARCHIVE_WARN); | ||
112 | + } | ||
113 | + | ||
114 | acl = acl_init(entries); | ||
115 | if (acl == (acl_t)NULL) { | ||
116 | archive_set_error(a, errno, | ||
117 | @@ -727,14 +744,14 @@ | ||
118 | & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) { | ||
119 | if ((archive_acl_types(abstract_acl) | ||
120 | & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { | ||
121 | - ret = set_acl(a, fd, name, abstract_acl, | ||
122 | + ret = set_acl(a, fd, name, abstract_acl, mode, | ||
123 | ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access"); | ||
124 | if (ret != ARCHIVE_OK) | ||
125 | return (ret); | ||
126 | } | ||
127 | if ((archive_acl_types(abstract_acl) | ||
128 | & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) | ||
129 | - ret = set_acl(a, fd, name, abstract_acl, | ||
130 | + ret = set_acl(a, fd, name, abstract_acl, mode, | ||
131 | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default"); | ||
132 | } | ||
133 | #endif /* ARCHIVE_ACL_LIBACL */ | ||
134 | --- a/libarchive/archive_disk_acl_sunos.c | ||
135 | +++ b/libarchive/archive_disk_acl_sunos.c | ||
136 | @@ -443,7 +443,7 @@ | ||
137 | |||
138 | static int | ||
139 | set_acl(struct archive *a, int fd, const char *name, | ||
140 | - struct archive_acl *abstract_acl, | ||
141 | + struct archive_acl *abstract_acl, __LA_MODE_T mode, | ||
142 | int ae_requested_type, const char *tname) | ||
143 | { | ||
144 | aclent_t *aclent; | ||
145 | @@ -467,7 +467,6 @@ | ||
146 | if (entries == 0) | ||
147 | return (ARCHIVE_OK); | ||
148 | |||
149 | - | ||
150 | switch (ae_requested_type) { | ||
151 | case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E: | ||
152 | cmd = SETACL; | ||
153 | @@ -492,6 +491,12 @@ | ||
154 | return (ARCHIVE_FAILED); | ||
155 | } | ||
156 | |||
157 | + if (S_ISLNK(mode)) { | ||
158 | + /* Skip ACLs on symbolic links */ | ||
159 | + ret = ARCHIVE_OK; | ||
160 | + goto exit_free; | ||
161 | + } | ||
162 | + | ||
163 | e = 0; | ||
164 | |||
165 | while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type, | ||
166 | @@ -801,7 +806,7 @@ | ||
167 | if ((archive_acl_types(abstract_acl) | ||
168 | & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) { | ||
169 | /* Solaris writes POSIX.1e access and default ACLs together */ | ||
170 | - ret = set_acl(a, fd, name, abstract_acl, | ||
171 | + ret = set_acl(a, fd, name, abstract_acl, mode, | ||
172 | ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e"); | ||
173 | |||
174 | /* Simultaneous POSIX.1e and NFSv4 is not supported */ | ||
175 | @@ -810,7 +815,7 @@ | ||
176 | #if ARCHIVE_ACL_SUNOS_NFS4 | ||
177 | else if ((archive_acl_types(abstract_acl) & | ||
178 | ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { | ||
179 | - ret = set_acl(a, fd, name, abstract_acl, | ||
180 | + ret = set_acl(a, fd, name, abstract_acl, mode, | ||
181 | ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4"); | ||
182 | } | ||
183 | #endif | ||
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-31566-01.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-31566-01.patch new file mode 100644 index 0000000000..c4a2fb612c --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-31566-01.patch | |||
@@ -0,0 +1,23 @@ | |||
1 | Description: Never follow symlinks when setting file flags on Linux | ||
2 | Published as CVE-2021-31566 | ||
3 | Origin: upstream, https://github.com/libarchive/libarchive/commit/e2ad1a2c3064fa9eba6274b3641c4c1beed25c0b | ||
4 | Bug-Debian: https://bugs.debian.org/1001990 | ||
5 | Author: Martin Matuska <martin@matuska.org> | ||
6 | Last-Update: 2021-12-20 | ||
7 | |||
8 | CVE: CVE-2021-31566 | ||
9 | Upstream-Status: Backport [http://deb.debian.org/debian/pool/main/liba/libarchive/libarchive_3.4.3-2+deb11u1.debian.tar.xz] | ||
10 | Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> | ||
11 | |||
12 | --- a/libarchive/archive_write_disk_posix.c | ||
13 | +++ b/libarchive/archive_write_disk_posix.c | ||
14 | @@ -3927,7 +3927,8 @@ | ||
15 | |||
16 | /* If we weren't given an fd, open it ourselves. */ | ||
17 | if (myfd < 0) { | ||
18 | - myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY | O_CLOEXEC); | ||
19 | + myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY | | ||
20 | + O_CLOEXEC | O_NOFOLLOW); | ||
21 | __archive_ensure_cloexec_flag(myfd); | ||
22 | } | ||
23 | if (myfd < 0) | ||
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-31566-02.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-31566-02.patch new file mode 100644 index 0000000000..0dfcd1ac5c --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-31566-02.patch | |||
@@ -0,0 +1,172 @@ | |||
1 | Description: Do not follow symlinks when processing the fixup list | ||
2 | Published as CVE-2021-31566 | ||
3 | Origin: upstream, https://github.com/libarchive/libarchive/commit/b41daecb5ccb4c8e3b2c53fd6147109fc12c3043 | ||
4 | Bug-Debian: https://bugs.debian.org/1001990 | ||
5 | Author: Martin Matuska <martin@matuska.org> | ||
6 | Last-Update: 2021-12-20 | ||
7 | |||
8 | CVE: CVE-2021-31566 | ||
9 | Upstream-Status: Backport [http://deb.debian.org/debian/pool/main/liba/libarchive/libarchive_3.4.3-2+deb11u1.debian.tar.xz] | ||
10 | Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> | ||
11 | |||
12 | --- a/Makefile.am | ||
13 | +++ b/Makefile.am | ||
14 | @@ -556,6 +556,7 @@ | ||
15 | libarchive/test/test_write_disk.c \ | ||
16 | libarchive/test/test_write_disk_appledouble.c \ | ||
17 | libarchive/test/test_write_disk_failures.c \ | ||
18 | + libarchive/test/test_write_disk_fixup.c \ | ||
19 | libarchive/test/test_write_disk_hardlink.c \ | ||
20 | libarchive/test/test_write_disk_hfs_compression.c \ | ||
21 | libarchive/test/test_write_disk_lookup.c \ | ||
22 | --- a/libarchive/archive_write_disk_posix.c | ||
23 | +++ b/libarchive/archive_write_disk_posix.c | ||
24 | @@ -2461,6 +2461,7 @@ | ||
25 | { | ||
26 | struct archive_write_disk *a = (struct archive_write_disk *)_a; | ||
27 | struct fixup_entry *next, *p; | ||
28 | + struct stat st; | ||
29 | int fd, ret; | ||
30 | |||
31 | archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, | ||
32 | @@ -2478,6 +2479,20 @@ | ||
33 | (TODO_TIMES | TODO_MODE_BASE | TODO_ACLS | TODO_FFLAGS)) { | ||
34 | fd = open(p->name, | ||
35 | O_WRONLY | O_BINARY | O_NOFOLLOW | O_CLOEXEC); | ||
36 | + if (fd == -1) { | ||
37 | + /* If we cannot lstat, skip entry */ | ||
38 | + if (lstat(p->name, &st) != 0) | ||
39 | + goto skip_fixup_entry; | ||
40 | + /* | ||
41 | + * If we deal with a symbolic link, mark | ||
42 | + * it in the fixup mode to ensure no | ||
43 | + * modifications are made to its target. | ||
44 | + */ | ||
45 | + if (S_ISLNK(st.st_mode)) { | ||
46 | + p->mode &= ~S_IFMT; | ||
47 | + p->mode |= S_IFLNK; | ||
48 | + } | ||
49 | + } | ||
50 | } | ||
51 | if (p->fixup & TODO_TIMES) { | ||
52 | set_times(a, fd, p->mode, p->name, | ||
53 | @@ -2492,7 +2507,12 @@ | ||
54 | fchmod(fd, p->mode); | ||
55 | else | ||
56 | #endif | ||
57 | - chmod(p->name, p->mode); | ||
58 | +#ifdef HAVE_LCHMOD | ||
59 | + lchmod(p->name, p->mode); | ||
60 | +#else | ||
61 | + if (!S_ISLNK(p->mode)) | ||
62 | + chmod(p->name, p->mode); | ||
63 | +#endif | ||
64 | } | ||
65 | if (p->fixup & TODO_ACLS) | ||
66 | archive_write_disk_set_acls(&a->archive, fd, | ||
67 | @@ -2503,6 +2523,7 @@ | ||
68 | if (p->fixup & TODO_MAC_METADATA) | ||
69 | set_mac_metadata(a, p->name, p->mac_metadata, | ||
70 | p->mac_metadata_size); | ||
71 | +skip_fixup_entry: | ||
72 | next = p->next; | ||
73 | archive_acl_clear(&p->acl); | ||
74 | free(p->mac_metadata); | ||
75 | @@ -2643,6 +2664,7 @@ | ||
76 | fe->next = a->fixup_list; | ||
77 | a->fixup_list = fe; | ||
78 | fe->fixup = 0; | ||
79 | + fe->mode = 0; | ||
80 | fe->name = strdup(pathname); | ||
81 | return (fe); | ||
82 | } | ||
83 | --- a/libarchive/test/CMakeLists.txt | ||
84 | +++ b/libarchive/test/CMakeLists.txt | ||
85 | @@ -208,6 +208,7 @@ | ||
86 | test_write_disk.c | ||
87 | test_write_disk_appledouble.c | ||
88 | test_write_disk_failures.c | ||
89 | + test_write_disk_fixup.c | ||
90 | test_write_disk_hardlink.c | ||
91 | test_write_disk_hfs_compression.c | ||
92 | test_write_disk_lookup.c | ||
93 | --- /dev/null | ||
94 | +++ b/libarchive/test/test_write_disk_fixup.c | ||
95 | @@ -0,0 +1,77 @@ | ||
96 | +/*- | ||
97 | + * Copyright (c) 2021 Martin Matuska | ||
98 | + * All rights reserved. | ||
99 | + * | ||
100 | + * Redistribution and use in source and binary forms, with or without | ||
101 | + * modification, are permitted provided that the following conditions | ||
102 | + * are met: | ||
103 | + * 1. Redistributions of source code must retain the above copyright | ||
104 | + * notice, this list of conditions and the following disclaimer. | ||
105 | + * 2. Redistributions in binary form must reproduce the above copyright | ||
106 | + * notice, this list of conditions and the following disclaimer in the | ||
107 | + * documentation and/or other materials provided with the distribution. | ||
108 | + * | ||
109 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR | ||
110 | + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
111 | + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
112 | + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
113 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
114 | + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
115 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
116 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
117 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
118 | + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
119 | + */ | ||
120 | +#include "test.h" | ||
121 | + | ||
122 | +/* | ||
123 | + * Test fixup entries don't follow symlinks | ||
124 | + */ | ||
125 | +DEFINE_TEST(test_write_disk_fixup) | ||
126 | +{ | ||
127 | + struct archive *ad; | ||
128 | + struct archive_entry *ae; | ||
129 | + int r; | ||
130 | + | ||
131 | + if (!canSymlink()) { | ||
132 | + skipping("Symlinks not supported"); | ||
133 | + return; | ||
134 | + } | ||
135 | + | ||
136 | + /* Write entries to disk. */ | ||
137 | + assert((ad = archive_write_disk_new()) != NULL); | ||
138 | + | ||
139 | + /* | ||
140 | + * Create a file | ||
141 | + */ | ||
142 | + assertMakeFile("victim", 0600, "a"); | ||
143 | + | ||
144 | + /* | ||
145 | + * Create a directory and a symlink with the same name | ||
146 | + */ | ||
147 | + | ||
148 | + /* Directory: dir */ | ||
149 | + assert((ae = archive_entry_new()) != NULL); | ||
150 | + archive_entry_copy_pathname(ae, "dir"); | ||
151 | + archive_entry_set_mode(ae, AE_IFDIR | 0606); | ||
152 | + assertEqualIntA(ad, 0, archive_write_header(ad, ae)); | ||
153 | + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); | ||
154 | + archive_entry_free(ae); | ||
155 | + | ||
156 | + /* Symbolic Link: dir -> foo */ | ||
157 | + assert((ae = archive_entry_new()) != NULL); | ||
158 | + archive_entry_copy_pathname(ae, "dir"); | ||
159 | + archive_entry_set_mode(ae, AE_IFLNK | 0777); | ||
160 | + archive_entry_set_size(ae, 0); | ||
161 | + archive_entry_copy_symlink(ae, "victim"); | ||
162 | + assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); | ||
163 | + if (r >= ARCHIVE_WARN) | ||
164 | + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); | ||
165 | + archive_entry_free(ae); | ||
166 | + | ||
167 | + assertEqualInt(ARCHIVE_OK, archive_write_free(ad)); | ||
168 | + | ||
169 | + /* Test the entries on disk. */ | ||
170 | + assertIsSymlink("dir", "victim", 0); | ||
171 | + assertFileMode("victim", 0600); | ||
172 | +} | ||
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch new file mode 100644 index 0000000000..fca53fc9b6 --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch | |||
@@ -0,0 +1,321 @@ | |||
1 | From 05ebb55896d10a9737dad9ae0303f7f45489ba6f Mon Sep 17 00:00:00 2001 | ||
2 | From: Grzegorz Antoniak <ga@anadoxin.org> | ||
3 | Date: Sat, 13 Feb 2021 09:08:13 +0100 | ||
4 | Subject: [PATCH] RAR5 reader: fixed out of bounds read in some files | ||
5 | |||
6 | Added more range checks in the bit stream reading functions | ||
7 | (read_bits_16 and read_bits_32) in order to better guard against out of | ||
8 | memory reads. | ||
9 | |||
10 | This commit contains a test with OSSFuzz sample #30448. | ||
11 | |||
12 | Upstream-Status: Backport [https://git.launchpad.net/ubuntu/+source/libarchive/plain/debian/patches/CVE-2021-36976-1.patch?h=applied/3.4.3-2ubuntu0.1] | ||
13 | CVE: CVE-2021-36976 | ||
14 | Signed-off-by: Virendra Thakur <virendra.thakur@kpit.com> | ||
15 | --- | ||
16 | Makefile.am | 1 + | ||
17 | libarchive/archive_read_support_format_rar5.c | 108 ++++++++++-------- | ||
18 | libarchive/test/test_read_format_rar5.c | 16 +++ | ||
19 | ...r5_decode_number_out_of_bounds_read.rar.uu | 10 ++ | ||
20 | 4 files changed, 89 insertions(+), 46 deletions(-) | ||
21 | create mode 100644 libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu | ||
22 | |||
23 | --- a/Makefile.am | ||
24 | +++ b/Makefile.am | ||
25 | @@ -883,6 +883,7 @@ libarchive_test_EXTRA_DIST=\ | ||
26 | libarchive/test/test_read_format_rar5_arm_filter_on_window_boundary.rar.uu \ | ||
27 | libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \ | ||
28 | libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ | ||
29 | + libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ | ||
30 | libarchive/test/test_read_format_raw.bufr.uu \ | ||
31 | libarchive/test/test_read_format_raw.data.gz.uu \ | ||
32 | libarchive/test/test_read_format_raw.data.Z.uu \ | ||
33 | --- a/libarchive/archive_read_support_format_rar5.c | ||
34 | +++ b/libarchive/archive_read_support_format_rar5.c | ||
35 | @@ -1012,7 +1012,16 @@ static int read_var_sized(struct archive | ||
36 | return ret; | ||
37 | } | ||
38 | |||
39 | -static int read_bits_32(struct rar5* rar, const uint8_t* p, uint32_t* value) { | ||
40 | +static int read_bits_32(struct archive_read* a, struct rar5* rar, | ||
41 | + const uint8_t* p, uint32_t* value) | ||
42 | +{ | ||
43 | + if(rar->bits.in_addr >= rar->cstate.cur_block_size) { | ||
44 | + archive_set_error(&a->archive, | ||
45 | + ARCHIVE_ERRNO_PROGRAMMER, | ||
46 | + "Premature end of stream during extraction of data (#1)"); | ||
47 | + return ARCHIVE_FATAL; | ||
48 | + } | ||
49 | + | ||
50 | uint32_t bits = ((uint32_t) p[rar->bits.in_addr]) << 24; | ||
51 | bits |= p[rar->bits.in_addr + 1] << 16; | ||
52 | bits |= p[rar->bits.in_addr + 2] << 8; | ||
53 | @@ -1023,7 +1032,16 @@ static int read_bits_32(struct rar5* rar | ||
54 | return ARCHIVE_OK; | ||
55 | } | ||
56 | |||
57 | -static int read_bits_16(struct rar5* rar, const uint8_t* p, uint16_t* value) { | ||
58 | +static int read_bits_16(struct archive_read* a, struct rar5* rar, | ||
59 | + const uint8_t* p, uint16_t* value) | ||
60 | +{ | ||
61 | + if(rar->bits.in_addr >= rar->cstate.cur_block_size) { | ||
62 | + archive_set_error(&a->archive, | ||
63 | + ARCHIVE_ERRNO_PROGRAMMER, | ||
64 | + "Premature end of stream during extraction of data (#2)"); | ||
65 | + return ARCHIVE_FATAL; | ||
66 | + } | ||
67 | + | ||
68 | int bits = (int) ((uint32_t) p[rar->bits.in_addr]) << 16; | ||
69 | bits |= (int) p[rar->bits.in_addr + 1] << 8; | ||
70 | bits |= (int) p[rar->bits.in_addr + 2]; | ||
71 | @@ -1039,8 +1057,8 @@ static void skip_bits(struct rar5* rar, | ||
72 | } | ||
73 | |||
74 | /* n = up to 16 */ | ||
75 | -static int read_consume_bits(struct rar5* rar, const uint8_t* p, int n, | ||
76 | - int* value) | ||
77 | +static int read_consume_bits(struct archive_read* a, struct rar5* rar, | ||
78 | + const uint8_t* p, int n, int* value) | ||
79 | { | ||
80 | uint16_t v; | ||
81 | int ret, num; | ||
82 | @@ -1051,7 +1069,7 @@ static int read_consume_bits(struct rar5 | ||
83 | return ARCHIVE_FATAL; | ||
84 | } | ||
85 | |||
86 | - ret = read_bits_16(rar, p, &v); | ||
87 | + ret = read_bits_16(a, rar, p, &v); | ||
88 | if(ret != ARCHIVE_OK) | ||
89 | return ret; | ||
90 | |||
91 | @@ -2425,13 +2443,13 @@ static int create_decode_tables(uint8_t* | ||
92 | static int decode_number(struct archive_read* a, struct decode_table* table, | ||
93 | const uint8_t* p, uint16_t* num) | ||
94 | { | ||
95 | - int i, bits, dist; | ||
96 | + int i, bits, dist, ret; | ||
97 | uint16_t bitfield; | ||
98 | uint32_t pos; | ||
99 | struct rar5* rar = get_context(a); | ||
100 | |||
101 | - if(ARCHIVE_OK != read_bits_16(rar, p, &bitfield)) { | ||
102 | - return ARCHIVE_EOF; | ||
103 | + if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &bitfield))) { | ||
104 | + return ret; | ||
105 | } | ||
106 | |||
107 | bitfield &= 0xfffe; | ||
108 | @@ -2537,14 +2555,6 @@ static int parse_tables(struct archive_r | ||
109 | for(i = 0; i < HUFF_TABLE_SIZE;) { | ||
110 | uint16_t num; | ||
111 | |||
112 | - if((rar->bits.in_addr + 6) >= rar->cstate.cur_block_size) { | ||
113 | - /* Truncated data, can't continue. */ | ||
114 | - archive_set_error(&a->archive, | ||
115 | - ARCHIVE_ERRNO_FILE_FORMAT, | ||
116 | - "Truncated data in huffman tables (#2)"); | ||
117 | - return ARCHIVE_FATAL; | ||
118 | - } | ||
119 | - | ||
120 | ret = decode_number(a, &rar->cstate.bd, p, &num); | ||
121 | if(ret != ARCHIVE_OK) { | ||
122 | archive_set_error(&a->archive, | ||
123 | @@ -2561,8 +2571,8 @@ static int parse_tables(struct archive_r | ||
124 | /* 16..17: repeat previous code */ | ||
125 | uint16_t n; | ||
126 | |||
127 | - if(ARCHIVE_OK != read_bits_16(rar, p, &n)) | ||
128 | - return ARCHIVE_EOF; | ||
129 | + if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n))) | ||
130 | + return ret; | ||
131 | |||
132 | if(num == 16) { | ||
133 | n >>= 13; | ||
134 | @@ -2590,8 +2600,8 @@ static int parse_tables(struct archive_r | ||
135 | /* other codes: fill with zeroes `n` times */ | ||
136 | uint16_t n; | ||
137 | |||
138 | - if(ARCHIVE_OK != read_bits_16(rar, p, &n)) | ||
139 | - return ARCHIVE_EOF; | ||
140 | + if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n))) | ||
141 | + return ret; | ||
142 | |||
143 | if(num == 18) { | ||
144 | n >>= 13; | ||
145 | @@ -2707,22 +2717,22 @@ static int parse_block_header(struct arc | ||
146 | } | ||
147 | |||
148 | /* Convenience function used during filter processing. */ | ||
149 | -static int parse_filter_data(struct rar5* rar, const uint8_t* p, | ||
150 | - uint32_t* filter_data) | ||
151 | +static int parse_filter_data(struct archive_read* a, struct rar5* rar, | ||
152 | + const uint8_t* p, uint32_t* filter_data) | ||
153 | { | ||
154 | - int i, bytes; | ||
155 | + int i, bytes, ret; | ||
156 | uint32_t data = 0; | ||
157 | |||
158 | - if(ARCHIVE_OK != read_consume_bits(rar, p, 2, &bytes)) | ||
159 | - return ARCHIVE_EOF; | ||
160 | + if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, p, 2, &bytes))) | ||
161 | + return ret; | ||
162 | |||
163 | bytes++; | ||
164 | |||
165 | for(i = 0; i < bytes; i++) { | ||
166 | uint16_t byte; | ||
167 | |||
168 | - if(ARCHIVE_OK != read_bits_16(rar, p, &byte)) { | ||
169 | - return ARCHIVE_EOF; | ||
170 | + if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &byte))) { | ||
171 | + return ret; | ||
172 | } | ||
173 | |||
174 | /* Cast to uint32_t will ensure the shift operation will not | ||
175 | @@ -2765,16 +2775,17 @@ static int parse_filter(struct archive_r | ||
176 | uint16_t filter_type; | ||
177 | struct filter_info* filt = NULL; | ||
178 | struct rar5* rar = get_context(ar); | ||
179 | + int ret; | ||
180 | |||
181 | /* Read the parameters from the input stream. */ | ||
182 | - if(ARCHIVE_OK != parse_filter_data(rar, p, &block_start)) | ||
183 | - return ARCHIVE_EOF; | ||
184 | + if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_start))) | ||
185 | + return ret; | ||
186 | |||
187 | - if(ARCHIVE_OK != parse_filter_data(rar, p, &block_length)) | ||
188 | - return ARCHIVE_EOF; | ||
189 | + if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_length))) | ||
190 | + return ret; | ||
191 | |||
192 | - if(ARCHIVE_OK != read_bits_16(rar, p, &filter_type)) | ||
193 | - return ARCHIVE_EOF; | ||
194 | + if(ARCHIVE_OK != (ret = read_bits_16(ar, rar, p, &filter_type))) | ||
195 | + return ret; | ||
196 | |||
197 | filter_type >>= 13; | ||
198 | skip_bits(rar, 3); | ||
199 | @@ -2814,8 +2825,8 @@ static int parse_filter(struct archive_r | ||
200 | if(filter_type == FILTER_DELTA) { | ||
201 | int channels; | ||
202 | |||
203 | - if(ARCHIVE_OK != read_consume_bits(rar, p, 5, &channels)) | ||
204 | - return ARCHIVE_EOF; | ||
205 | + if(ARCHIVE_OK != (ret = read_consume_bits(ar, rar, p, 5, &channels))) | ||
206 | + return ret; | ||
207 | |||
208 | filt->channels = channels + 1; | ||
209 | } | ||
210 | @@ -2823,10 +2834,11 @@ static int parse_filter(struct archive_r | ||
211 | return ARCHIVE_OK; | ||
212 | } | ||
213 | |||
214 | -static int decode_code_length(struct rar5* rar, const uint8_t* p, | ||
215 | - uint16_t code) | ||
216 | +static int decode_code_length(struct archive_read* a, struct rar5* rar, | ||
217 | + const uint8_t* p, uint16_t code) | ||
218 | { | ||
219 | int lbits, length = 2; | ||
220 | + | ||
221 | if(code < 8) { | ||
222 | lbits = 0; | ||
223 | length += code; | ||
224 | @@ -2838,7 +2850,7 @@ static int decode_code_length(struct rar | ||
225 | if(lbits > 0) { | ||
226 | int add; | ||
227 | |||
228 | - if(ARCHIVE_OK != read_consume_bits(rar, p, lbits, &add)) | ||
229 | + if(ARCHIVE_OK != read_consume_bits(a, rar, p, lbits, &add)) | ||
230 | return -1; | ||
231 | |||
232 | length += add; | ||
233 | @@ -2933,7 +2945,7 @@ static int do_uncompress_block(struct ar | ||
234 | continue; | ||
235 | } else if(num >= 262) { | ||
236 | uint16_t dist_slot; | ||
237 | - int len = decode_code_length(rar, p, num - 262), | ||
238 | + int len = decode_code_length(a, rar, p, num - 262), | ||
239 | dbits, | ||
240 | dist = 1; | ||
241 | |||
242 | @@ -2975,12 +2987,12 @@ static int do_uncompress_block(struct ar | ||
243 | uint16_t low_dist; | ||
244 | |||
245 | if(dbits > 4) { | ||
246 | - if(ARCHIVE_OK != read_bits_32( | ||
247 | - rar, p, &add)) { | ||
248 | + if(ARCHIVE_OK != (ret = read_bits_32( | ||
249 | + a, rar, p, &add))) { | ||
250 | /* Return EOF if we | ||
251 | * can't read more | ||
252 | * data. */ | ||
253 | - return ARCHIVE_EOF; | ||
254 | + return ret; | ||
255 | } | ||
256 | |||
257 | skip_bits(rar, dbits - 4); | ||
258 | @@ -3015,11 +3027,11 @@ static int do_uncompress_block(struct ar | ||
259 | /* dbits is one of [0,1,2,3] */ | ||
260 | int add; | ||
261 | |||
262 | - if(ARCHIVE_OK != read_consume_bits(rar, | ||
263 | - p, dbits, &add)) { | ||
264 | + if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, | ||
265 | + p, dbits, &add))) { | ||
266 | /* Return EOF if we can't read | ||
267 | * more data. */ | ||
268 | - return ARCHIVE_EOF; | ||
269 | + return ret; | ||
270 | } | ||
271 | |||
272 | dist += add; | ||
273 | @@ -3076,7 +3088,11 @@ static int do_uncompress_block(struct ar | ||
274 | return ARCHIVE_FATAL; | ||
275 | } | ||
276 | |||
277 | - len = decode_code_length(rar, p, len_slot); | ||
278 | + len = decode_code_length(a, rar, p, len_slot); | ||
279 | + if (len == -1) { | ||
280 | + return ARCHIVE_FATAL; | ||
281 | + } | ||
282 | + | ||
283 | rar->cstate.last_len = len; | ||
284 | |||
285 | if(ARCHIVE_OK != copy_string(a, len, dist)) | ||
286 | --- a/libarchive/test/test_read_format_rar5.c | ||
287 | +++ b/libarchive/test/test_read_format_rar5.c | ||
288 | @@ -1271,3 +1271,20 @@ DEFINE_TEST(test_read_format_rar5_block_ | ||
289 | |||
290 | EPILOGUE(); | ||
291 | } | ||
292 | + | ||
293 | +DEFINE_TEST(test_read_format_rar5_decode_number_out_of_bounds_read) | ||
294 | +{ | ||
295 | + /* oss fuzz 30448 */ | ||
296 | + | ||
297 | + char buf[4096]; | ||
298 | + PROLOGUE("test_read_format_rar5_decode_number_out_of_bounds_read.rar"); | ||
299 | + | ||
300 | + /* Return codes of those calls are ignored, because this sample file | ||
301 | + * is invalid. However, the unpacker shouldn't produce any SIGSEGV | ||
302 | + * errors during processing. */ | ||
303 | + | ||
304 | + (void) archive_read_next_header(a, &ae); | ||
305 | + while(0 < archive_read_data(a, buf, sizeof(buf))) {} | ||
306 | + | ||
307 | + EPILOGUE(); | ||
308 | +} | ||
309 | --- /dev/null | ||
310 | +++ b/libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu | ||
311 | @@ -0,0 +1,10 @@ | ||
312 | +begin 644 test_read_format_rar5_decode_number_out_of_bounds_read.rar | ||
313 | +M4F%R(1H'`0!3@"KT`P+G(@(0("`@@`L!!"`@("`@(($D_[BJ2"!::7!)210V | ||
314 | +M+0#ZF#)Q!`+>YPW_("`@("``_R````````````````````````````!__P`` | ||
315 | +M``````!T72`@/EW_(/\@("`@("`@("`@("`@("`@("`@("`@("`@(/\@("`@ | ||
316 | +M("`@("#_("`@("`@("`@("`@("`@("`@("`@("`@("#_("`@("`@("`@_R`@ | ||
317 | +M("`@("`@("`@("`@("`@("`@("`@("`@_R`@("`@("`@(/\@("`@("`@("`@ | ||
318 | +M("`@("`@("`@("`@("`@(/\@("`@("`@("#_("`@("`@("`@("`@("`@("`@ | ||
319 | +E("`@("`@("#_("`@("`@("`@_R`@("`@("`@("`@("`@("`@(``` | ||
320 | +` | ||
321 | +end | ||
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch new file mode 100644 index 0000000000..b5da44ec7b --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch | |||
@@ -0,0 +1,121 @@ | |||
1 | From 17f4e83c0f0fc3bacf4b2bbacb01f987bb5aff5f Mon Sep 17 00:00:00 2001 | ||
2 | From: Grzegorz Antoniak <ga@anadoxin.org> | ||
3 | Date: Fri, 12 Feb 2021 20:18:31 +0100 | ||
4 | Subject: [PATCH] RAR5 reader: fix invalid memory access in some files | ||
5 | |||
6 | RAR5 reader uses several variables to manage the window buffer during | ||
7 | extraction: the buffer itself (`window_buf`), the current size of the | ||
8 | window buffer (`window_size`), and a helper variable (`window_mask`) | ||
9 | that is used to constrain read and write offsets to the window buffer. | ||
10 | |||
11 | Some specially crafted files can force the unpacker to update the | ||
12 | `window_mask` variable to a value that is out of sync with current | ||
13 | buffer size. If the `window_mask` will be bigger than the actual buffer | ||
14 | size, then an invalid access operation can happen (SIGSEGV). | ||
15 | |||
16 | This commit ensures that if the `window_size` and `window_mask` will be | ||
17 | changed, the window buffer will be reallocated to the proper size, so no | ||
18 | invalid memory operation should be possible. | ||
19 | |||
20 | This commit contains a test file from OSSFuzz #30442. | ||
21 | |||
22 | Upstream-Status: Backport [https://git.launchpad.net/ubuntu/+source/libarchive/plain/debian/patches/CVE-2021-36976-2.patch?h=applied/3.4.3-2ubuntu0.1] | ||
23 | CVE: CVE-2021-36976 | ||
24 | Signed-off-by: Virendra Thakur <virendra.thakur@kpit.com> | ||
25 | |||
26 | --- | ||
27 | Makefile.am | 1 + | ||
28 | libarchive/archive_read_support_format_rar5.c | 27 ++++++++++++++----- | ||
29 | libarchive/test/test_read_format_rar5.c | 17 ++++++++++++ | ||
30 | ...mat_rar5_window_buf_and_size_desync.rar.uu | 11 ++++++++ | ||
31 | 4 files changed, 50 insertions(+), 6 deletions(-) | ||
32 | create mode 100644 libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu | ||
33 | |||
34 | --- a/Makefile.am | ||
35 | +++ b/Makefile.am | ||
36 | @@ -884,6 +884,7 @@ libarchive_test_EXTRA_DIST=\ | ||
37 | libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \ | ||
38 | libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ | ||
39 | libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ | ||
40 | + libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \ | ||
41 | libarchive/test/test_read_format_raw.bufr.uu \ | ||
42 | libarchive/test/test_read_format_raw.data.gz.uu \ | ||
43 | libarchive/test/test_read_format_raw.data.Z.uu \ | ||
44 | --- a/libarchive/archive_read_support_format_rar5.c | ||
45 | +++ b/libarchive/archive_read_support_format_rar5.c | ||
46 | @@ -1730,14 +1730,29 @@ static int process_head_file(struct arch | ||
47 | } | ||
48 | } | ||
49 | |||
50 | - /* If we're currently switching volumes, ignore the new definition of | ||
51 | - * window_size. */ | ||
52 | - if(rar->cstate.switch_multivolume == 0) { | ||
53 | - /* Values up to 64M should fit into ssize_t on every | ||
54 | - * architecture. */ | ||
55 | - rar->cstate.window_size = (ssize_t) window_size; | ||
56 | + if(rar->cstate.window_size < (ssize_t) window_size && | ||
57 | + rar->cstate.window_buf) | ||
58 | + { | ||
59 | + /* If window_buf has been allocated before, reallocate it, so | ||
60 | + * that its size will match new window_size. */ | ||
61 | + | ||
62 | + uint8_t* new_window_buf = | ||
63 | + realloc(rar->cstate.window_buf, window_size); | ||
64 | + | ||
65 | + if(!new_window_buf) { | ||
66 | + archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, | ||
67 | + "Not enough memory when trying to realloc the window " | ||
68 | + "buffer."); | ||
69 | + return ARCHIVE_FATAL; | ||
70 | + } | ||
71 | + | ||
72 | + rar->cstate.window_buf = new_window_buf; | ||
73 | } | ||
74 | |||
75 | + /* Values up to 64M should fit into ssize_t on every | ||
76 | + * architecture. */ | ||
77 | + rar->cstate.window_size = (ssize_t) window_size; | ||
78 | + | ||
79 | if(rar->file.solid > 0 && rar->file.solid_window_size == 0) { | ||
80 | /* Solid files have to have the same window_size across | ||
81 | whole archive. Remember the window_size parameter | ||
82 | --- a/libarchive/test/test_read_format_rar5.c | ||
83 | +++ b/libarchive/test/test_read_format_rar5.c | ||
84 | @@ -1206,6 +1206,23 @@ DEFINE_TEST(test_read_format_rar5_differ | ||
85 | EPILOGUE(); | ||
86 | } | ||
87 | |||
88 | +DEFINE_TEST(test_read_format_rar5_window_buf_and_size_desync) | ||
89 | +{ | ||
90 | + /* oss fuzz 30442 */ | ||
91 | + | ||
92 | + char buf[4096]; | ||
93 | + PROLOGUE("test_read_format_rar5_window_buf_and_size_desync.rar"); | ||
94 | + | ||
95 | + /* Return codes of those calls are ignored, because this sample file | ||
96 | + * is invalid. However, the unpacker shouldn't produce any SIGSEGV | ||
97 | + * errors during processing. */ | ||
98 | + | ||
99 | + (void) archive_read_next_header(a, &ae); | ||
100 | + while(0 < archive_read_data(a, buf, 46)) {} | ||
101 | + | ||
102 | + EPILOGUE(); | ||
103 | +} | ||
104 | + | ||
105 | DEFINE_TEST(test_read_format_rar5_arm_filter_on_window_boundary) | ||
106 | { | ||
107 | char buf[4096]; | ||
108 | --- /dev/null | ||
109 | +++ b/libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu | ||
110 | @@ -0,0 +1,11 @@ | ||
111 | +begin 644 test_read_format_rar5_window_buf_and_size_desync.rar | ||
112 | +M4F%R(1H'`0`]/-[E`@$`_P$`1#[Z5P("`PL``BXB"?\`!(@B@0`)6.-AF?_1 | ||
113 | +M^0DI&0GG(F%R(0<:)`!3@"KT`P+G(@O_X[\``#&``(?!!0$$[:L``$.M*E)A | ||
114 | +M<B$`O<\>P0";/P1%``A*2DI*2DYQ<6TN9'%*2DI*2DI*``!D<F--``````"Z | ||
115 | +MNC*ZNKJZNFYO=&%I;+JZNKJZNKJZOKJZ.KJZNKJZNKKZU@4%````0$!`0$!` | ||
116 | +M0$!`0$!`0$!`0$#_________/T#`0$!`0$!`-UM`0$!`0$!`0$!`0$!`0$!` | ||
117 | +M0$!`0'!,J+:O!IZ-WN4'@`!3*F0````````````````````````````````` | ||
118 | +M``````````````#T`P)287(A&@<!`%.`*O0#`N<B`_,F@`'[__\``(`4`01S | ||
119 | +J'`/H/O\H@?\D`#O9GIZ>GN<B"_]%``(``&1RGIZ>GIZ>8_^>GE/_``!. | ||
120 | +` | ||
121 | +end | ||
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch new file mode 100644 index 0000000000..0e1549f229 --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch | |||
@@ -0,0 +1,93 @@ | |||
1 | From 313bcd7ac547f7cc25945831f63507420c0874d7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Grzegorz Antoniak <ga@anadoxin.org> | ||
3 | Date: Sat, 13 Feb 2021 10:13:22 +0100 | ||
4 | Subject: [PATCH] RAR5 reader: add more checks for invalid extraction | ||
5 | parameters | ||
6 | |||
7 | Some specially crafted files declare invalid extraction parameters that | ||
8 | can confuse the RAR5 reader. | ||
9 | |||
10 | One of the arguments is the declared window size parameter that the | ||
11 | archive file can declare for each file stored in the archive. Some | ||
12 | crafted files declare window size equal to 0, which is clearly wrong. | ||
13 | |||
14 | This commit adds additional safety checks decreasing the tolerance of | ||
15 | the RAR5 format. | ||
16 | |||
17 | This commit also contains OSSFuzz sample #30459. | ||
18 | --- | ||
19 | Makefile.am | 1 + | ||
20 | libarchive/archive_read_support_format_rar5.c | 10 ++++++++++ | ||
21 | libarchive/test/test_read_format_rar5.c | 19 +++++++++++++++++++ | ||
22 | ...t_rar5_bad_window_sz_in_mltarc_file.rar.uu | 7 +++++++ | ||
23 | 4 files changed, 37 insertions(+) | ||
24 | create mode 100644 libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu | ||
25 | |||
26 | Upstream-Status: Backport [https://github.com/libarchive/libarchive/pull/1493/commits/313bcd7ac547f7cc25945831f63507420c0874d7] | ||
27 | CVE: CVE-2021-36976 | ||
28 | Signed-off-by: Virendra Thakur <virendra.thakur@kpit.com> | ||
29 | |||
30 | --- libarchive-3.4.2.orig/Makefile.am | ||
31 | +++ libarchive-3.4.2/Makefile.am | ||
32 | @@ -882,6 +882,7 @@ libarchive_test_EXTRA_DIST=\ | ||
33 | libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ | ||
34 | libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ | ||
35 | libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \ | ||
36 | + libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu \ | ||
37 | libarchive/test/test_read_format_raw.bufr.uu \ | ||
38 | libarchive/test/test_read_format_raw.data.gz.uu \ | ||
39 | libarchive/test/test_read_format_raw.data.Z.uu \ | ||
40 | --- libarchive-3.4.2.orig/libarchive/archive_read_support_format_rar5.c | ||
41 | +++ libarchive-3.4.2/libarchive/archive_read_support_format_rar5.c | ||
42 | @@ -3637,6 +3637,16 @@ static int do_uncompress_file(struct arc | ||
43 | rar->cstate.initialized = 1; | ||
44 | } | ||
45 | |||
46 | + /* Don't allow extraction if window_size is invalid. */ | ||
47 | + if(rar->cstate.window_size == 0) { | ||
48 | + archive_set_error(&a->archive, | ||
49 | + ARCHIVE_ERRNO_FILE_FORMAT, | ||
50 | + "Invalid window size declaration in this file"); | ||
51 | + | ||
52 | + /* This should never happen in valid files. */ | ||
53 | + return ARCHIVE_FATAL; | ||
54 | + } | ||
55 | + | ||
56 | if(rar->cstate.all_filters_applied == 1) { | ||
57 | /* We use while(1) here, but standard case allows for just 1 | ||
58 | * iteration. The loop will iterate if process_block() didn't | ||
59 | --- libarchive-3.4.2.orig/libarchive/test/test_read_format_rar5.c | ||
60 | +++ libarchive-3.4.2/libarchive/test/test_read_format_rar5.c | ||
61 | @@ -1305,3 +1305,22 @@ DEFINE_TEST(test_read_format_rar5_decode | ||
62 | |||
63 | EPILOGUE(); | ||
64 | } | ||
65 | + | ||
66 | +DEFINE_TEST(test_read_format_rar5_bad_window_size_in_multiarchive_file) | ||
67 | +{ | ||
68 | + /* oss fuzz 30459 */ | ||
69 | + | ||
70 | + char buf[4096]; | ||
71 | + PROLOGUE("test_read_format_rar5_bad_window_sz_in_mltarc_file.rar"); | ||
72 | + | ||
73 | + /* This file is damaged, so those functions should return failure. | ||
74 | + * Additionally, SIGSEGV shouldn't be raised during execution | ||
75 | + * of those functions. */ | ||
76 | + | ||
77 | + (void) archive_read_next_header(a, &ae); | ||
78 | + while(0 < archive_read_data(a, buf, sizeof(buf))) {} | ||
79 | + (void) archive_read_next_header(a, &ae); | ||
80 | + while(0 < archive_read_data(a, buf, sizeof(buf))) {} | ||
81 | + | ||
82 | + EPILOGUE(); | ||
83 | +} | ||
84 | --- /dev/null | ||
85 | +++ libarchive-3.4.2/libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu | ||
86 | @@ -0,0 +1,7 @@ | ||
87 | +begin 644 test_read_format_rar5_bad_window_size_in_multiarchive_file.rar | ||
88 | +M4F%R(1H'`0`]/-[E`@$`_R`@1#[Z5P("`PL`("`@@"(`"?\@("#___\@("`@ | ||
89 | +M("`@("`@("`@4X`J]`,"YR(#$($@("`@``$@("`@@<L0("`@("`@("`@("`@ | ||
90 | +M("`@(""LCTJA`P$%`B`@`2!3@"KT`P+G(@,@("`@_P,!!B`@(/___R`@(('+ | ||
91 | +5$"`OX2`@[.SL[.S_("`@("`@("`@ | ||
92 | +` | ||
93 | +end | ||
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2022-26280.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2022-26280.patch new file mode 100644 index 0000000000..501fcc5848 --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2022-26280.patch | |||
@@ -0,0 +1,29 @@ | |||
1 | From cfaa28168a07ea4a53276b63068f94fce37d6aff Mon Sep 17 00:00:00 2001 | ||
2 | From: Tim Kientzle <kientzle@acm.org> | ||
3 | Date: Thu, 24 Mar 2022 10:35:00 +0100 | ||
4 | Subject: [PATCH] ZIP reader: fix possible out-of-bounds read in | ||
5 | zipx_lzma_alone_init() | ||
6 | |||
7 | Fixes #1672 | ||
8 | |||
9 | CVE: CVE-2022-26280 | ||
10 | Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/cfaa28168a07ea4a53276b63068f94fce37d6aff] | ||
11 | Signed-off-by: Andrej Valek <andrej.valek@siemens.com> | ||
12 | |||
13 | --- | ||
14 | libarchive/archive_read_support_format_zip.c | 2 +- | ||
15 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
16 | |||
17 | diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c | ||
18 | index 38ada70b5..9d6c900b2 100644 | ||
19 | --- a/libarchive/archive_read_support_format_zip.c | ||
20 | +++ b/libarchive/archive_read_support_format_zip.c | ||
21 | @@ -1667,7 +1667,7 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip) | ||
22 | */ | ||
23 | |||
24 | /* Read magic1,magic2,lzma_params from the ZIPX stream. */ | ||
25 | - if((p = __archive_read_ahead(a, 9, NULL)) == NULL) { | ||
26 | + if(zip->entry_bytes_remaining < 9 || (p = __archive_read_ahead(a, 9, NULL)) == NULL) { | ||
27 | archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, | ||
28 | "Truncated lzma data"); | ||
29 | return (ARCHIVE_FATAL); | ||
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2022-36227.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2022-36227.patch new file mode 100644 index 0000000000..980a0e884a --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2022-36227.patch | |||
@@ -0,0 +1,43 @@ | |||
1 | From 6311080bff566fcc5591dadfd78efb41705b717f Mon Sep 17 00:00:00 2001 | ||
2 | From: obiwac <obiwac@gmail.com> | ||
3 | Date: Fri, 22 Jul 2022 22:41:10 +0200 | ||
4 | Subject: [PATCH] CVE-2022-36227 | ||
5 | |||
6 | libarchive: CVE-2022-36227 Handle a `calloc` returning NULL (fixes #1754) | ||
7 | |||
8 | Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/bff38efe8c110469c5080d387bec62a6ca15b1a5] | ||
9 | CVE: CVE-2022-36227 | ||
10 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com | ||
11 | --- | ||
12 | libarchive/archive_write.c | 8 ++++++++ | ||
13 | 1 file changed, 8 insertions(+) | ||
14 | |||
15 | diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c | ||
16 | index 98a55fb..7fe88b6 100644 | ||
17 | --- a/libarchive/archive_write.c | ||
18 | +++ b/libarchive/archive_write.c | ||
19 | @@ -211,6 +211,10 @@ __archive_write_allocate_filter(struct archive *_a) | ||
20 | struct archive_write_filter *f; | ||
21 | |||
22 | f = calloc(1, sizeof(*f)); | ||
23 | + | ||
24 | + if (f == NULL) | ||
25 | + return (NULL); | ||
26 | + | ||
27 | f->archive = _a; | ||
28 | f->state = ARCHIVE_WRITE_FILTER_STATE_NEW; | ||
29 | if (a->filter_first == NULL) | ||
30 | @@ -527,6 +531,10 @@ archive_write_open(struct archive *_a, void *client_data, | ||
31 | a->client_data = client_data; | ||
32 | |||
33 | client_filter = __archive_write_allocate_filter(_a); | ||
34 | + | ||
35 | + if (client_filter == NULL) | ||
36 | + return (ARCHIVE_FATAL); | ||
37 | + | ||
38 | client_filter->open = archive_write_client_open; | ||
39 | client_filter->write = archive_write_client_write; | ||
40 | client_filter->close = archive_write_client_close; | ||
41 | -- | ||
42 | 2.25.1 | ||
43 | |||