Open
fix: CVE-2023-30571 umask race (issue #16) #176
fix: CVE-2023-30571 umask race (issue #16) #176
Open
huijing_zhangAdd on 3 days ago
Total: 2 files changed+268-1
@@ -0,0 +1,263 @@
1+From 70d36b909ab20de702503b04ffed37bbe72c9b88 Mon Sep 17 00:00:00 2001
2+From: Mike Frysinger <vapier@gmail.com>
3+Date: Tue, 19 Aug 2026 04:00:00 -0400
4+Subject: [PATCH] unify helper to read current umask
5+ 
6+Backport to libarchive for CVE-2023-30571.
7+ 
8+Combines three upstream commits:
9+ 70d36b909ab20de702503b04ffed37bbe72c9b88 - unify helper to read current umask
10+ 065488cd453a60c64e9300de83c9ef95ea47e3fa - archive_umask.c implementation
11+ 8266767d50a2253fb3da4395172829e0257b9bc4 - umask: Use simple Linux system calls if possible
12+https://github.com/libarchive/libarchive/commit/70d36b909ab20de702503b04ffed37bbe72c9b88
13+https://github.com/libarchive/libarchive/commit/065488cd453a60c64e9300de83c9ef95ea47e3fa
14+https://github.com/libarchive/libarchive/commit/8266767d50a2253fb3da4395172829e0257b9bc4
15+---
16+ 6 files changed, 101 insertion(s)(+)
17+--- a/libarchive/archive_umask.c
U
Uultra_planet2 days ago

保留上游补丁文件头、作者信息,保持原本3个补丁不要合并

likedislike
18++++ b/libarchive/archive_umask.c
19+@@ -0,0 +1,101 @@
20++/*-
21++ * SPDX-License-Identifier: BSD-3-Clause
22++ *
23++ * Copyright (c) 1989, 1993, 1994
24++ * The Regents of the University of California. All rights reserved.
25++ *
26++ * This code is derived from software contributed to Berkeley by
27++ * Dave Borman at Cray Research, Inc.
28++ *
29++ * Redistribution and use in source and binary forms, with or without
30++ * modification, are permitted provided that the following conditions
31++ * are met:
32++ * 1. Redistributions of source code must retain the above copyright
33++ * notice, this list of conditions and the following disclaimer.
34++ * 2. Redistributions in binary form must reproduce the above copyright
35++ * notice, this list of conditions and the following disclaimer in the
36++ * documentation and/or other materials provided with the distribution.
37++ * 3. Neither the name of the University nor the names of its contributors
38++ * may be used to endorse or promote products derived from this software
39++ * without specific prior written permission.
40++ *
41++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
42++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
45++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51++ * SUCH DAMAGE.
52++ */
53++
54++#include "archive_platform.h"
55++#include "archive_umask_private.h"
56++
57++#ifdef HAVE_SYS_SINGLE_THREADED_H
58++#include <sys/single_threaded.h>
59++#endif
60++#include <stddef.h>
61++#include <stdio.h>
62++#ifdef HAVE_UNISTD_H
63++#include <unistd.h>
64++#endif
65++#include <sys/stat.h>
66++
67++/* Return the current umask. Attempt to read it without changing. */
68++mode_t
69++__archive_get_umask(void)
70++{
71++ mode_t mask;
72++
73++#ifdef __linux__
74++#ifdef HAVE_SYS_SINGLE_THREADED_H
75++ if (!__libc_single_threaded)
76++#endif
77++ {
78++ /*
79++ * Starting with Linux 4.7, the current process umask can be accessed
80++ * via /proc/self/status.
81++ */
82++
83++ // Lines in status files are almost always less than 100 bytes, so
84++ // 1 KiB should be plenty. Plus, the umask field should show up in
85++ // the first few lines & always be very short. So even if we split
86++ // other lines, that should never happen with umask. We assume any
87++ // lines we split do not contain "Umask:" in the middle of them.
88++ char line[1024];
89++ // The standard doesn't guarantee mode_t size, so scan a specific
90++ // size ourselves. We know the umask will always be 9 bits, so 32
91++ // bits should be plenty.
92++ int int_umask = -1;
93++
94++ FILE *fp = fopen("/proc/self/status", "re");
95++ if (fp != NULL) {
96++ while (fgets(line, sizeof(line), fp)) {
97++ if (sscanf(line, "Umask: %o", &int_umask) == 1)
98++ break;
99++ }
100++ fclose(fp);
101++ if (int_umask != -1)
102++ return (int_umask);
103++ }
104++ }
105++#elif defined(KERN_PROC_UMASK)
106++ /*
107++ * FreeBSD has a sysctl interface for requesting the umask without
108++ * temporarily modifying it. Note that this does not work if the sysctl
109++ * security.bsd.unprivileged_proc_debug is set to 0.
110++ */
111++ u_short smask;
112++ size_t len = sizeof(smask);
113++ if (sysctl((int[4]){ CTL_KERN, KERN_PROC, KERN_PROC_UMASK, 0 },
114++ 4, &smask, &len, NULL, 0) == 0)
115++ return (smask);
116++#endif
117++
118++ umask(mask = umask(0));
119++ return (mask);
120++}
121+--- a/libarchive/archive_umask_private.h
122++++ b/libarchive/archive_umask_private.h
123+@@ -0,0 +1,49 @@
124++/*-
125++ * SPDX-License-Identifier: BSD-3-Clause
126++ *
127++ * Copyright (c) 1989, 1993, 1994
128++ * The Regents of the University of California. All rights reserved.
129++ *
130++ * This code is derived from software contributed to Berkeley by
131++ * Dave Borman at Cray Research, Inc.
132++ *
133++ * Redistribution and use in source and binary forms, with or without
134++ * modification, are permitted provided that the following conditions
135++ * are met:
136++ * 1. Redistributions of source code must retain the above copyright
137++ * notice, this list of conditions and the following disclaimer.
138++ * 2. Redistributions in binary form must reproduce the above copyright
139++ * notice, this list of conditions and the following disclaimer in the
140++ * documentation and/or other materials provided with the distribution.
141++ * 3. Neither the name of the University nor the names of its contributors
142++ * may be used to endorse or promote products derived from this software
143++ * without specific prior written permission.
144++ *
145++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
146++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
147++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
148++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
149++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
150++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
151++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
152++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
153++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
154++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
155++ * SUCH DAMAGE.
156++ */
157++
158++#ifndef ARCHIVE_UMASK_PRIVATE_H_INCLUDED
159++#define ARCHIVE_UMASK_PRIVATE_H_INCLUDED
160++
161++#ifndef __LIBARCHIVE_BUILD
162++#ifndef __LIBARCHIVE_TEST
163++#error This header is only to be used internally to libarchive.
164++#endif
165++#endif
166++
167++#include <sys/stat.h>
168++
169++/* Return the current umask. Attempt to read it without changing. */
170++extern mode_t __archive_get_umask(void);
171++
172++#endif
173+--- a/libarchive/archive_write_disk_posix.c
174++++ b/libarchive/archive_write_disk_posix.c
175+@@ -29,6 +29,8 @@
176+
177+ #if !defined(_WIN32) || defined(__CYGWIN__)
178+
179++#include "archive_umask_private.h"
180++
181+ #ifdef HAVE_SYS_TYPES_H
182+ #include <sys/types.h>
183+ #endif
184+@@ -646,7 +648,7 @@
185+ * user edits their umask during the extraction for some
186+ * reason.
187+ */
188+- umask(a->user_umask = umask(0));
189++ a->user_umask = __archive_get_umask();
190+
191+ /* Figure out what we need to do for this entry. */
192+ a->todo = TODO_MODE_BASE;
193+@@ -2014,8 +2016,8 @@
194+ a->archive.state = ARCHIVE_STATE_HEADER;
195+ a->archive.vtable = &archive_write_disk_vtable;
196+ a->start_time = time(NULL);
197+- /* Query and restore the umask. */
198+- umask(a->user_umask = umask(0));
199++ /* Query the umask. */
200++ a->user_umask = __archive_get_umask();
201+ #ifdef HAVE_GETEUID
202+ a->user_uid = geteuid();
203+ #endif /* HAVE_GETEUID */
204+--- a/libarchive/archive_write_disk_windows.c
205++++ b/libarchive/archive_write_disk_windows.c
206+@@ -29,6 +29,8 @@
207+
208+ #if defined(_WIN32) && !defined(__CYGWIN__)
209+
210++#include "archive_umask_private.h"
211++
212+ #ifdef HAVE_SYS_TYPES_H
213+ #include <sys/types.h>
214+ #endif
215+@@ -863,7 +865,7 @@
216+ * user edits their umask during the extraction for some
217+ * reason.
218+ */
219+- umask(a->user_umask = umask(0));
220++ a->user_umask = __archive_get_umask();
221+
222+ /* Figure out what we need to do for this entry. */
223+ a->todo = TODO_MODE_BASE;
224+@@ -1368,8 +1370,8 @@
225+ a->archive.state = ARCHIVE_STATE_HEADER;
226+ a->archive.vtable = &archive_write_disk_vtable;
227+ a->start_time = time(NULL);
228+- /* Query and restore the umask. */
229+- umask(a->user_umask = umask(0));
230++ /* Query the umask. */
231++ a->user_umask = __archive_get_umask();
232+ if (archive_wstring_ensure(&a->path_safe, 512) == NULL) {
233+ free(a);
234+ return (NULL);
235+--- a/libarchive/CMakeLists.txt
236++++ b/libarchive/CMakeLists.txt
237+@@ -120,6 +120,8 @@
238+ archive_string_sprintf.c
239+ archive_time.c
240+ archive_time_private.h
241++ archive_umask.c
242++ archive_umask_private.h
243+ archive_util.c
244+ archive_version_details.c
245+ archive_virtual.c
246+--- a/Makefile.am
247++++ b/Makefile.am
248+@@ -137,6 +137,7 @@
249+ libarchive/archive_string.h \
250+ libarchive/archive_string_composition.h \
251+ libarchive/archive_time_private.h \
252++ libarchive/archive_umask_private.h \
253+ libarchive/archive_write_disk_private.h \
254+ libarchive/archive_write_private.h \
255+ libarchive/archive_write_set_format_private.h \
256+@@ -217,6 +218,7 @@
257+ libarchive/archive_string.c \
258+ libarchive/archive_string_sprintf.c \
259+ libarchive/archive_time.c \
260++ libarchive/archive_umask.c \
261+ libarchive/archive_util.c \
262+ libarchive/archive_version_details.c \
263+ libarchive/archive_virtual.c \
@@ -2,11 +2,12 @@
2 2 
3Name: libarchive3Name: libarchive
4Version: 3.8.94Version: 3.8.9
5-Release: 15+Release: 2
6Summary: Multi-format archive and compression library6Summary: Multi-format archive and compression library
7License: BSD-2-Clause7License: BSD-2-Clause
8URL: https://www.libarchive.org/8URL: https://www.libarchive.org/
9Source0: https://github.com/libarchive/libarchive/releases/download/v%{version}/%{name}-%{version}.tar.xz9Source0: https://github.com/libarchive/libarchive/releases/download/v%{version}/%{name}-%{version}.tar.xz
10+Patch1: backport-CVE-2023-30571.patch
10 11 
11BuildRequires: gcc bison sharutils zlib-devel bzip2-devel xz-devel12BuildRequires: gcc bison sharutils zlib-devel bzip2-devel xz-devel
12BuildRequires: e2fsprogs-devel libacl-devel libattr-devel13BuildRequires: e2fsprogs-devel libacl-devel libattr-devel
@@ -187,6 +188,9 @@ run_testsuite
187%{_bindir}/bsdunzip188%{_bindir}/bsdunzip
188 189 
189%changelog190%changelog
191+* Wed Nov 4 2026 huijing_zhang <zhanghuijing@kylinos.cn> - 3.8.9-2
192+- backport fix for CVE-2023-30571
193+ 
190* Wed Jul 29 2026 Funda Wang <fundawang@yeah.net> - 3.8.9-1194* Wed Jul 29 2026 Funda Wang <fundawang@yeah.net> - 3.8.9-1
191- update to 3.8.9195- update to 3.8.9
192 196