From: Eric Biggers Date: Mon, 5 Jul 2021 06:03:50 +0000 (-0700) Subject: Warn rather than abort if SHA-1 is same but size is different X-Git-Tag: v1.13.5~8 X-Git-Url: https://wimlib.net/git/?a=commitdiff_plain;h=ba8edbaf442ff0b30ca9ee1d16a4a646876ed94c;p=wimlib Warn rather than abort if SHA-1 is same but size is different 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. --- diff --git a/include/wimlib/blob_table.h b/include/wimlib/blob_table.h index f15c6117..d16f5a24 100644 --- a/include/wimlib/blob_table.h +++ b/include/wimlib/blob_table.h @@ -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, diff --git a/src/blob_table.c b/src/blob_table.c index 3fcde011..0554a7a9 100644 --- a/src/blob_table.c +++ b/src/blob_table.c @@ -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; } diff --git a/src/template.c b/src/template.c index e5413e5f..1c018df7 100644 --- a/src/template.c +++ b/src/template.c @@ -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); } } diff --git a/src/win32_capture.c b/src/win32_capture.c index 0298cf00..8c9d726d 100644 --- a/src/win32_capture.c +++ b/src/win32_capture.c @@ -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); }