Skip to content

Commit 26d0843

Browse files
committed
Worked on format support #13
1 parent 921a58c commit 26d0843

9 files changed

+151
-36
lines changed

documentation/Extended File System (EXT).asciidoc

+15-6
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,9 @@ See section: <<checksum_types,checksum types>>
421421
Some versions of mkfs.ext set the file system creation time even for ext2 and
422422
when EXT3_FEATURE_COMPAT_HAS_JOURNAL is not set.
423423

424-
The checksum, if checksum type is CRC-32C, contain a CRC-32 of data in the
425-
superblock before the checksum. The checksum is stored as 0xffffffff - CRC-32C.
424+
The checksum is calculated from the data in the superblock before the checksum.
425+
426+
If checksum type is CRC-32C, the checksum is stored as 0xffffffff - CRC-32C.
426427

427428
[yellow-background]*Is the only way to determine the file system version the
428429
compatibility and equivalent flags?*
@@ -641,8 +642,7 @@ Contains the lower 16-bit of the value if 64-bit support (EXT4_FEATURE_INCOMPAT_
641642
The checksum is a CRC-32C [yellow-background]*TODO: crc32c(s_uuid+grp_num+ibitmap)*
642643
| 28 | 2 | | Number of unused inodes +
643644
Contains the lower 16-bit of the value if 64-bit support (EXT4_FEATURE_INCOMPAT_64BIT) is enabled +
644-
| 30 | 2 | | Checksum +
645-
The checksum is a CRC-16 [yellow-background]*TODO: crc16(sb_uuid+group+desc)*
645+
| 30 | 2 | | Checksum
646646
4+| _If 64-bit support (EXT4_FEATURE_INCOMPAT_64BIT) is enabled and group descriptor size > 32_
647647
| 32 | 4 | | Block bitmap block number +
648648
Contains the upper 32-bit of the value +
@@ -674,6 +674,15 @@ The checksum is a CRC-32C [yellow-background]*TODO: crc32c(s_uuid+grp_num+ibitma
674674
| 64 | 4 | | [yellow-background]*Unknown (reserved)*
675675
|===
676676

677+
The checksum is calculated from:
678+
679+
* file system identifier in the superblock
680+
* group number
681+
* data of the group descriptor with the checksum set to 0-byte values.
682+
683+
If checksum type is CRC-32C, the checksum is stored as the lower 16-bits of 0xffffffff
684+
- CRC-32C, otherwise the checksum is stored as CRC-16.
685+
677686
=== [[block_group_flags]]Block group flags
678687

679688
*TODO: add description*
@@ -975,14 +984,14 @@ Contains the upper 16-bit of the checksum value
975984
For a character and block device the first 2 bytes of the array of direct
976985
block numbers contain the minor and major device number respectively.
977986

978-
The checksum, if checksum type is CRC-32C, contain a CRC-32 of:
987+
The checksum is calculated from:
979988

980989
* file system identifier in the superblock
981990
* inode number
982991
* NFS generation number in the inode
983992
* data of the inode with the lower and upper part of the checksum set to 0-byte values.
984993

985-
The checksum is stored as 0xffffffff - CRC-32C.
994+
If checksum type is CRC-32C, the checksum is stored as 0xffffffff - CRC-32C.
986995

987996
[yellow-background]*TODO describe extra precision*
988997

libfsext/libfsext_group_descriptor.c

+122-11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <memory.h>
2525
#include <types.h>
2626

27+
#include "libfsext_checksum.h"
2728
#include "libfsext_definitions.h"
2829
#include "libfsext_group_descriptor.h"
2930
#include "libfsext_io_handle.h"
@@ -146,14 +147,16 @@ int libfsext_group_descriptor_read_data(
146147
size_t data_size,
147148
libcerror_error_t **error )
148149
{
150+
uint8_t checksum_data[ 4 ];
151+
uint8_t empty_checksum_data[ 2 ] = { 0, 0 };
152+
149153
static char *function = "libfsext_group_descriptor_read_data";
150154
size_t group_descriptor_data_size = 0;
151155
uint64_t value_64bit = 0;
156+
uint32_t calculated_checksum = 0;
157+
uint32_t stored_checksum = 0;
152158
uint32_t value_32bit = 0;
153-
154-
#if defined( HAVE_DEBUG_OUTPUT )
155159
uint16_t value_16bit = 0;
156-
#endif
157160

158161
if( group_descriptor == NULL )
159162
{
@@ -331,6 +334,12 @@ int libfsext_group_descriptor_read_data(
331334
( (fsext_group_descriptor_ext4_t *) data )->number_of_unused_inodes_lower,
332335
group_descriptor->number_of_unused_inodes );
333336

337+
byte_stream_copy_to_uint16_little_endian(
338+
( (fsext_group_descriptor_ext4_t *) data )->checksum,
339+
value_16bit );
340+
341+
stored_checksum = value_16bit;
342+
334343
#if defined( HAVE_DEBUG_OUTPUT )
335344
if( libcnotify_verbose != 0 )
336345
{
@@ -587,21 +596,123 @@ int libfsext_group_descriptor_read_data(
587596
function,
588597
group_descriptor->number_of_unused_inodes );
589598

590-
libcnotify_printf(
591-
"%s: block bitmap checksum\t\t\t: 0x%04" PRIx32 "\n",
592-
function,
593-
group_descriptor->block_bitmap_checksum );
599+
if( ( io_handle->read_only_compatible_features_flags & LIBFSEXT_READ_ONLY_COMPATIBLE_FEATURES_FLAG_METADATA_CHECKSUM ) != 0 )
600+
{
601+
libcnotify_printf(
602+
"%s: block bitmap checksum\t\t\t: 0x%08" PRIx32 "\n",
603+
function,
604+
group_descriptor->block_bitmap_checksum );
594605

595-
libcnotify_printf(
596-
"%s: inode bitmap checksum\t\t\t: 0x%04" PRIx32 "\n",
597-
function,
598-
group_descriptor->inode_bitmap_checksum );
606+
libcnotify_printf(
607+
"%s: inode bitmap checksum\t\t\t: 0x%08" PRIx32 "\n",
608+
function,
609+
group_descriptor->inode_bitmap_checksum );
610+
}
611+
else
612+
{
613+
libcnotify_printf(
614+
"%s: block bitmap checksum\t\t\t: 0x%04" PRIx32 "\n",
615+
function,
616+
group_descriptor->block_bitmap_checksum );
599617

618+
libcnotify_printf(
619+
"%s: inode bitmap checksum\t\t\t: 0x%04" PRIx32 "\n",
620+
function,
621+
group_descriptor->inode_bitmap_checksum );
622+
}
600623
libcnotify_printf(
601624
"\n" );
602625
}
603626
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
604627
}
628+
/* TODO add support for crc16 checksum */
629+
if( ( io_handle->read_only_compatible_features_flags & LIBFSEXT_READ_ONLY_COMPATIBLE_FEATURES_FLAG_METADATA_CHECKSUM ) != 0 )
630+
{
631+
byte_stream_copy_from_uint32_little_endian(
632+
checksum_data,
633+
group_descriptor->group_number );
634+
635+
if( libfsext_checksum_calculate_crc32(
636+
&calculated_checksum,
637+
checksum_data,
638+
4,
639+
io_handle->metadata_checksum_seed,
640+
error ) != 1 )
641+
{
642+
libcerror_error_set(
643+
error,
644+
LIBCERROR_ERROR_DOMAIN_RUNTIME,
645+
LIBCERROR_RUNTIME_ERROR_SET_FAILED,
646+
"%s: unable to calculate CRC-32.",
647+
function );
648+
649+
return( -1 );
650+
}
651+
if( libfsext_checksum_calculate_crc32(
652+
&calculated_checksum,
653+
data,
654+
30,
655+
calculated_checksum,
656+
error ) != 1 )
657+
{
658+
libcerror_error_set(
659+
error,
660+
LIBCERROR_ERROR_DOMAIN_RUNTIME,
661+
LIBCERROR_RUNTIME_ERROR_SET_FAILED,
662+
"%s: unable to calculate CRC-32.",
663+
function );
664+
665+
return( -1 );
666+
}
667+
if( libfsext_checksum_calculate_crc32(
668+
&calculated_checksum,
669+
empty_checksum_data,
670+
2,
671+
calculated_checksum,
672+
error ) != 1 )
673+
{
674+
libcerror_error_set(
675+
error,
676+
LIBCERROR_ERROR_DOMAIN_RUNTIME,
677+
LIBCERROR_RUNTIME_ERROR_SET_FAILED,
678+
"%s: unable to calculate CRC-32.",
679+
function );
680+
681+
return( -1 );
682+
}
683+
if( libfsext_checksum_calculate_crc32(
684+
&calculated_checksum,
685+
&( data[ 32 ] ),
686+
data_size - 32,
687+
calculated_checksum,
688+
error ) != 1 )
689+
{
690+
libcerror_error_set(
691+
error,
692+
LIBCERROR_ERROR_DOMAIN_RUNTIME,
693+
LIBCERROR_RUNTIME_ERROR_SET_FAILED,
694+
"%s: unable to calculate CRC-32.",
695+
function );
696+
697+
return( -1 );
698+
}
699+
calculated_checksum = ( 0xffffffffUL - calculated_checksum ) & 0x0000ffffUL;
700+
701+
if( ( stored_checksum != 0 )
702+
&& ( stored_checksum != calculated_checksum ) )
703+
{
704+
#if defined( HAVE_DEBUG_OUTPUT )
705+
if( libcnotify_verbose != 0 )
706+
{
707+
libcnotify_printf(
708+
"%s: mismatch in checksum ( 0x%08" PRIx32 " != 0x%08" PRIx32 " ).\n",
709+
function,
710+
stored_checksum,
711+
calculated_checksum );
712+
}
713+
#endif
714+
}
715+
}
605716
return( 1 );
606717
}
607718

libfsext/libfsext_group_descriptor.h

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ typedef struct libfsext_group_descriptor libfsext_group_descriptor_t;
3737

3838
struct libfsext_group_descriptor
3939
{
40+
/* Group number
41+
*/
42+
uint32_t group_number;
43+
4044
/* Block bitmap block number
4145
*/
4246
uint64_t block_bitmap_block_number;

libfsext/libfsext_inode.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,6 @@ int libfsext_inode_clone(
406406
int libfsext_inode_read_data(
407407
libfsext_inode_t *inode,
408408
libfsext_io_handle_t *io_handle,
409-
uint32_t inode_number,
410409
const uint8_t *data,
411410
size_t data_size,
412411
libcerror_error_t **error )
@@ -1520,7 +1519,7 @@ int libfsext_inode_read_data(
15201519
{
15211520
byte_stream_copy_from_uint32_little_endian(
15221521
checksum_data,
1523-
inode_number + 1 );
1522+
inode->inode_number );
15241523

15251524
if( libfsext_checksum_calculate_crc32(
15261525
&calculated_checksum,
@@ -2562,7 +2561,7 @@ int libfsext_inode_read_element_data(
25622561
LIBFSEXT_UNREFERENCED_PARAMETER( element_flags )
25632562
LIBFSEXT_UNREFERENCED_PARAMETER( read_flags )
25642563

2565-
if( (uint64_t) element_index > (uint64_t) UINT32_MAX )
2564+
if( (uint64_t) element_index > (uint64_t) ( UINT32_MAX - 1 ) )
25662565
{
25672566
libcerror_error_set(
25682567
error,
@@ -2642,10 +2641,11 @@ int libfsext_inode_read_element_data(
26422641

26432642
goto on_error;
26442643
}
2644+
inode->inode_number = (uint32_t) element_index + 1;
2645+
26452646
if( libfsext_inode_read_data(
26462647
inode,
26472648
io_handle,
2648-
(uint32_t) element_index,
26492649
data,
26502650
(size_t) element_data_size,
26512651
error ) != 1 )

libfsext/libfsext_inode.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ typedef struct libfsext_inode libfsext_inode_t;
4040

4141
struct libfsext_inode
4242
{
43+
/* Inode number
44+
*/
45+
uint32_t inode_number;
46+
4347
/* File mode
4448
*/
4549
uint16_t file_mode;
@@ -154,7 +158,6 @@ int libfsext_inode_clone(
154158
int libfsext_inode_read_data(
155159
libfsext_inode_t *inode,
156160
libfsext_io_handle_t *io_handle,
157-
uint32_t inode_number,
158161
const uint8_t *data,
159162
size_t data_size,
160163
libcerror_error_t **error );

libfsext/libfsext_volume.c

+2
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,8 @@ int libfsext_internal_volume_read_block_groups(
14211421

14221422
goto on_error;
14231423
}
1424+
group_descriptor->group_number = group_descriptor_index;
1425+
14241426
if( libfsext_group_descriptor_read_file_io_handle(
14251427
group_descriptor,
14261428
internal_volume->io_handle,

tests/fsext_test_block_vector.c

-2
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ int fsext_test_block_vector_initialize(
173173
result = libfsext_inode_read_data(
174174
inode,
175175
io_handle,
176-
0,
177176
fsext_test_inode_data1,
178177
128,
179178
&error );
@@ -469,7 +468,6 @@ int fsext_test_block_vector_read_element_data(
469468
result = libfsext_inode_read_data(
470469
inode,
471470
io_handle,
472-
0,
473471
fsext_test_inode_data1,
474472
128,
475473
&error );

tests/fsext_test_directory.c

-2
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,6 @@ int fsext_test_directory_read_file_io_handle(
470470
result = libfsext_inode_read_data(
471471
inode,
472472
io_handle,
473-
0,
474473
fsext_test_inode_data1,
475474
128,
476475
&error );
@@ -1067,7 +1066,6 @@ int main(
10671066
result = libfsext_inode_read_data(
10681067
inode,
10691068
io_handle,
1070-
0,
10711069
fsext_test_inode_data1,
10721070
128,
10731071
&error );

0 commit comments

Comments
 (0)