From 74198afa04de6f63fbb69109cdfc6bff865644fe Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 13 Aug 2009 21:41:30 +0200 Subject: [PATCH] Discarding MD5 array at image load time if its own checksum does not match. --- doc/checksums.txt | 5 +++-- libisofs/fs_image.c | 35 +++++++++++++++++++++++++++++++---- libisofs/libisofs.h | 11 ++++++++++- libisofs/messages.c | 2 ++ 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/doc/checksums.txt b/doc/checksums.txt index 3b646dd..e445050 100644 --- a/doc/checksums.txt +++ b/doc/checksums.txt @@ -3,6 +3,7 @@ by Thomas Schmitt - mailto:scdbackup@gmx.net Libburnia project - mailto:libburn-hackers@pykix.org + 13 Aug 2009 MD5 is a 128 bit message digest with a very low probability to be the same for @@ -80,12 +81,12 @@ There are four parameters: gives the block address where the tag supposes itself to be stored. If this does not match the block address where the tag is found then this either indicates that the tag is payload of the image or that the image has - been relocated. (The latter makes the image unuable.) + been relocated. (The latter makes the image unusable.) range_start= The block address where the session is supposed to start. If this does not match the session start on media then the image volume descriptors of the - image have been been relocated. (The latter can happen with the overwriteable + image have been been relocated. (The latter can happen with overwriteable media.) range_size= diff --git a/libisofs/fs_image.c b/libisofs/fs_image.c index 2620385..4e3a11c 100644 --- a/libisofs/fs_image.c +++ b/libisofs/fs_image.c @@ -2952,6 +2952,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, uint32_t checksum_size; size_t size; uint8_t *rpt; + void *ctx = NULL; + char md5[16]; #endif if (image == NULL || src == NULL || opts == NULL) { @@ -3166,8 +3168,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, if (ret > 0) if (checksum_size != 16 || strcmp(checksum_type, "MD5") != 0) ret = 0; - if (ret > 0) { - size = image->checksum_idx_count / 128 + 1; + if (ret > 0 && image->checksum_idx_count > 1) { + size = image->checksum_idx_count / 128; + if (size * 128 < image->checksum_idx_count) + size++; image->checksum_array = calloc(size, 2048); if (image->checksum_array == NULL) { ret = ISO_OUT_OF_MEM; @@ -3179,7 +3183,29 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, rpt = (uint8_t *) (image->checksum_array + i * 2048); ret = src->read_block(src, image->checksum_end_lba + i, rpt); if (ret <= 0) - goto import_revert; + goto import_cleanup; + } + + /* Compute MD5 and compare with recorded MD5 */ + ret = iso_md5_start(&ctx); + if (ret < 0) { + ret = ISO_OUT_OF_MEM; + goto import_revert; + } + for (i = 0; i < image->checksum_idx_count - 1; i++) + iso_md5_compute(ctx, image->checksum_array + i * 16, 16); + iso_md5_end(&ctx, md5); + for (i = 0; i < 16; i++) + if (md5[i] != image->checksum_array[ + (image->checksum_idx_count - 1) * 16 + i] + ) + break; + if (i < 16) { + iso_msg_submit(image->id, ISO_MD5_ARRAY_CORRUPTED, 0, + "MD5 checksum array appears damaged and not trustworthy for verifications."); + free(image->checksum_array); + image->checksum_array = NULL; + image->checksum_idx_count = 0; } } } @@ -3217,9 +3243,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, #ifdef Libisofs_with_checksumS if (old_checksum_array != NULL) free(old_checksum_array); + if (ctx != NULL) + iso_md5_end(&ctx, md5); #endif - return ret; } diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 025fd4c..7d70225 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -5242,11 +5242,20 @@ int iso_md5_end(void **md5_context, char result[16]); #define ISO_FILE_IMGPATH_WRONG 0xD020FF70 /** - * Offset greater than file size (FAILURE,HIGH, -145) + * Checksum array appears damaged and not trustworthy for verifications. + * (WARNING,HIGH, -145) + * @since 0.6.22 +*/ +#define ISO_MD5_ARRAY_CORRUPTED 0xD030FF6F + + +/** + * Offset greater than file size (FAILURE,HIGH, -150) * @since 0.6.4 */ #define ISO_FILE_OFFSET_TOO_BIG 0xE830FF6A + /** Charset conversion error (FAILURE,HIGH, -256) */ #define ISO_CHARSET_CONV_ERROR 0xE830FF00 diff --git a/libisofs/messages.c b/libisofs/messages.c index c779549..03bce5b 100644 --- a/libisofs/messages.c +++ b/libisofs/messages.c @@ -260,6 +260,8 @@ const char *iso_error_to_msg(int errcode) return "Cannot set global zisofs parameters while filters exist"; case ISO_ZLIB_EARLY_EOF: return "Premature EOF of zlib input stream"; + case ISO_MD5_ARRAY_CORRUPTED: + return "Checksum array appears damaged and not trustworthy for verifications"; default: return "Unknown error"; }