]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
xar: Avoid infinite link loop (#2123)
authorTobias Stoeckmann <tobias@stoeckmann.org>
Wed, 10 Apr 2024 20:59:40 +0000 (22:59 +0200)
committerMartin Matuska <martin@matuska.de>
Tue, 23 Apr 2024 09:43:07 +0000 (11:43 +0200)
A file may have only one link target at a time. Otherwise the internal
link structure could loop. Besides, a hard link realistically can only
link to one file, not multiple ones.

Consider such an archive invalid.

Co-authored-by: Martin Matuska <martin@matuska.de>
Makefile.am
libarchive/archive_read_support_format_xar.c
libarchive/test/CMakeLists.txt
libarchive/test/test_read_format_xar_doublelink.c [new file with mode: 0644]
libarchive/test/test_read_format_xar_doublelink.xar.uu [new file with mode: 0644]

index 286f08694c4384fb5f679ae75ad5031fe4480b9c..47b6fa1fc63e0cce380e003c801c64497f59d53d 100644 (file)
@@ -528,6 +528,7 @@ libarchive_test_SOURCES= \
        libarchive/test/test_read_format_ustar_filename.c \
        libarchive/test/test_read_format_warc.c \
        libarchive/test/test_read_format_xar.c \
+       libarchive/test/test_read_format_xar_doublelink.c \
        libarchive/test/test_read_format_zip.c \
        libarchive/test/test_read_format_zip_7075_utf8_paths.c \
        libarchive/test/test_read_format_zip_comment_stored.c \
@@ -932,6 +933,7 @@ libarchive_test_EXTRA_DIST=\
        libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \
        libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
        libarchive/test/test_read_format_warc.warc.uu \
+       libarchive/test/test_read_format_xar_doublelink.xar.uu \
        libarchive/test/test_read_format_zip.zip.uu \
        libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \
        libarchive/test/test_read_format_zip_7z_deflate.zip.uu \
index fd63594373cbec515ff134d768083966ad9513e9..2c3432642937bcfbae209aad48c913ec68f32558 100644 (file)
@@ -2055,6 +2055,11 @@ xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
                            attr = attr->next) {
                                if (strcmp(attr->name, "link") != 0)
                                        continue;
+                               if (xar->file->hdnext != NULL || xar->file->link != 0) {
+                                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+                                           "File with multiple link targets");
+                                       return (ARCHIVE_FATAL);
+                               }
                                if (strcmp(attr->value, "original") == 0) {
                                        xar->file->hdnext = xar->hdlink_orgs;
                                        xar->hdlink_orgs = xar->file;
index 8209c25a5f8d532dc2a6dc10e229486719822b5f..7b166c5fba0ffbbb515936d4970bbf1c3eb92b6e 100644 (file)
@@ -172,6 +172,7 @@ IF(ENABLE_TEST)
     test_read_format_ustar_filename.c
     test_read_format_warc.c
     test_read_format_xar.c
+    test_read_format_xar_doublelink.c
     test_read_format_zip.c
     test_read_format_zip_7075_utf8_paths.c
     test_read_format_zip_comment_stored.c
diff --git a/libarchive/test/test_read_format_xar_doublelink.c b/libarchive/test/test_read_format_xar_doublelink.c
new file mode 100644 (file)
index 0000000..73ddebd
--- /dev/null
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2024 Martin Matuska
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+#define __LIBARCHIVE_BUILD
+
+DEFINE_TEST(test_read_format_xar_doublelink)
+{
+       const char *refname = "test_read_format_xar_doublelink.xar";
+       struct archive *a;
+       struct archive_entry *ae;
+
+       extract_reference_file(refname);
+
+       /* Verify with seeking reader. */
+       assert((a = archive_read_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+        if(ARCHIVE_OK != archive_read_support_format_xar(a)) {
+                skipping("XAR format unsupported");
+                assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+                return;
+        }
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname,
+           10240));
+
+       assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
+       assertEqualString(archive_error_string(a),
+               "File with multiple link targets");
+       assert(archive_errno(a) != 0);
+
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
diff --git a/libarchive/test/test_read_format_xar_doublelink.xar.uu b/libarchive/test/test_read_format_xar_doublelink.xar.uu
new file mode 100644 (file)
index 0000000..5fed96a
--- /dev/null
@@ -0,0 +1,12 @@
+begin 664 test_read_foxmat_xar_doublelink.xar
+M>&%R(0`<``$````````!0`````````/7`````7B<[9/!<L(@%$7W?@7#/H60
+MU'0R!'?]`KOICDF>D3&``]'1?GT!-1U;;:=[5[G<=WB0=P>^..@![<%Y94V#
+M\R>*$9C6=LKT#7Y;OF8O>"%F_""=F"$^VC9\$&\=R#'LR$:E03#*RHR6&2N6
+MM*KIO,YS3JZ1M&D-[<;O-/+C<8`&^[7,<:P@;E<K#Z.@G)Q5<KWZB,TY22*V
+M()<>:;52`R#5A6N?VQ@9CHIN.#_IY(['+:!!F4V#K5.],G+`8BU=%SU.8OF?
+MH#*V`U%5K"@9)Z=5*G2P5RT8*YY+3J9%*ND(T?D\%/3$[U0G<DK#+T9ULCPX
+MH75PHDA6/U']A>J=W6T3=E+);&^E4=0%?0^#N\00;G(;8U7`]!<F?\'D%"J)
+MX[Y.@WU/@]U)(_\SACO$8_X_YA_&$]\F)^FE?@)<4AJ<B%QTTZN3JTL:$,<5
+<`XH;(KD-Q0=XG.V3P7+"(!1%]WX%PSZ%D-1T,@``
+`
+end