From 67ff72910dbe5b7101415aec7cb3114840675c79 Mon Sep 17 00:00:00 2001 From: zhangxingrong Date: Mon, 18 Mar 2024 16:25:04 +0800 Subject: [PATCH 1/2] Fix CVE-2024-2313 --- ...ole-checking-unpacked-kernel-headers.patch | 119 ++++++++++++++++++ bpftrace.spec | 6 +- 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 0001-CVE-2024-2313-Fix-security-hole-checking-unpacked-kernel-headers.patch diff --git a/0001-CVE-2024-2313-Fix-security-hole-checking-unpacked-kernel-headers.patch b/0001-CVE-2024-2313-Fix-security-hole-checking-unpacked-kernel-headers.patch new file mode 100644 index 0000000..a57a536 --- /dev/null +++ b/0001-CVE-2024-2313-Fix-security-hole-checking-unpacked-kernel-headers.patch @@ -0,0 +1,119 @@ +From ee52f3be197ac16e8715a4446e4744de28739f84 Mon Sep 17 00:00:00 2001 +From: zhangxingrong +Date: Mon, 18 Mar 2024 15:52:38 +0800 +Subject: [PATCH] + CVE-2024-2313-Fix-security-hole-checking-unpacked-kernel-headers + +--- + src/utils.cpp | 22 +++++++++++++++++++--- + src/utils.h | 1 + + tests/utils.cpp | 21 +++++++++++++++++++++ + 3 files changed, 41 insertions(+), 3 deletions(-) + +diff --git a/src/utils.cpp b/src/utils.cpp +index b3e4234..a24317f 100644 +--- a/src/utils.cpp ++++ b/src/utils.cpp +@@ -116,6 +116,8 @@ const struct vmlinux_location vmlinux_locs[] = { + { nullptr, false }, + }; + ++constexpr std::string_view PROC_KHEADERS_PATH = "/sys/kernel/kheaders.tar.xz"; ++ + static bool pid_in_different_mountns(int pid); + static std::vector + resolve_binary_path(const std::string &cmd, const char *env_paths, int pid); +@@ -581,6 +583,20 @@ bool is_dir(const std::string& path) + return std_filesystem::is_directory(buf, ec); + } + ++bool file_exists_and_ownedby_root(const char *f) ++{ ++ struct stat st; ++ if (stat(f, &st) == 0) { ++ if (st.st_uid != 0) { ++ LOG(ERROR) << "header file ownership expected to be root: " ++ << std::string(f); ++ return false; ++ } ++ return true; ++ } ++ return false; ++} ++ + namespace { + struct KernelHeaderTmpDir { + KernelHeaderTmpDir(const std::string& prefix) : path{prefix + "XXXXXX"} +@@ -613,14 +629,14 @@ namespace { + { + std::error_code ec; + std_filesystem::path path_prefix{ "/tmp" }; +- std_filesystem::path path_kheaders{ "/sys/kernel/kheaders.tar.xz" }; ++ std_filesystem::path path_kheaders{ PROC_KHEADERS_PATH }; + if (const char* tmpdir = ::getenv("TMPDIR")) { + path_prefix = tmpdir; + } + path_prefix /= "kheaders-"; + std_filesystem::path shared_path{ path_prefix.string() + utsname.release }; + +- if (std_filesystem::exists(shared_path, ec)) ++ if (file_exists_and_ownedby_root(shared_path.c_str())) { + { + // already unpacked + return shared_path.string(); +@@ -644,7 +660,7 @@ namespace { + + KernelHeaderTmpDir tmpdir{path_prefix}; + +- FILE* tar = ::popen(("tar xf /sys/kernel/kheaders.tar.xz -C " + tmpdir.path).c_str(), "w"); ++ FILE *tar = ::popen(("tar xf " + std::string(PROC_KHEADERS_PATH) + " -C " + tmpdir.path).c_str(),"w"); + if (!tar) { + return ""; + } +diff --git a/src/utils.h b/src/utils.h +index f2f52de..9dd1ad9 100644 +--- a/src/utils.h ++++ b/src/utils.h +@@ -176,6 +176,7 @@ std::vector get_wildcard_tokens(const std::string &input, + std::vector get_online_cpus(); + std::vector get_possible_cpus(); + bool is_dir(const std::string &path); ++bool file_exists_and_ownedby_root(const char *f); + std::tuple get_kernel_dirs( + const struct utsname &utsname, + bool unpack_kheaders = true); +diff --git a/tests/utils.cpp b/tests/utils.cpp +index 433cb1a..2bbd213 100644 +--- a/tests/utils.cpp ++++ b/tests/utils.cpp +@@ -265,6 +265,27 @@ TEST(utils, parse_kconfig) + unlink(path); + } + ++TEST(utils, file_exists_and_ownedby_root) ++{ ++ std::string tmpdir = "/tmp/bpftrace-test-utils-XXXXXX"; ++ std::string file1 = "/ownedby-user"; ++ std::string file2 = "/no-exists"; ++ if (::mkdtemp(tmpdir.data()) == nullptr) { ++ throw std::runtime_error("creating temporary path for tests failed"); ++ } ++ ++ int fd; ++ fd = open((tmpdir + file1).c_str(), O_CREAT, S_IRUSR); ++ close(fd); ++ ASSERT_GE(fd, 0); ++ ++ EXPECT_FALSE(file_exists_and_ownedby_root((tmpdir + file1).c_str())); ++ EXPECT_FALSE(file_exists_and_ownedby_root((tmpdir + file2).c_str())); ++ EXPECT_TRUE(file_exists_and_ownedby_root("/proc/1/maps")); ++ ++ EXPECT_GT(std_filesystem::remove_all(tmpdir), 0); ++} ++ + } // namespace utils + } // namespace test + } // namespace bpftrace +-- +2.33.0 + diff --git a/bpftrace.spec b/bpftrace.spec index 6fac9bd..584f96b 100644 --- a/bpftrace.spec +++ b/bpftrace.spec @@ -1,11 +1,12 @@ Name: bpftrace Version: 0.19.1 -Release: 1 +Release: 2 Summary: High-level tracing language for Linux eBPF License: ASL 2.0 URL: https://github.com/iovisor/bpftrace Source0: %{url}/archive/refs/tags/v%{version}.tar.gz +Patch001: 0001-CVE-2024-2313-Fix-security-hole-checking-unpacked-kernel-headers.patch # Arches will be included as upstream support is added and dependencies are # satisfied in the respective arches @@ -68,6 +69,9 @@ find %{buildroot}%{_datadir}/%{name}/tools -type f -exec \ %changelog +* Mon Mar 18 2024 woody2918 - 0.19.1-2 +- Fix CVE-2024-2314 + * Mon Jan 08 2024 Paul Thomas - 0.19.1-1 - update to version 0.19.1 -- Gitee From 97e53107c175024705fc422c254a44dc3b81a9ef Mon Sep 17 00:00:00 2001 From: woody2918 Date: Mon, 18 Mar 2024 09:28:52 +0000 Subject: [PATCH 2/2] =?UTF-8?q?update=200001-CVE-2024-2313-Fix-security-ho?= =?UTF-8?q?le-checking-unpacked-kernel-headers.patch.=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=A4=9A=E4=BD=99{?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: woody2918 --- ...313-Fix-security-hole-checking-unpacked-kernel-headers.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0001-CVE-2024-2313-Fix-security-hole-checking-unpacked-kernel-headers.patch b/0001-CVE-2024-2313-Fix-security-hole-checking-unpacked-kernel-headers.patch index a57a536..3402ad2 100644 --- a/0001-CVE-2024-2313-Fix-security-hole-checking-unpacked-kernel-headers.patch +++ b/0001-CVE-2024-2313-Fix-security-hole-checking-unpacked-kernel-headers.patch @@ -57,7 +57,7 @@ index b3e4234..a24317f 100644 std_filesystem::path shared_path{ path_prefix.string() + utsname.release }; - if (std_filesystem::exists(shared_path, ec)) -+ if (file_exists_and_ownedby_root(shared_path.c_str())) { ++ if (file_exists_and_ownedby_root(shared_path.c_str())) { // already unpacked return shared_path.string(); -- Gitee