Improve error message for --one-top-level

Backported from upstream.

Resolves: RHEL-151392
This commit is contained in:
Pavel Cahyna 2026-02-23 16:14:33 +01:00
parent 7976e6da22
commit 5d7cb06111
2 changed files with 67 additions and 0 deletions

View File

@ -0,0 +1,66 @@
diff --git a/NEWS b/NEWS
index 464def57..41a3c4e2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,13 @@
-GNU tar NEWS - User visible changes. 2025-12-05
+GNU tar NEWS - User visible changes. 2026-02-23
Please send GNU tar bug reports to <bug-tar@gnu.org>
version 1.35.90 (git)
+* Changes to behavior
+
+** --one-top-level=DIR now requires DIR to be relative.
+ Previously this restriction was alluded to in the manual but not enforced.
+
* Bug fixes
** When extracting, tar no longer follows symbolic links to targets
diff --git a/doc/tar.texi b/doc/tar.texi
index cd57fde5..59720f13 100644
--- a/doc/tar.texi
+++ b/doc/tar.texi
@@ -3221,10 +3221,14 @@ directory.
@opsummary{one-top-level}
@item --one-top-level[=@var{dir}]
Tells @command{tar} to create a new directory beneath the extraction directory
-(or the one passed to @option{-C}) and use it to guard against
-tarbombs. In the absence of @var{dir} argument, the name of the new directory
-will be equal to the base name of the archive (file name minus the
-archive suffix, if recognized). Any member names that do not begin
+(or the one passed to @option{-C}) and use it to prevent @command{tar}
+from modifying files outside that directory.
+If @var{dir} is present, it must be a relative file name.
+If it is absent, the name of the new directory
+is the base name of the archive minus any recognized archive suffix.
+If multiple @option{-C} options are present,
+each has its own subdirectory with the same name.
+Any member names that do not begin
with that directory name (after
transformations from @option{--transform} and
@option{--strip-components}) will be prefixed with it. Recognized
diff --git a/src/tar.c b/src/tar.c
index 26cf745c..a814e319 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -2578,7 +2578,7 @@ decode_options (int argc, char **argv)
one_top_level_option = false;
}
- if (one_top_level_option && !one_top_level_dir)
+ if (!one_top_level_dir && one_top_level_option)
{
/* If the user wants to guarantee that everything is under one
directory, determine its name now and let it be created later. */
@@ -2591,6 +2591,10 @@ decode_options (int argc, char **argv)
_("Cannot deduce top-level directory name; "
"please set it explicitly with --one-top-level=DIR")));
}
+
+ if (one_top_level_dir && !IS_RELATIVE_FILE_NAME (one_top_level_dir))
+ USAGE_ERROR ((0, 0,
+ _("--one-top-level=DIR must use a relative file name")));
}
/* If ready to unlink hierarchies, so we are for simpler files. */

View File

@ -51,6 +51,7 @@ Patch22: tar-1.34-no-overwrite-dir-no-overwrite-even-temporarily.patch
# 45b6e6898d1f931bfca41d961289bd6ac33238e5
# e54b645fc6b8422562327443bda575c65d931fbd
Patch23: tar-1.34-CVE-2025-45582.patch
Patch24: tar-1.34-tar-one-top-level-DIR-must-be-relative.patch
BuildRequires: make
BuildRequires: gcc