mirror of
git://git.openembedded.org/meta-openembedded
synced 2026-01-04 16:10:10 +00:00
cve-check.bbclass reported unpatched vulnerabilities in libtar
[1,2,3,4,5]. The NIST assigned base score for the worst vulnerability
is 9.1 / critical.
The patches were taken from the libtar [6] master branch after the
latest tag v1.2.20 (the changes in libtar master mostly originate from
Fedora and their patches), and from the Fedora 41 libtar source package
[7] and the Debian libtar package 1.2.20-8 [8] where the patches were
not available in the libtar repository itself.
The Fedora patch series was taken in its entirety in order to minimize
differences to Fedora's source tree instead of cherry-picking only CVE
fixes. Minimizing the differences should avoid issues with potential
inter-dependencies between the patches, and hopefully provide better
confidence as even the newest patches have been in use in Fedora for
nearly 2 years (since December 2022; Fedora rpms/libtar.git commit
e25b692fc7ceaa387dafb865b472510754f51bd2). The series includes even the
Fedora patch libtar-1.2.20-no-static-buffer.patch, which contains
changes *) that match the libtar commit
ec613af2e9371d7a3e1f7c7a6822164a4255b4d1 ("decode: avoid using a static
buffer in th_get_pathname()") whose commit message says
Note this can break programs that expect sizeof(TAR) to be fixed.
The patches applied cleanly except for the Fedora srpm patch
libtar-1.2.11-bz729009.patch, which is identical with the pre-existing
meta-oe patch 0002-Do-not-strip-libtar.patch and is thus omitted.
The meta-openembedded recipe does not include any of the patches in
Kirkstone [9] nor the current master [10].
libtar does not have newer releases, and the libtar master doesn't
contain all of the changes included in the patches. Fedora's
libtar.1.2.11-*.patch are not included in the libtar v1.2.20 release
either but only in the master branch after the tag v1.2.20. The version
number in the filename is supposedly due to the patches being created
originally against v1.2.11 but have been upstreamed or at least
committed to the master only after v1.2.20.
The commit metadata could not be practically completed in most of the
cases due to missing commit messages in the original commits and
patches. The informal note about the author ("Authored by") was added to
the patch commit messages where the commit message was missing the
original author(s)' Signed-off-by.
*) The patch also contains the changes split to the libtar commits
495d0c0eabc5648186e7d58ad54b508d14af38f4 ("Check for NULL before
freeing th_pathname") and 20aa09bd7775094a2beb0f136c2c7d9e9fd6c7e6
("Added stdlib.h for malloc() in lib/decode.c"))
[1] https://nvd.nist.gov/vuln/detail/CVE-2021-33643
[2] https://nvd.nist.gov/vuln/detail/CVE-2021-33644
[3] https://nvd.nist.gov/vuln/detail/CVE-2021-33645
[4] https://nvd.nist.gov/vuln/detail/CVE-2021-33646
[5] https://nvd.nist.gov/vuln/detail/CVE-2013-4420
[6] https://repo.or.cz/libtar.git
[7] https://src.fedoraproject.org/rpms/libtar/tree/f41
[8] https://sources.debian.org/patches/libtar/1.2.20-8/CVE-2013-4420.patch/
[9] https://git.openembedded.org/meta-openembedded/tree/meta-oe/recipes-support/libtar/libtar_1.2.20.bb?h=kirkstone&id=9a24b7679810628b594cc5a9b52f77f53d37004f
[10] https://git.openembedded.org/meta-openembedded/tree/meta-oe/recipes-support/libtar/libtar_1.2.20.bb?h=master&id=9356340655b3a4f87f98be88f2d167bb2514a54c
Signed-off-by: Katariina Lounento <katariina.lounento@vaisala.com>
Signed-off-by: Khem Raj <raj.khem@gmail.com>
161 lines
4.6 KiB
Diff
161 lines
4.6 KiB
Diff
From 2c81f47508fa6bce9df84e3b43dfb16dffb742a0 Mon Sep 17 00:00:00 2001
|
|
From: Raphael Geissert <geissert@debian.org>
|
|
Date: Thu, 12 Sep 2024 15:51:05 +0300
|
|
Subject: [PATCH] Avoid directory traversal when extracting archives
|
|
|
|
Description of the vulnerability from the NIST CVE tracker [1]:
|
|
|
|
Multiple directory traversal vulnerabilities in the (1)
|
|
tar_extract_glob and (2) tar_extract_all functions in libtar 1.2.20
|
|
and earlier allow remote attackers to overwrite arbitrary files via
|
|
a .. (dot dot) in a crafted tar file.
|
|
|
|
Imported from the Debian libtar package 1.2.20-8 [2]. Original Debian
|
|
description:
|
|
|
|
Author: Raphael Geissert <geissert@debian.org>
|
|
Bug-Debian: https://bugs.debian.org/731860
|
|
Description: Avoid directory traversal when extracting archives
|
|
by skipping over leading slashes and any prefix containing ".." components.
|
|
Forwarded: yes
|
|
|
|
meta-openembedded uses Debian's release tarball [3]. Debian uses
|
|
repo.or.cz/libtar.git as their upstream [4]. repo.or.cz/libtar.git has
|
|
been inactive since 2013 [5].
|
|
|
|
CVE: CVE-2013-4420
|
|
|
|
Upstream-Status: Inactive-Upstream [lastrelease: 2013 lastcommit: 2013]
|
|
|
|
Comments: Added the commit message
|
|
|
|
[1] https://nvd.nist.gov/vuln/detail/CVE-2013-4420
|
|
[2] https://sources.debian.org/patches/libtar/1.2.20-8/CVE-2013-4420.patch/
|
|
[3] https://git.openembedded.org/meta-openembedded/tree/meta-oe/recipes-support/libtar/libtar_1.2.20.bb?h=master#n8
|
|
[4] http://svn.kibibyte.se/libtar/trunk/debian/control (rev 51; not tagged)
|
|
[5] https://repo.or.cz/libtar.git/shortlog/refs/heads/master
|
|
|
|
Signed-off-by: Katariina Lounento <katariina.lounento@vaisala.com>
|
|
---
|
|
lib/decode.c | 33 +++++++++++++++++++++++++++++++--
|
|
lib/extract.c | 8 ++++----
|
|
lib/internal.h | 1 +
|
|
lib/output.c | 4 ++--
|
|
4 files changed, 38 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/lib/decode.c b/lib/decode.c
|
|
index 35312be..edd5f2e 100644
|
|
--- a/lib/decode.c
|
|
+++ b/lib/decode.c
|
|
@@ -22,13 +22,42 @@
|
|
# include <string.h>
|
|
#endif
|
|
|
|
+char *
|
|
+safer_name_suffix (char const *file_name)
|
|
+{
|
|
+ char const *p, *t;
|
|
+ p = t = file_name;
|
|
+ while (*p == '/') t = ++p;
|
|
+ while (*p)
|
|
+ {
|
|
+ while (p[0] == '.' && p[0] == p[1] && p[2] == '/')
|
|
+ {
|
|
+ p += 3;
|
|
+ t = p;
|
|
+ }
|
|
+ /* advance pointer past the next slash */
|
|
+ while (*p && (p++)[0] != '/');
|
|
+ }
|
|
+
|
|
+ if (!*t)
|
|
+ {
|
|
+ t = ".";
|
|
+ }
|
|
+
|
|
+ if (t != file_name)
|
|
+ {
|
|
+ /* TODO: warn somehow that the path was modified */
|
|
+ }
|
|
+ return (char*)t;
|
|
+}
|
|
+
|
|
|
|
/* determine full path name */
|
|
char *
|
|
th_get_pathname(TAR *t)
|
|
{
|
|
if (t->th_buf.gnu_longname)
|
|
- return t->th_buf.gnu_longname;
|
|
+ return safer_name_suffix(t->th_buf.gnu_longname);
|
|
|
|
/* allocate the th_pathname buffer if not already */
|
|
if (t->th_pathname == NULL)
|
|
@@ -50,7 +79,7 @@ th_get_pathname(TAR *t)
|
|
}
|
|
|
|
/* will be deallocated in tar_close() */
|
|
- return t->th_pathname;
|
|
+ return safer_name_suffix(t->th_pathname);
|
|
}
|
|
|
|
|
|
diff --git a/lib/extract.c b/lib/extract.c
|
|
index 9fc6ad5..4ff1a95 100644
|
|
--- a/lib/extract.c
|
|
+++ b/lib/extract.c
|
|
@@ -302,14 +302,14 @@ tar_extract_hardlink(TAR * t, char *realname)
|
|
if (mkdirhier(dirname(filename)) == -1)
|
|
return -1;
|
|
libtar_hashptr_reset(&hp);
|
|
- if (libtar_hash_getkey(t->h, &hp, th_get_linkname(t),
|
|
+ if (libtar_hash_getkey(t->h, &hp, safer_name_suffix(th_get_linkname(t)),
|
|
(libtar_matchfunc_t)libtar_str_match) != 0)
|
|
{
|
|
lnp = (char *)libtar_hashptr_data(&hp);
|
|
linktgt = &lnp[strlen(lnp) + 1];
|
|
}
|
|
else
|
|
- linktgt = th_get_linkname(t);
|
|
+ linktgt = safer_name_suffix(th_get_linkname(t));
|
|
|
|
#ifdef DEBUG
|
|
printf(" ==> extracting: %s (link to %s)\n", filename, linktgt);
|
|
@@ -347,9 +347,9 @@ tar_extract_symlink(TAR *t, char *realname)
|
|
|
|
#ifdef DEBUG
|
|
printf(" ==> extracting: %s (symlink to %s)\n",
|
|
- filename, th_get_linkname(t));
|
|
+ filename, safer_name_suffix(th_get_linkname(t)));
|
|
#endif
|
|
- if (symlink(th_get_linkname(t), filename) == -1)
|
|
+ if (symlink(safer_name_suffix(th_get_linkname(t)), filename) == -1)
|
|
{
|
|
#ifdef DEBUG
|
|
perror("symlink()");
|
|
diff --git a/lib/internal.h b/lib/internal.h
|
|
index da7be7f..f05ca4f 100644
|
|
--- a/lib/internal.h
|
|
+++ b/lib/internal.h
|
|
@@ -21,3 +21,4 @@
|
|
#define TLS_THREAD
|
|
#endif
|
|
|
|
+char* safer_name_suffix(char const*);
|
|
diff --git a/lib/output.c b/lib/output.c
|
|
index a5262ee..af754f1 100644
|
|
--- a/lib/output.c
|
|
+++ b/lib/output.c
|
|
@@ -124,9 +124,9 @@ th_print_long_ls(TAR *t)
|
|
else
|
|
printf(" link to ");
|
|
if ((t->options & TAR_GNU) && t->th_buf.gnu_longlink != NULL)
|
|
- printf("%s", t->th_buf.gnu_longlink);
|
|
+ printf("%s", safer_name_suffix(t->th_buf.gnu_longlink));
|
|
else
|
|
- printf("%.100s", t->th_buf.linkname);
|
|
+ printf("%.100s", safer_name_suffix(t->th_buf.linkname));
|
|
}
|
|
|
|
putchar('\n');
|