Skip to content

Commit 4914e1b

Browse files
feat: update busybox to 1:1.37.0-10.1
1 parent 1e5b4dd commit 4914e1b

File tree

4 files changed

+237
-0
lines changed

4 files changed

+237
-0
lines changed

debian/changelog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
busybox (1:1.37.0-10.1) unstable; urgency=medium
2+
3+
* Non-maintainer upload.
4+
* CVE-2026-26157: Incomplete path sanitization in archive
5+
extraction utilities
6+
* CVE-2026-26158: File modification outside of the intended
7+
extraction directory in tar
8+
* (Closes: #1127782)
9+
10+
-- Adrian Bunk <bunk@debian.org> Wed, 04 Mar 2026 19:42:01 +0200
11+
112
busybox (1:1.37.0-10) unstable; urgency=medium
213

314
* Revert "initramfs-tools/conf-hooks.d/busybox:
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
From 0c20d6b353b058ab910dd3a0211e2b906802b105 Mon Sep 17 00:00:00 2001
2+
From: Denys Vlasenko <vda.linux@googlemail.com>
3+
Date: Thu, 29 Jan 2026 11:48:02 +0100
4+
Subject: tar: strip unsafe hardlink components - GNU tar does the same
5+
6+
Defends against files like these (python reproducer):
7+
8+
import tarfile
9+
ti = tarfile.TarInfo("leak_hosts")
10+
ti.type = tarfile.LNKTYPE
11+
ti.linkname = "/etc/hosts" # or "../etc/hosts" or ".."
12+
ti.size = 0
13+
with tarfile.open("/tmp/hardlink.tar", "w") as t:
14+
t.addfile(ti)
15+
16+
function old new delta
17+
skip_unsafe_prefix - 127 +127
18+
get_header_tar 1752 1754 +2
19+
.rodata 106861 106856 -5
20+
unzip_main 2715 2706 -9
21+
strip_unsafe_prefix 102 18 -84
22+
------------------------------------------------------------------------------
23+
(add/remove: 1/0 grow/shrink: 1/3 up/down: 129/-98) Total: 31 bytes
24+
25+
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
26+
---
27+
archival/libarchive/data_extract_all.c | 7 +++--
28+
archival/libarchive/get_header_tar.c | 11 ++++++--
29+
archival/libarchive/unsafe_prefix.c | 30 +++++++++++++++++----
30+
archival/libarchive/unsafe_symlink_target.c | 1 +
31+
archival/tar.c | 2 +-
32+
archival/unzip.c | 2 +-
33+
include/bb_archive.h | 3 ++-
34+
7 files changed, 42 insertions(+), 14 deletions(-)
35+
36+
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c
37+
index 8a69711c1..b84b960c4 100644
38+
--- a/archival/libarchive/data_extract_all.c
39+
+++ b/archival/libarchive/data_extract_all.c
40+
@@ -66,8 +66,8 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
41+
}
42+
#endif
43+
#if ENABLE_FEATURE_PATH_TRAVERSAL_PROTECTION
44+
- /* Strip leading "/" and up to last "/../" path component */
45+
- dst_name = (char *)strip_unsafe_prefix(dst_name);
46+
+ /* Skip leading "/" and past last ".." path component */
47+
+ dst_name = (char *)skip_unsafe_prefix(dst_name);
48+
#endif
49+
// ^^^ This may be a problem if some applets do need to extract absolute names.
50+
// (Probably will need to invent ARCHIVE_ALLOW_UNSAFE_NAME flag).
51+
@@ -185,8 +185,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
52+
53+
/* To avoid a directory traversal attack via symlinks,
54+
* do not restore symlinks with ".." components
55+
- * or symlinks starting with "/", unless a magic
56+
- * envvar is set.
57+
+ * or symlinks starting with "/"
58+
*
59+
* For example, consider a .tar created via:
60+
* $ tar cvf bug.tar anything.txt
61+
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c
62+
index cc6f3f0ad..1c40ecedb 100644
63+
--- a/archival/libarchive/get_header_tar.c
64+
+++ b/archival/libarchive/get_header_tar.c
65+
@@ -454,8 +454,15 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
66+
#endif
67+
68+
/* Everything up to and including last ".." component is stripped */
69+
- overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name));
70+
-//TODO: do the same for file_header->link_target?
71+
+ strip_unsafe_prefix(file_header->name);
72+
+ if (file_header->link_target) {
73+
+ /* GNU tar 1.34 examples:
74+
+ * tar: Removing leading '/' from hard link targets
75+
+ * tar: Removing leading '../' from hard link targets
76+
+ * tar: Removing leading 'etc/../' from hard link targets
77+
+ */
78+
+ strip_unsafe_prefix(file_header->link_target);
79+
+ }
80+
81+
/* Strip trailing '/' in directories */
82+
/* Must be done after mode is set as '/' is used to check if it's a directory */
83+
diff --git a/archival/libarchive/unsafe_prefix.c b/archival/libarchive/unsafe_prefix.c
84+
index 667081195..89a371a7f 100644
85+
--- a/archival/libarchive/unsafe_prefix.c
86+
+++ b/archival/libarchive/unsafe_prefix.c
87+
@@ -5,11 +5,11 @@
88+
#include "libbb.h"
89+
#include "bb_archive.h"
90+
91+
-const char* FAST_FUNC strip_unsafe_prefix(const char *str)
92+
+const char* FAST_FUNC skip_unsafe_prefix(const char *str)
93+
{
94+
const char *cp = str;
95+
while (1) {
96+
- char *cp2;
97+
+ const char *cp2;
98+
if (*cp == '/') {
99+
cp++;
100+
continue;
101+
@@ -22,10 +22,25 @@ const char* FAST_FUNC strip_unsafe_prefix(const char *str)
102+
cp += 3;
103+
continue;
104+
}
105+
- cp2 = strstr(cp, "/../");
106+
+ cp2 = cp;
107+
+ find_dotdot:
108+
+ cp2 = strstr(cp2, "/..");
109+
if (!cp2)
110+
- break;
111+
- cp = cp2 + 4;
112+
+ break; /* No (more) malicious components */
113+
+
114+
+ /* We found "/..something" */
115+
+ cp2 += 3;
116+
+ if (*cp2 != '/') {
117+
+ if (*cp2 == '\0') {
118+
+ /* Trailing "/..": malicious, return "" */
119+
+ /* (causes harmless errors trying to create or hardlink a file named "") */
120+
+ return cp2;
121+
+ }
122+
+ /* "/..name" is not malicious, look for next "/.." */
123+
+ goto find_dotdot;
124+
+ }
125+
+ /* Found "/../": malicious, advance past it */
126+
+ cp = cp2 + 1;
127+
}
128+
if (cp != str) {
129+
static smallint warned = 0;
130+
@@ -37,3 +52,8 @@ const char* FAST_FUNC strip_unsafe_prefix(const char *str)
131+
}
132+
return cp;
133+
}
134+
+
135+
+void FAST_FUNC strip_unsafe_prefix(char *str)
136+
+{
137+
+ overlapping_strcpy(str, skip_unsafe_prefix(str));
138+
+}
139+
diff --git a/archival/libarchive/unsafe_symlink_target.c b/archival/libarchive/unsafe_symlink_target.c
140+
index f8dc8033d..d764c89ab 100644
141+
--- a/archival/libarchive/unsafe_symlink_target.c
142+
+++ b/archival/libarchive/unsafe_symlink_target.c
143+
@@ -36,6 +36,7 @@ void FAST_FUNC create_links_from_list(llist_t *list)
144+
*list->data ? "hard" : "sym",
145+
list->data + 1, target
146+
);
147+
+ /* Note: GNU tar 1.34 errors out only _after_ all links are (attempted to be) created */
148+
}
149+
list = list->link;
150+
}
151+
diff --git a/archival/tar.c b/archival/tar.c
152+
index d6ca6c1e0..d42dcfc26 100644
153+
--- a/archival/tar.c
154+
+++ b/archival/tar.c
155+
@@ -475,7 +475,7 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
156+
DBG("writeFileToTarball('%s')", fileName);
157+
158+
/* Strip leading '/' and such (must be before memorizing hardlink's name) */
159+
- header_name = strip_unsafe_prefix(fileName);
160+
+ header_name = skip_unsafe_prefix(fileName);
161+
162+
if (header_name[0] == '\0')
163+
return TRUE;
164+
diff --git a/archival/unzip.c b/archival/unzip.c
165+
index 71a302915..8a9a90f7d 100644
166+
--- a/archival/unzip.c
167+
+++ b/archival/unzip.c
168+
@@ -860,7 +860,7 @@ int unzip_main(int argc, char **argv)
169+
170+
/* Guard against "/abspath", "/../" and similar attacks */
171+
// NB: UnZip 6.00 has option -: to disable this
172+
- overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn));
173+
+ strip_unsafe_prefix(dst_fn);
174+
175+
/* Filter zip entries */
176+
if (find_list_entry(zreject, dst_fn)
177+
diff --git a/include/bb_archive.h b/include/bb_archive.h
178+
index e0ef8fc4e..1dc77f31d 100644
179+
--- a/include/bb_archive.h
180+
+++ b/include/bb_archive.h
181+
@@ -202,7 +202,8 @@ char get_header_tar_xz(archive_handle_t *archive_handle) FAST_FUNC;
182+
void seek_by_jump(int fd, off_t amount) FAST_FUNC;
183+
void seek_by_read(int fd, off_t amount) FAST_FUNC;
184+
185+
-const char *strip_unsafe_prefix(const char *str) FAST_FUNC;
186+
+const char *skip_unsafe_prefix(const char *str) FAST_FUNC;
187+
+void strip_unsafe_prefix(char *str) FAST_FUNC;
188+
void create_or_remember_link(llist_t **link_placeholders,
189+
const char *target,
190+
const char *linkname,
191+
--
192+
2.47.3
193+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
From 038e0e4d791ea4e8a8da5e06904756142fc6b8dc Mon Sep 17 00:00:00 2001
2+
From: Radoslav Kolev <radoslav.kolev@suse.com>
3+
Date: Mon, 16 Feb 2026 11:50:04 +0200
4+
Subject: tar: only strip unsafe components from hardlinks, not symlinks
5+
6+
commit 3fb6b31c7 introduced a check for unsafe components in
7+
tar archive hardlinks, but it was being applied to symlinks too
8+
which broke "Symlinks and hardlinks coexist" tar test.
9+
10+
Signed-off-by: Radoslav Kolev <radoslav.kolev@suse.com>
11+
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
12+
---
13+
archival/libarchive/get_header_tar.c | 2 +-
14+
1 file changed, 1 insertion(+), 1 deletion(-)
15+
16+
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c
17+
index 1c40ecedb..606d8067f 100644
18+
--- a/archival/libarchive/get_header_tar.c
19+
+++ b/archival/libarchive/get_header_tar.c
20+
@@ -455,7 +455,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
21+
22+
/* Everything up to and including last ".." component is stripped */
23+
strip_unsafe_prefix(file_header->name);
24+
- if (file_header->link_target) {
25+
+ if (file_header->link_target && !S_ISLNK(file_header->mode)) {
26+
/* GNU tar 1.34 examples:
27+
* tar: Removing leading '/' from hard link targets
28+
* tar: Removing leading '../' from hard link targets
29+
--
30+
2.47.3
31+

debian/patches/series

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,5 @@ wget-disallow-control-chars-in-URLs-CVE-2025-60876.patch
2626
archival-libarchive-sanitize-filenames-on-output-CVE-2025-46394.patch
2727
archival-libarchive-sanitize-filenames-on-output-CVE-2025-46394-2.patch
2828
netstat-sanitize-argv0-for-p-CVE-2024-58251.patch
29+
0001-tar-strip-unsafe-hardlink-components-GNU-tar-does-th.patch
30+
0002-tar-only-strip-unsafe-components-from-hardlinks-not-.patch

0 commit comments

Comments
 (0)