[git commit branch/1_31_stable] dpkg-deb: work around bogus error message when working with XZ compressed packages

Denys Vlasenko vda.linux at googlemail.com
Mon Oct 21 14:54:40 UTC 2019


commit: https://git.busybox.net/busybox/commit/?id=ebc1c38a9295228b35c99e03c2377c717703469e
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/1_31_stable

function                                             old     new   delta
unpack_xz_stream                                    2309    2317      +8
bb_full_fd_action                                    464     472      +8

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 archival/libarchive/decompress_unxz.c | 20 +++++++++++++++++++-
 archival/libarchive/unxz/xz_stream.h  |  2 +-
 libbb/copyfd.c                        | 13 ++++++++-----
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c
index 8ae7a275b..948ef978c 100644
--- a/archival/libarchive/decompress_unxz.c
+++ b/archival/libarchive/decompress_unxz.c
@@ -96,6 +96,24 @@ unpack_xz_stream(transformer_state_t *xstate)
 			 */
 			do {
 				if (membuf[iobuf.in_pos] != 0) {
+					/* There is more data, but is it XZ data?
+					 * Example: dpkg-deb -f busybox_1.30.1-4_amd64.deb
+					 * reads control.tar.xz "control" file
+					 * inside the ar archive, but tar.xz
+					 * extraction code reaches end of xz data,
+					 * reached this code and reads the beginning
+					 * of data.tar.xz's ar header, which isn't xz data,
+					 * and prints "corrupted data".
+					 * The correct solution is to not read
+					 * past nested archive (to simulate EOF).
+					 * This is a workaround:
+					 */
+					if (membuf[iobuf.in_pos] != 0xfd) {
+						/* It's definitely not a xz signature
+						 * (which is 0xfd,"7zXZ",0x00).
+						 */
+						goto end;
+					}
 					xz_dec_reset(state);
 					goto do_run;
 				}
@@ -128,7 +146,7 @@ unpack_xz_stream(transformer_state_t *xstate)
 			break;
 		}
 	}
-
+ end:
 	xz_dec_end(state);
 	free(membuf);
 
diff --git a/archival/libarchive/unxz/xz_stream.h b/archival/libarchive/unxz/xz_stream.h
index 66cb5a705..45056e42c 100644
--- a/archival/libarchive/unxz/xz_stream.h
+++ b/archival/libarchive/unxz/xz_stream.h
@@ -25,7 +25,7 @@
 
 #define STREAM_HEADER_SIZE 12
 
-#define HEADER_MAGIC "\3757zXZ"
+#define HEADER_MAGIC "\375""7zXZ"
 #define HEADER_MAGIC_SIZE 6
 
 #define FOOTER_MAGIC "YZ"
diff --git a/libbb/copyfd.c b/libbb/copyfd.c
index dd0517cd6..3b754efb8 100644
--- a/libbb/copyfd.c
+++ b/libbb/copyfd.c
@@ -18,7 +18,7 @@
  * was seen to cause largish delays when user tries to ^C a file copy.
  * Let's use a saner size.
  * Note: needs to be >= max(CONFIG_FEATURE_COPYBUF_KB),
- * or else "copy to eof" code will use neddlesly short reads.
+ * or else "copy to eof" code will use needlesly short reads.
  */
 #define SENDFILE_BIGBUF (16*1024*1024)
 
@@ -60,10 +60,13 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size)
 		ssize_t rd;
 
 		if (sendfile_sz) {
-			rd = sendfile(dst_fd, src_fd, NULL,
-				size > sendfile_sz ? sendfile_sz : size);
-			if (rd >= 0)
-				goto read_ok;
+			/* dst_fd == -1 is a fake, else... */
+			if (dst_fd >= 0) {
+				rd = sendfile(dst_fd, src_fd, NULL,
+					size > sendfile_sz ? sendfile_sz : size);
+				if (rd >= 0)
+					goto read_ok;
+			}
 			sendfile_sz = 0; /* do not try sendfile anymore */
 		}
 #if CONFIG_FEATURE_COPYBUF_KB > 4


More information about the busybox-cvs mailing list