[RESEND][PATCH] fix masking of malicious path traversals in archive content listings

2024-10-11 Thread Ian Norton
Prevent unprintable bytes including terminal escapes being printed when
listing tar file contents in a terminal as this can be used to hide
malicious archive content from users prior to unpacking a file.

Re #16018

Also added bb_safe_dump_str() to include/libbb.h
---
archival/libarchive/header_list.c |  3 ++-
archival/libarchive/header_verbose_list.c | 14 +++---
include/libbb.h   |  8 
3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/archival/libarchive/header_list.c 
b/archival/libarchive/header_list.c
index 0621aa406..9ee69aae2 100644
--- a/archival/libarchive/header_list.c
+++ b/archival/libarchive/header_list.c
@@ -8,5 +8,6 @@
void FAST_FUNC header_list(const file_header_t *file_header)
{
//TODO: cpio -vp DIR should output "DIR/NAME", not just "NAME" */
-   puts(file_header->name);
+   bb_safe_dump_str(stdout, file_header->name);
+   bb_putchar('\n');
}
diff --git a/archival/libarchive/header_verbose_list.c 
b/archival/libarchive/header_verbose_list.c
index a575a08a0..956589a1b 100644
--- a/archival/libarchive/header_verbose_list.c
+++ b/archival/libarchive/header_verbose_list.c
@@ -29,7 +29,7 @@ void FAST_FUNC header_verbose_list(const file_header_t 
*file_header)
/*sprintf(gid, "%u", (unsigned)file_header->gid);*/
group = utoa(file_header->gid);
}
-   printf("%s %s/%s %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s",
+   printf("%s %s/%s %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u ",
bb_mode_string(modestr, file_header->mode),
user,
group,
@@ -39,14 +39,13 @@ void FAST_FUNC header_verbose_list(const file_header_t 
*file_header)
ptm->tm_mday,
ptm->tm_hour,
ptm->tm_min,
-   ptm->tm_sec,
-   file_header->name);
+   ptm->tm_sec);

#else /* !FEATURE_TAR_UNAME_GNAME */

localtime_r(&file_header->mtime, ptm);

-   printf("%s %u/%u %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s",
+   printf("%s %u/%u %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u ",
bb_mode_string(modestr, file_header->mode),
(unsigned)file_header->uid,
(unsigned)file_header->gid,
@@ -56,14 +55,15 @@ void FAST_FUNC header_verbose_list(const file_header_t 
*file_header)
ptm->tm_mday,
ptm->tm_hour,
ptm->tm_min,
-   ptm->tm_sec,
-   file_header->name);
+   ptm->tm_sec);

#endif /* FEATURE_TAR_UNAME_GNAME */

+   bb_safe_dump_str(stdout, file_header->name);
/* NB: GNU tar shows "->" for symlinks and "link to" for hardlinks */
if (file_header->link_target) {
-   printf(" -> %s", file_header->link_target);
+   printf(" -> ");
+   bb_safe_dump_str(stdout, file_header->link_target);
}
bb_putchar('\n');
}
diff --git a/include/libbb.h b/include/libbb.h
index 01cdb1bdc..3222fac8b 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2524,6 +2524,14 @@ static ALWAYS_INLINE unsigned char 
bb_ascii_tolower(unsigned char a)
#define isgraph_asciionly(a) ((unsigned)((a) - 0x21) <= 0x7e - 0x21)
#define isprint_asciionly(a) ((unsigned)((a) - 0x20) <= 0x7e - 0x20)

+/* Print msg to a file-descriptor, replacing any unprintable and terminal 
escape bytes with '?' if fd is a TTY */
+static ALWAYS_INLINE void bb_safe_dump_str(FILE* fd, const char* msg) {
+   int fdno = fileno(fd);
+   if (isatty(fdno)) {
+msg = printable_string(msg);
+   }
+   fprintf(fd, "%s", msg);
+}

/* Simple unit-testing framework */

--
2.20.1



Any email and files/attachments transmitted with it are intended solely for the 
use of the individual or entity to whom they are addressed. If this message has 
been sent to you in error, you must not copy, distribute or disclose of the 
information it contains. Please notify Entrust immediately and delete the 
message from your system.

Wellbeing Notice: Receiving this email outside of normal working hours? 
Managing work and life responsibilities is unique for everyone. I have sent 
this email at a time that works for me.
Unless this email is specifically marked urgent, please respond at a time that 
works for you.
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [EXTERNAL] [RESEND(4) PATCH] archival: disallow path traversals (CVE-2023-39810)

2024-10-11 Thread Ian Norton
FYI, This seems also related to https://bugs.busybox.net/show_bug.cgi?id=16018  
(my patch for fixing that seems to have got lost in the mailing list noise)

From: busybox  on behalf of Peter Kaestle 

Date: Wednesday 2 October 2024 at 09:12
To: "busybox@busybox.net" , Denys Vlasenko 

Cc: "martin.schob...@pentagrid.ch" , Peter 
Kaestle , Samuel Sapalski 
Subject: [EXTERNAL] [RESEND(4) PATCH] archival: disallow path traversals 
(CVE-2023-39810)

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


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 

Reviewed-by: Samuel Sapalski 

---

 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.42.0



___

busybox mailing list

busybox@busybox.net

https://urldefense.com/v3/__http://lists.busybox.net/mailman/listinfo/busybox__;!!FJ-Y8qCqXTj2!dv3Uoeo_xECehdxW2TOtpmp-ONDwsssh0Tl72I5vnwfii2WIcR71lUIMVSJb44L4bKG4Eg6HpK5s3-Bv4ph0xWY$