Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package busybox for openSUSE:Factory checked 
in at 2026-02-20 17:40:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/busybox (Old)
 and      /work/SRC/openSUSE:Factory/.busybox.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "busybox"

Fri Feb 20 17:40:10 2026 rev:95 rq:1333723 version:1.37.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/busybox/busybox.changes  2025-12-20 
21:45:40.557171752 +0100
+++ /work/SRC/openSUSE:Factory/.busybox.new.1977/busybox.changes        
2026-02-20 17:40:16.961531720 +0100
@@ -1,0 +2,8 @@
+Fri Feb 13 13:44:52 UTC 2026 - Radoslav Kolev <[email protected]>
+
+- Fix arbitrary file modification and privilege escalation via
+  unvalidated tar archive entries (CVE-2026-26158, bsc#1258167)
+  * 0001-tar-strip-unsafe-hardlink-components-GNU-tar-does-th.patch
+  * 0002-tar-only-strip-unsafe-components-from-hardlinks-not-.patch
+
+-------------------------------------------------------------------

New:
----
  0001-tar-strip-unsafe-hardlink-components-GNU-tar-does-th.patch
  0002-tar-only-strip-unsafe-components-from-hardlinks-not-.patch

----------(New B)----------
  New:  unvalidated tar archive entries (CVE-2026-26158, bsc#1258167)
  * 0001-tar-strip-unsafe-hardlink-components-GNU-tar-does-th.patch
  * 0002-tar-only-strip-unsafe-components-from-hardlinks-not-.patch
  New:  * 0001-tar-strip-unsafe-hardlink-components-GNU-tar-does-th.patch
  * 0002-tar-only-strip-unsafe-components-from-hardlinks-not-.patch
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ busybox.spec ++++++
--- /var/tmp/diff_new_pack.GgqSdn/_old  2026-02-20 17:40:19.193624737 +0100
+++ /var/tmp/diff_new_pack.GgqSdn/_new  2026-02-20 17:40:19.197624903 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package busybox
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -63,6 +63,10 @@
 Patch14:        wget-don-t-allow-control-characters-in-url.patch
 # PATCH-FIX-UPSTREAM - Fix bsc#1249237, from upstream commit 362159593
 Patch15:        0001-nsenter-unshare-don-t-use-xvfork_parent_waits_and_ex.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1258163 from upstream commit 
3fb6b31c716669e12f75a2accd31bb7685b1a1cb
+Patch16:        0001-tar-strip-unsafe-hardlink-components-GNU-tar-does-th.patch
+# PATCH-FIX-UPSTREAM - The fix above introducesa problem rewriting symlink 
targets too
+Patch17:        0002-tar-only-strip-unsafe-components-from-hardlinks-not-.patch
 
 # other patches
 Patch100:       busybox.install.patch

++++++ 0001-tar-strip-unsafe-hardlink-components-GNU-tar-does-th.patch ++++++
>From b847292170b4f976133932e0eadb50c5f307b1a4 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <[email protected]>
Date: Thu, 29 Jan 2026 11:48:02 +0100
Subject: [PATCH 1/2] tar: strip unsafe hardlink components - GNU tar does the
 same

Defends against files like these (python reproducer):

import tarfile
ti = tarfile.TarInfo("leak_hosts")
ti.type = tarfile.LNKTYPE
ti.linkname = "/etc/hosts"  # or "../etc/hosts" or ".."
ti.size = 0
with tarfile.open("/tmp/hardlink.tar", "w") as t:
        t.addfile(ti)

function                                             old     new   delta
skip_unsafe_prefix                                     -     127    +127
get_header_tar                                      1752    1754      +2
.rodata                                           106861  106856      -5
unzip_main                                          2715    2706      -9
strip_unsafe_prefix                                  102      18     -84
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/3 up/down: 129/-98)            Total: 31 bytes

Signed-off-by: Denys Vlasenko <[email protected]>
---
 archival/libarchive/data_extract_all.c      |  3 +--
 archival/libarchive/get_header_tar.c        | 11 ++++++--
 archival/libarchive/unsafe_prefix.c         | 30 +++++++++++++++++----
 archival/libarchive/unsafe_symlink_target.c |  1 +
 archival/tar.c                              |  2 +-
 archival/unzip.c                            |  2 +-
 include/bb_archive.h                        |  3 ++-
 7 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/archival/libarchive/data_extract_all.c 
b/archival/libarchive/data_extract_all.c
index 049c2c156..0e57a7b03 100644
--- a/archival/libarchive/data_extract_all.c
+++ b/archival/libarchive/data_extract_all.c
@@ -177,8 +177,7 @@ void FAST_FUNC data_extract_all(archive_handle_t 
*archive_handle)
 
                /* To avoid a directory traversal attack via symlinks,
                 * do not restore symlinks with ".." components
-                * or symlinks starting with "/", unless a magic
-                * envvar is set.
+                * or symlinks starting with "/"
                 *
                 * For example, consider a .tar created via:
                 *  $ tar cvf bug.tar anything.txt
diff --git a/archival/libarchive/get_header_tar.c 
b/archival/libarchive/get_header_tar.c
index cc6f3f0ad..1c40ecedb 100644
--- a/archival/libarchive/get_header_tar.c
+++ b/archival/libarchive/get_header_tar.c
@@ -454,8 +454,15 @@ char FAST_FUNC get_header_tar(archive_handle_t 
*archive_handle)
 #endif
 
        /* Everything up to and including last ".." component is stripped */
-       overlapping_strcpy(file_header->name, 
strip_unsafe_prefix(file_header->name));
-//TODO: do the same for file_header->link_target?
+       strip_unsafe_prefix(file_header->name);
+       if (file_header->link_target) {
+               /* GNU tar 1.34 examples:
+                * tar: Removing leading '/' from hard link targets
+                * tar: Removing leading '../' from hard link targets
+                * tar: Removing leading 'etc/../' from hard link targets
+                */
+               strip_unsafe_prefix(file_header->link_target);
+       }
 
        /* Strip trailing '/' in directories */
        /* Must be done after mode is set as '/' is used to check if it's a 
directory */
diff --git a/archival/libarchive/unsafe_prefix.c 
b/archival/libarchive/unsafe_prefix.c
index 33e487bf9..62f676ea6 100644
--- a/archival/libarchive/unsafe_prefix.c
+++ b/archival/libarchive/unsafe_prefix.c
@@ -5,11 +5,11 @@
 #include "libbb.h"
 #include "bb_archive.h"
 
-const char* FAST_FUNC strip_unsafe_prefix(const char *str)
+const char* FAST_FUNC skip_unsafe_prefix(const char *str)
 {
        const char *cp = str;
        while (1) {
-               char *cp2;
+               const char *cp2;
                if (*cp == '/') {
                        cp++;
                        continue;
@@ -18,10 +18,25 @@ const char* FAST_FUNC strip_unsafe_prefix(const char *str)
                        cp += 3;
                        continue;
                }
-               cp2 = strstr(cp, "/../");
+               cp2 = cp;
+ find_dotdot:
+               cp2 = strstr(cp2, "/..");
                if (!cp2)
-                       break;
-               cp = cp2 + 4;
+                       break; /* No (more) malicious components */
+
+               /* We found "/..something" */
+               cp2 += 3;
+               if (*cp2 != '/') {
+                       if (*cp2 == '\0') {
+                               /* Trailing "/..": malicious, return "" */
+                               /* (causes harmless errors trying to create or 
hardlink a file named "") */
+                               return cp2;
+                       }
+                       /* "/..name" is not malicious, look for next "/.." */
+                       goto find_dotdot;
+               }
+               /* Found "/../": malicious, advance past it */
+               cp = cp2 + 1;
        }
        if (cp != str) {
                static smallint warned = 0;
@@ -33,3 +48,8 @@ const char* FAST_FUNC strip_unsafe_prefix(const char *str)
        }
        return cp;
 }
+
+void FAST_FUNC strip_unsafe_prefix(char *str)
+{
+       overlapping_strcpy(str, skip_unsafe_prefix(str));
+}
diff --git a/archival/libarchive/unsafe_symlink_target.c 
b/archival/libarchive/unsafe_symlink_target.c
index f8dc8033d..d764c89ab 100644
--- a/archival/libarchive/unsafe_symlink_target.c
+++ b/archival/libarchive/unsafe_symlink_target.c
@@ -36,6 +36,7 @@ void FAST_FUNC create_links_from_list(llist_t *list)
                                *list->data ? "hard" : "sym",
                                list->data + 1, target
                        );
+                       /* Note: GNU tar 1.34 errors out only _after_ all links 
are (attempted to be) created */
                }
                list = list->link;
        }
diff --git a/archival/tar.c b/archival/tar.c
index d6ca6c1e0..d42dcfc26 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -475,7 +475,7 @@ static int FAST_FUNC writeFileToTarball(struct 
recursive_state *state,
        DBG("writeFileToTarball('%s')", fileName);
 
        /* Strip leading '/' and such (must be before memorizing hardlink's 
name) */
-       header_name = strip_unsafe_prefix(fileName);
+       header_name = skip_unsafe_prefix(fileName);
 
        if (header_name[0] == '\0')
                return TRUE;
diff --git a/archival/unzip.c b/archival/unzip.c
index 71a302915..8a9a90f7d 100644
--- a/archival/unzip.c
+++ b/archival/unzip.c
@@ -860,7 +860,7 @@ int unzip_main(int argc, char **argv)
 
                /* Guard against "/abspath", "/../" and similar attacks */
 // NB: UnZip 6.00 has option -: to disable this
-               overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn));
+               strip_unsafe_prefix(dst_fn);
 
                /* Filter zip entries */
                if (find_list_entry(zreject, dst_fn)
diff --git a/include/bb_archive.h b/include/bb_archive.h
index e0ef8fc4e..1dc77f31d 100644
--- a/include/bb_archive.h
+++ b/include/bb_archive.h
@@ -202,7 +202,8 @@ char get_header_tar_xz(archive_handle_t *archive_handle) 
FAST_FUNC;
 void seek_by_jump(int fd, off_t amount) FAST_FUNC;
 void seek_by_read(int fd, off_t amount) FAST_FUNC;
 
-const char *strip_unsafe_prefix(const char *str) FAST_FUNC;
+const char *skip_unsafe_prefix(const char *str) FAST_FUNC;
+void strip_unsafe_prefix(char *str) FAST_FUNC;
 void create_or_remember_link(llist_t **link_placeholders,
                const char *target,
                const char *linkname,
-- 
2.52.0


++++++ 0002-tar-only-strip-unsafe-components-from-hardlinks-not-.patch ++++++
>From b73fddd2f7fa792b28db63b60159ba44f3b6b7da Mon Sep 17 00:00:00 2001
From: Radoslav Kolev <[email protected]>
Date: Mon, 16 Feb 2026 11:28:20 +0200
Subject: [PATCH 2/2] tar: only strip unsafe components from hardlinks, not
 symlinks

commit 3fb6b31c7 introduced a check for unsafe components in
tar archive hardlinks, but it was being applied to symlinks too
which broke "Symlinks and hardlinks coexist" tar test.

Signed-off-by: Radoslav Kolev <[email protected]>
---
 archival/libarchive/get_header_tar.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/archival/libarchive/get_header_tar.c 
b/archival/libarchive/get_header_tar.c
index 1c40ecedb..606d8067f 100644
--- a/archival/libarchive/get_header_tar.c
+++ b/archival/libarchive/get_header_tar.c
@@ -455,7 +455,7 @@ char FAST_FUNC get_header_tar(archive_handle_t 
*archive_handle)
 
        /* Everything up to and including last ".." component is stripped */
        strip_unsafe_prefix(file_header->name);
-       if (file_header->link_target) {
+       if (file_header->link_target && !S_ISLNK(file_header->mode)) {
                /* GNU tar 1.34 examples:
                 * tar: Removing leading '/' from hard link targets
                 * tar: Removing leading '../' from hard link targets
-- 
2.52.0

Reply via email to