mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Enhance DDT processing in ddt_v1.c and ddt_v2.c with improved error handling for LZMA compression
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "errors.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
@@ -141,6 +142,12 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
|||||||
{
|
{
|
||||||
// TODO: Check CRC
|
// TODO: Check CRC
|
||||||
case Lzma:
|
case Lzma:
|
||||||
|
if(ddt_header.cmpLength <= LZMA_PROPERTIES_LENGTH)
|
||||||
|
{
|
||||||
|
FATAL("Compressed DDT payload too small (%" PRIu64 ") for LZMA properties.", ddt_header.cmpLength);
|
||||||
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
||||||
|
|
||||||
cmp_data = (uint8_t *)malloc(lzma_size);
|
cmp_data = (uint8_t *)malloc(lzma_size);
|
||||||
@@ -201,6 +208,9 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
|||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(cmp_data);
|
||||||
|
cmp_data = NULL;
|
||||||
|
|
||||||
ctx->inMemoryDdt = true;
|
ctx->inMemoryDdt = true;
|
||||||
*found_user_data_ddt = true;
|
*found_user_data_ddt = true;
|
||||||
|
|
||||||
@@ -239,6 +249,12 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
|||||||
{
|
{
|
||||||
// TODO: Check CRC
|
// TODO: Check CRC
|
||||||
case Lzma:
|
case Lzma:
|
||||||
|
if(ddt_header.cmpLength <= LZMA_PROPERTIES_LENGTH)
|
||||||
|
{
|
||||||
|
FATAL("Compressed DDT payload too small (%" PRIu64 ") for LZMA properties.", ddt_header.cmpLength);
|
||||||
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
||||||
|
|
||||||
cmp_data = (uint8_t *)malloc(lzma_size);
|
cmp_data = (uint8_t *)malloc(lzma_size);
|
||||||
@@ -295,6 +311,9 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
|||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(cmp_data);
|
||||||
|
cmp_data = NULL;
|
||||||
|
|
||||||
if(entry->dataType == CdSectorPrefixCorrected)
|
if(entry->dataType == CdSectorPrefixCorrected)
|
||||||
ctx->sectorPrefixDdt = cd_ddt;
|
ctx->sectorPrefixDdt = cd_ddt;
|
||||||
else if(entry->dataType == CdSectorSuffixCorrected)
|
else if(entry->dataType == CdSectorSuffixCorrected)
|
||||||
@@ -397,9 +416,23 @@ int32_t decode_ddt_entry_v1(aaruformatContext *ctx, const uint64_t sector_addres
|
|||||||
return AARUF_ERROR_NOT_AARUFORMAT;
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ctx->userDataDdt == NULL)
|
||||||
|
{
|
||||||
|
FATAL("User data DDT not loaded.");
|
||||||
|
TRACE("Exiting decode_ddt_entry_v1() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctx->shift >= 64)
|
||||||
|
{
|
||||||
|
FATAL("Invalid DDT shift value %u", ctx->shift);
|
||||||
|
TRACE("Exiting decode_ddt_entry_v1() = AARUF_ERROR_INCORRECT_DATA_SIZE");
|
||||||
|
return AARUF_ERROR_INCORRECT_DATA_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
const uint64_t ddt_entry = ctx->userDataDdt[sector_address];
|
const uint64_t ddt_entry = ctx->userDataDdt[sector_address];
|
||||||
const uint32_t offset_mask = (uint32_t)((1 << ctx->shift) - 1);
|
const uint64_t offset_mask64 = (UINT64_C(1) << ctx->shift) - UINT64_C(1);
|
||||||
*offset = ddt_entry & offset_mask;
|
*offset = ddt_entry & offset_mask64;
|
||||||
*block_offset = ddt_entry >> ctx->shift;
|
*block_offset = ddt_entry >> ctx->shift;
|
||||||
|
|
||||||
// Partially written image... as we can't know the real sector size just assume it's common :/
|
// Partially written image... as we can't know the real sector size just assume it's common :/
|
||||||
|
|||||||
@@ -158,7 +158,14 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
|||||||
switch(ddt_header.compression)
|
switch(ddt_header.compression)
|
||||||
{
|
{
|
||||||
case Lzma:
|
case Lzma:
|
||||||
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
if(ddt_header.cmpLength <= LZMA_PROPERTIES_LENGTH)
|
||||||
|
{
|
||||||
|
FATAL("Compressed DDT payload too small (%" PRIu64 ") for LZMA properties.", ddt_header.cmpLength);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
lzma_size = (size_t)(ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH);
|
||||||
|
|
||||||
cmp_data = (uint8_t *)malloc(lzma_size);
|
cmp_data = (uint8_t *)malloc(lzma_size);
|
||||||
if(cmp_data == NULL)
|
if(cmp_data == NULL)
|
||||||
@@ -309,7 +316,14 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
|||||||
switch(ddt_header.compression)
|
switch(ddt_header.compression)
|
||||||
{
|
{
|
||||||
case Lzma:
|
case Lzma:
|
||||||
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
if(ddt_header.cmpLength <= LZMA_PROPERTIES_LENGTH)
|
||||||
|
{
|
||||||
|
FATAL("Compressed DDT payload too small (%" PRIu64 ") for LZMA properties.", ddt_header.cmpLength);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
lzma_size = (size_t)(ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH);
|
||||||
|
|
||||||
cmp_data = (uint8_t *)malloc(lzma_size);
|
cmp_data = (uint8_t *)malloc(lzma_size);
|
||||||
if(cmp_data == NULL)
|
if(cmp_data == NULL)
|
||||||
@@ -367,6 +381,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
|||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(cmp_data);
|
||||||
|
cmp_data = NULL;
|
||||||
|
|
||||||
crc64_context = aaruf_crc64_init();
|
crc64_context = aaruf_crc64_init();
|
||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
@@ -825,14 +842,14 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
|||||||
|
|
||||||
if(read_bytes != sizeof(DdtHeader2))
|
if(read_bytes != sizeof(DdtHeader2))
|
||||||
{
|
{
|
||||||
FATAL("Could not read block header at %" PRIu64 "", secondaryDdtOffset);
|
FATAL("Could not read block header at %" PRIu64 "", secondary_ddt_offset);
|
||||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ddt_header.identifier != DeDuplicationTable2 || ddt_header.type != UserData)
|
if(ddt_header.identifier != DeDuplicationTable2 || ddt_header.type != UserData)
|
||||||
{
|
{
|
||||||
FATAL("Invalid block header at %" PRIu64 "", secondaryDdtOffset);
|
FATAL("Invalid block header at %" PRIu64 "", secondary_ddt_offset);
|
||||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
@@ -841,7 +858,14 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
|||||||
switch(ddt_header.compression)
|
switch(ddt_header.compression)
|
||||||
{
|
{
|
||||||
case Lzma:
|
case Lzma:
|
||||||
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
if(ddt_header.cmpLength <= LZMA_PROPERTIES_LENGTH)
|
||||||
|
{
|
||||||
|
FATAL("Compressed DDT payload too small (%" PRIu64 ") for LZMA properties.", ddt_header.cmpLength);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
lzma_size = (size_t)(ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH);
|
||||||
|
|
||||||
cmp_data = (uint8_t *)malloc(lzma_size);
|
cmp_data = (uint8_t *)malloc(lzma_size);
|
||||||
if(cmp_data == NULL)
|
if(cmp_data == NULL)
|
||||||
@@ -919,7 +943,7 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
|||||||
|
|
||||||
if(crc64 != ddt_header.crc64)
|
if(crc64 != ddt_header.crc64)
|
||||||
{
|
{
|
||||||
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.crc64, crc64);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
@@ -968,7 +992,7 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
|||||||
|
|
||||||
if(crc64 != ddt_header.crc64)
|
if(crc64 != ddt_header.crc64)
|
||||||
{
|
{
|
||||||
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.crc64, crc64);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
@@ -983,7 +1007,7 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FATAL("Found unknown compression type %d, stopping...", ddtHeader.compression);
|
FATAL("Found unknown compression type %d, stopping...", ddt_header.compression);
|
||||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
@@ -1719,7 +1743,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
|||||||
if(read_bytes != sizeof(DdtHeader2) || ddt_header.identifier != DeDuplicationTable2 ||
|
if(read_bytes != sizeof(DdtHeader2) || ddt_header.identifier != DeDuplicationTable2 ||
|
||||||
ddt_header.type != UserData)
|
ddt_header.type != UserData)
|
||||||
{
|
{
|
||||||
FATAL("Invalid secondary DDT header at %" PRIu64, secondaryDdtOffset);
|
FATAL("Invalid secondary DDT header at %" PRIu64, secondary_ddt_offset);
|
||||||
TRACE("Exiting set_ddt_multi_level_v2() = false");
|
TRACE("Exiting set_ddt_multi_level_v2() = false");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1757,7 +1781,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
|||||||
|
|
||||||
if(crc64 != ddt_header.crc64)
|
if(crc64 != ddt_header.crc64)
|
||||||
{
|
{
|
||||||
FATAL("Secondary DDT CRC mismatch. Expected 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
FATAL("Secondary DDT CRC mismatch. Expected 0x%16lX but got 0x%16lX.", ddt_header.crc64, crc64);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
TRACE("Exiting set_ddt_multi_level_v2() = false");
|
TRACE("Exiting set_ddt_multi_level_v2() = false");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user