[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH 1/1] archival: new option to disallow path traversals
From:       Peter Kaestle <peter.kaestle () nokia ! com>
Date:       2024-04-29 11:14:10
Message-ID: 20240429111410.1430555-2-peter.kaestle () nokia ! com
[Download RAW message or body]

Create new configure option for archival/libarchive based extractions to
disallow path traversals.
As this is a paranoid option and might introduce backward
incompatibiltiy, default it to no.

Fixes: CVE-2023-39810

Signed-off-by: Peter Kaestle <peter.kaestle@nokia.com>
Reviewed-by: Samuel Sapalski <samuel.sapalski@nokia.com>
---
 archival/Config.src                    |  7 +++++++
 archival/libarchive/data_extract_all.c | 22 ++++++++++++++++++++++
 testsuite/cpio.tests                   | 18 ++++++++++++++++++
 3 files changed, 47 insertions(+)

diff --git a/archival/Config.src b/archival/Config.src
index 6f4f30c43..ac9d3db95 100644
--- a/archival/Config.src
+++ b/archival/Config.src
@@ -35,4 +35,11 @@ config FEATURE_LZMA_FAST
 	This option reduces decompression time by about 25% at the cost of
 	a 1K bigger binary.
 
+config FEATURE_PATH_TRAVERSAL_PROTECTION
+	bool "enable path traversal protection"
+	default n
+	help
+	This option will disallow extraction of files outside of the
+	destination directory.
+
 endmenu
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c
index 049c2c156..cb5d5c4ca 100644
--- a/archival/libarchive/data_extract_all.c
+++ b/archival/libarchive/data_extract_all.c
@@ -66,6 +66,28 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
 	}
 #endif
 
+#if ENABLE_FEATURE_PATH_TRAVERSAL_PROTECTION
+	if (strstr(dst_name, "../")) {
+		char *resolved_dst_path, *cwd;
+
+		cwd = getcwd(NULL, 0);
+
+		resolved_dst_path = xmalloc_realpath_coreutils(dst_name);
+		if (resolved_dst_path) {
+			if (strncmp(cwd, resolved_dst_path, strlen(cwd))) {
+				errno = 0; /* suppress missleading error prints */
+				free(resolved_dst_path);
+				bb_perror_msg_and_die("path traversal detected: %s",
+						dst_name);
+			}
+			free(resolved_dst_path);
+		} else {
+			bb_perror_msg_and_die("cannot allocate memory for real path: %s",
+					dst_name);
+		}
+	}
+#endif
+
 	if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
 		char *slash = strrchr(dst_name, '/');
 		if (slash) {
diff --git a/testsuite/cpio.tests b/testsuite/cpio.tests
index 85e746589..1c0b75297 100755
--- a/testsuite/cpio.tests
+++ b/testsuite/cpio.tests
@@ -154,6 +154,24 @@ testing "cpio -R with extract" \
 " "" ""
 SKIP=
 
+optional FEATURE_PATH_TRAVERSAL_PROTECTION
+rm -rf cpio.testdir
+mkdir -p cpio.testdir/prepare/inner
+echo "file outside of destination was written" > cpio.testdir/prepare/dont_write
+echo "data" > cpio.testdir/prepare/inner/to_extract
+mkdir -p cpio.testdir/extract
+testing "cpio extract file outside of destination" \
+"(cd cpio.testdir/prepare/inner && echo -e '../dont_write\nto_extract' | cpio -H newc --create) |
+(cd cpio.testdir/extract && cpio -vi 2>&1);
+echo \$?;
+ls cpio.testdir/dont_write 2>&1" \
+"\
+cpio: path traversal detected: ../dont_write
+1
+ls: cpio.testdir/dont_write: No such file or directory
+" "" ""
+SKIP=
+
 # Clean up
 rm -rf cpio.testdir cpio.testdir2 2>/dev/null
 
-- 
2.44.0

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic