]> wimlib.net Git - wimlib/commitdiff
Warn rather than abort if SHA-1 is same but size is different
authorEric Biggers <ebiggers3@gmail.com>
Mon, 5 Jul 2021 06:03:50 +0000 (23:03 -0700)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 5 Jul 2021 07:05:50 +0000 (00:05 -0700)
Assertions should only be used for bugs in wimlib, but this scenario can
also happen if there is a SHA-1 collision, or if the SHA-1 hash provided
by the filesystem for a WIM-backed file on Windows is wrong.

include/wimlib/blob_table.h
src/blob_table.c
src/template.c
src/win32_capture.c

index f15c61175c45d86785b8e0f65d9f44aac0053af9..d16f5a243a99e5e5de8e63d6a72c1c289b70c4f8 100644 (file)
@@ -412,7 +412,7 @@ new_blob_from_data_buffer(const void *buffer, size_t size,
 extern struct blob_descriptor *
 after_blob_hashed(struct blob_descriptor *blob,
                  struct blob_descriptor **back_ptr,
-                 struct blob_table *blob_table);
+                 struct blob_table *blob_table, struct wim_inode *inode);
 
 extern int
 hash_unhashed_blob(struct blob_descriptor *blob, struct blob_table *blob_table,
index 3fcde0111d6c55d06d8dcef5611197bae61b1823..0554a7a942e96897679cf65026734a101cc5cdc7 100644 (file)
@@ -36,6 +36,7 @@
 #include "wimlib/assert.h"
 #include "wimlib/bitops.h"
 #include "wimlib/blob_table.h"
+#include "wimlib/dentry.h"
 #include "wimlib/encoding.h"
 #include "wimlib/endianness.h"
 #include "wimlib/error.h"
@@ -1259,7 +1260,7 @@ new_blob_from_data_buffer(const void *buffer, size_t size,
 struct blob_descriptor *
 after_blob_hashed(struct blob_descriptor *blob,
                  struct blob_descriptor **back_ptr,
-                 struct blob_table *blob_table)
+                 struct blob_table *blob_table, struct wim_inode *inode)
 {
        struct blob_descriptor *duplicate_blob;
 
@@ -1273,7 +1274,16 @@ after_blob_hashed(struct blob_descriptor *blob,
                 * this blob to the duplicate and update the reference to this
                 * blob (from a stream) to point to the duplicate.  The caller
                 * is responsible for freeing @blob if needed.  */
-               wimlib_assert(duplicate_blob->size == blob->size);
+               if (duplicate_blob->size != blob->size) {
+                       tchar hash_str[SHA1_HASH_SIZE * 2 + 1];
+
+                       sprint_hash(blob->hash, hash_str);
+                       WARNING("SHA-1 collision at \"%"TS"\"\n"
+                               "          (hash=%"TS", size=%"PRIu64", other_size=%"PRIu64").\n"
+                               "          File will be corrupted!",
+                               inode_any_full_path(inode), hash_str,
+                               blob->size, duplicate_blob->size);
+               }
                duplicate_blob->refcnt += blob->refcnt;
                blob->refcnt = 0;
                *back_ptr = duplicate_blob;
@@ -1307,15 +1317,17 @@ hash_unhashed_blob(struct blob_descriptor *blob, struct blob_table *blob_table,
                   struct blob_descriptor **blob_ret)
 {
        struct blob_descriptor **back_ptr;
+       struct wim_inode *inode;
        int ret;
 
        back_ptr = retrieve_pointer_to_unhashed_blob(blob);
+       inode = blob->back_inode;
 
        ret = sha1_blob(blob);
        if (ret)
                return ret;
 
-       *blob_ret = after_blob_hashed(blob, back_ptr, blob_table);
+       *blob_ret = after_blob_hashed(blob, back_ptr, blob_table, inode);
        return 0;
 }
 
index e5413e5fafa8c607ab50a942b17bdde45c41f847..1c018df7db28f4ac678582e718c729480732d4d3 100644 (file)
@@ -114,7 +114,8 @@ inode_copy_checksums(struct wim_inode *inode,
 
                back_ptr = retrieve_pointer_to_unhashed_blob(blob);
                copy_hash(blob->hash, template_blob->hash);
-               if (after_blob_hashed(blob, back_ptr, blob_table) != blob)
+               if (after_blob_hashed(blob, back_ptr, blob_table,
+                                     inode) != blob)
                        free_blob_descriptor(blob);
        }
 }
index 0298cf00e7de2bc70eba70bb62a47165ebe81228..8c9d726d3417a4fb02cdaa79dd405ec5b7301931 100644 (file)
@@ -1604,7 +1604,8 @@ try_to_use_wimboot_hash(HANDLE h, struct wim_inode *inode,
                        return 0;
                back_ptr = retrieve_pointer_to_unhashed_blob(blob);
                copy_hash(blob->hash, hash);
-               if (after_blob_hashed(blob, back_ptr, blob_table) != blob)
+               if (after_blob_hashed(blob, back_ptr, blob_table,
+                                     inode) != blob)
                        free_blob_descriptor(blob);
        }