From: Jonathan Dieter Date: Mon, 11 Jun 2018 18:47:59 +0000 (+0300) Subject: Rework how lead is read and add function to validate it X-Git-Tag: archive/raspbian/1.1.9+ds1-1+rpi1~1^2~222 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=ace84e8799edfc249a8a1736d3b5dc523c1651f2;p=zchunk.git Rework how lead is read and add function to validate it Signed-off-by: Jonathan Dieter --- diff --git a/include/zck.h b/include/zck.h index fe3239a..f51f704 100644 --- a/include/zck.h +++ b/include/zck.h @@ -199,6 +199,8 @@ int zck_read_lead(zckCtx *zck) int zck_read_header(zckCtx *zck) __attribute__ ((warn_unused_result)); +int zck_validate_lead(zckCtx *zck) + __attribute__ ((warn_unused_result)); /******************************************************************* * Indexes diff --git a/src/lib/header.c b/src/lib/header.c index 6a35c5d..68e86c9 100644 --- a/src/lib/header.c +++ b/src/lib/header.c @@ -421,7 +421,7 @@ int write_header(zckCtx *zck) { return True; } -int PUBLIC zck_read_lead(zckCtx *zck) { +static int read_lead(zckCtx *zck, zck_log_type log_level) { VALIDATE_READ(zck); int lead = 5 + 2*MAX_COMP_SIZE; @@ -438,7 +438,7 @@ int PUBLIC zck_read_lead(zckCtx *zck) { if(memcmp(header, "\0ZCK1", 5) != 0) { free(header); - zck_log(ZCK_LOG_ERROR, + zck_log(log_level, "Invalid lead, perhaps this is not a zck file?\n"); return False; } @@ -446,23 +446,31 @@ int PUBLIC zck_read_lead(zckCtx *zck) { /* Read hash type for header and full digest and initialize check hash */ int hash_type = 0; - if(!compint_to_int(&hash_type, header+length, &length, lead)) + if(!compint_to_int(&hash_type, header+length, &length, lead)) { + free(header); return False; + } if(zck->prep_hash_type > -1 && zck->prep_hash_type != hash_type) { - zck_log(ZCK_LOG_ERROR, + free(header); + zck_log(log_level, "Hash type (%i) doesn't match requested hash type " "(%i)\n", hash_type, zck->prep_hash_type); return False; } - if(!hash_setup(&(zck->hash_type), hash_type)) + if(!hash_setup(&(zck->hash_type), hash_type)) { + free(header); return False; + } zck_log(ZCK_LOG_DEBUG, "Setting header and full digest hash type to %s\n", zck_hash_name_from_type(hash_type)); /* Read header size */ size_t header_length = 0; - if(!compint_to_size(&header_length, header+length, &length, lead)) + if(!compint_to_size(&header_length, header+length, &length, lead)) { + free(header); + hash_reset(&(zck->hash_type)); return False; + } zck->header_length = header_length; /* Set header digest location */ @@ -472,6 +480,9 @@ int PUBLIC zck_read_lead(zckCtx *zck) { zck_log(ZCK_LOG_DEBUG, "Reading header digest\n"); header = realloc(header, length + zck->hash_type.digest_size); if(header == NULL) { + zck->header_length = 0; + zck->hdr_digest_loc = 0; + hash_reset(&(zck->hash_type)); zck_log(ZCK_LOG_ERROR, "Unable to re-allocate %lu bytes\n", length + zck->hash_type.digest_size); return False; @@ -479,13 +490,22 @@ int PUBLIC zck_read_lead(zckCtx *zck) { size_t to_read = 0; if(lead < length + zck->hash_type.digest_size) to_read = length + zck->hash_type.digest_size - lead; - if(read_data(zck->fd, header + lead, to_read) < to_read) + if(read_data(zck->fd, header + lead, to_read) < to_read) { + free(header); + zck->header_length = 0; + zck->hdr_digest_loc = 0; + hash_reset(&(zck->hash_type)); return False; + } lead += to_read; if(zck->prep_digest && memcmp(zck->prep_digest, header + length, zck->hash_type.digest_size) != 0) { - zck_log(ZCK_LOG_ERROR, + free(header); + zck->header_length = 0; + zck->hdr_digest_loc = 0; + hash_reset(&(zck->hash_type)); + zck_log(log_level, "Header digest doesn't match requested header digest\n" "Expected: %s\nActual: %s\n", get_digest_string(zck->prep_digest, zck->hash_type.digest_size), @@ -494,6 +514,10 @@ int PUBLIC zck_read_lead(zckCtx *zck) { } zck->header_digest = zmalloc(zck->hash_type.digest_size); if(zck->header_digest == NULL) { + free(header); + zck->header_length = 0; + zck->hdr_digest_loc = 0; + hash_reset(&(zck->hash_type)); zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", zck->hash_type.digest_size); return False; @@ -504,7 +528,13 @@ int PUBLIC zck_read_lead(zckCtx *zck) { /* Check whether full header length matches specified header length */ if(zck->prep_hdr_size > -1 && (size_t)zck->prep_hdr_size != zck->header_length + length) { - zck_log(ZCK_LOG_ERROR, + free(header); + zck->header_length = 0; + zck->hdr_digest_loc = 0; + hash_reset(&(zck->hash_type)); + free(zck->header_digest); + zck->header_digest = NULL; + zck_log(log_level, "Header length (%lu) doesn't match requested header length " "(%lu)\n", zck->header_length + length, zck->prep_hdr_size); @@ -519,6 +549,32 @@ int PUBLIC zck_read_lead(zckCtx *zck) { return True; } +int PUBLIC zck_read_lead(zckCtx *zck) { + if(zck == NULL) + return False; + return read_lead(zck, ZCK_LOG_ERROR); +} + +int PUBLIC zck_validate_lead(zckCtx *zck) { + if(zck == NULL) + return False; + int retval = read_lead(zck, ZCK_LOG_DEBUG); + free(zck->header); + free(zck->header_digest); + zck->header = NULL; + zck->header_size = 0; + zck->header_length = 0; + zck->hdr_digest_loc = 0; + zck->lead_string = NULL; + zck->lead_size = 0; + zck->header_digest = NULL; + zck->hdr_digest_loc = 0; + hash_reset(&(zck->hash_type)); + if(!seek_data(zck->fd, 0, SEEK_SET)) + return False; + return retval; +} + int PUBLIC zck_read_header(zckCtx *zck) { VALIDATE_READ(zck);