@@ -65,6 +65,29 @@ static const int PART0_END = 100;
6565static const int PART1_OFF = 101 ;
6666static const int PART1_END = 200 ;
6767
68+ static uint32_t test_crc32 (const uint8_t * data , uint32_t len )
69+ {
70+ uint32_t crc = 0xFFFFFFFFU ;
71+ uint32_t i ;
72+ uint32_t j ;
73+
74+ for (i = 0 ; i < len ; i ++ ) {
75+ crc ^= data [i ];
76+ for (j = 0 ; j < 8 ; j ++ ) {
77+ uint32_t mask = - (crc & 1U );
78+ crc = (crc >> 1 ) ^ (0xEDB88320U & mask );
79+ }
80+ }
81+
82+ return ~crc ;
83+ }
84+
85+ static void finalize_gpt_header_crc (struct guid_ptable * hdr )
86+ {
87+ hdr -> hdr_crc32 = 0 ;
88+ hdr -> hdr_crc32 = test_crc32 ((const uint8_t * )hdr , hdr -> hdr_size );
89+ }
90+
6891/* --- Helpers to build fake disk layouts --- */
6992
7093/* Write a UTF-16LE string into a buffer (no BOM).
@@ -133,6 +156,8 @@ static void build_gpt_disk(void)
133156 (PART0_END - PART0_OFF + 1 ) * GPT_SECTOR_SIZE );
134157 memset (fake_disk + PART1_OFF * GPT_SECTOR_SIZE , 0xBB ,
135158 (PART1_END - PART1_OFF + 1 ) * GPT_SECTOR_SIZE );
159+
160+ finalize_gpt_header_crc (gpt_hdr );
136161}
137162
138163/* Populate fake_disk with MBR-only layout (no GPT protective entry).
@@ -200,6 +225,17 @@ START_TEST(test_gpt_parse_header)
200225 ck_assert_uint_eq (hdr .start_array , 2 );
201226 ck_assert_uint_eq (hdr .array_sz , 128 );
202227
228+ /* Corrupt a header field without updating CRC */
229+ {
230+ struct guid_ptable * gpt_hdr =
231+ (struct guid_ptable * )(fake_disk + GPT_SECTOR_SIZE );
232+ gpt_hdr -> n_part = 3 ;
233+ ck_assert_int_eq (
234+ gpt_parse_header (fake_disk + GPT_SECTOR_SIZE , & hdr ), -1 );
235+ gpt_hdr -> n_part = 2 ;
236+ finalize_gpt_header_crc (gpt_hdr );
237+ }
238+
203239 /* Corrupt signature in the real header */
204240 {
205241 struct guid_ptable * gpt_hdr =
@@ -208,6 +244,7 @@ START_TEST(test_gpt_parse_header)
208244 ck_assert_int_eq (
209245 gpt_parse_header (fake_disk + GPT_SECTOR_SIZE , & hdr ), -1 );
210246 gpt_hdr -> signature = GPT_SIGNATURE ;
247+ finalize_gpt_header_crc (gpt_hdr );
211248 }
212249
213250 /* NULL inputs */
@@ -537,6 +574,7 @@ START_TEST(test_disk_open_gpt_excess_partitions)
537574
538575 gpt_hdr = (struct guid_ptable * )(fake_disk + GPT_SECTOR_SIZE );
539576 gpt_hdr -> n_part = MAX_PARTITIONS + 10 ;
577+ finalize_gpt_header_crc (gpt_hdr );
540578
541579 /* Only 2 actual entries on disk so loop will break after parsing them,
542580 * but the capping branch is exercised. */
@@ -555,6 +593,7 @@ START_TEST(test_disk_open_gpt_large_array_sz)
555593
556594 gpt_hdr = (struct guid_ptable * )(fake_disk + GPT_SECTOR_SIZE );
557595 gpt_hdr -> array_sz = GPT_PART_ENTRY_SIZE + 1 ; /* 257 > 256 */
596+ finalize_gpt_header_crc (gpt_hdr );
558597
559598 ck_assert_int_eq (disk_open (0 ), 0 ); /* 0 partitions found */
560599}
@@ -571,6 +610,7 @@ START_TEST(test_disk_open_gpt_empty_entry_mid_table)
571610
572611 gpt_hdr = (struct guid_ptable * )(fake_disk + GPT_SECTOR_SIZE );
573612 gpt_hdr -> n_part = 3 ;
613+ finalize_gpt_header_crc (gpt_hdr );
574614
575615 /* Zero out entry 1's type GUID */
576616 pe = (struct gpt_part_entry * )(fake_disk + 2 * GPT_SECTOR_SIZE + 128 );
0 commit comments