DF-0875 / verify_image.c
/* * verify_image.c - Read each HAMMER2 volume header copy and confirm * the three CRC32C values match what the kernel expects. Used to * sanity-check patch_image.c's CRC implementation BEFORE mounting. * * Build: cc -O2 -o verify_image verify_image.c * Run: ./verify_image <image-file> * Exit: 0 if all present copies verify, 1 if any mismatch. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <unistd.h> #include <fcntl.h> #include <inttypes.h> static uint32_t crc32c_table[256]; static void init_crc32c(void) { for (uint32_t i = 0; i < 256; i++) { uint32_t crc = i; for (int j = 0; j < 8; j++) crc = (crc >> 1) ^ (0x82F63B78u & (uint32_t)(-(int32_t)(crc & 1))); crc32c_table[i] = crc; } } static uint32_t crc32c(const uint8_t *buf, size_t len) { uint32_t crc = 0xFFFFFFFFu; for (size_t i = 0; i < len; i++) crc = (crc >> 8) ^ crc32c_table[(crc ^ buf[i]) & 0xFF]; return ~crc; } #define H2_VOLUME_BYTES 65536 #define H2_ZONE_BYTES64 (2LL * 1024 * 1024 * 1024) #define H2_NUM_VOLHDRS 4 #define H2_VOLUME_ID_HBO 0x48414d3205172011ULL #define DATA_OFF_OFF 0x220 int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "usage: %s <image>\n", argv[0]); return 2; } init_crc32c(); int fd = open(argv[1], O_RDONLY); if (fd < 0) { perror("open"); return 1; } uint8_t *buf = malloc(H2_VOLUME_BYTES); int ok = 0, bad = 0; for (int i = 0; i < H2_NUM_VOLHDRS; i++) { off_t off = (off_t)i * H2_ZONE_BYTES64; ssize_t r = pread(fd, buf, H2_VOLUME_BYTES, off); if (r != H2_VOLUME_BYTES) continue; uint64_t magic; memcpy(&magic, buf, 8); if (magic != H2_VOLUME_ID_HBO) continue; uint32_t e0, c0, e1, c1, evh, cvh; memcpy(&e0, buf + 0x1E0 + 7*4, 4); memcpy(&e1, buf + 0x1E0 + 6*4, 4); memcpy(&evh, buf + 0xFFFC, 4); c0 = crc32c(buf + 0, 508); c1 = crc32c(buf + 512, 512); cvh = crc32c(buf + 0, 65532); uint64_t data_off; memcpy(&data_off, buf + DATA_OFF_OFF, 8); int good = (e0==c0 && e1==c1 && evh==cvh); printf("copy %d: data_off=0x%016" PRIx64 " ICRC0 exp=%08x got=%08x %s | ICRC1 exp=%08x got=%08x %s | ICRCVH exp=%08x got=%08x %s\n", i, data_off, e0, c0, e0==c0?"OK":"MISMATCH", e1, c1, e1==c1?"OK":"MISMATCH", evh, cvh, evh==cvh?"OK":"MISMATCH"); if (good) ok++; else bad++; } free(buf); close(fd); fprintf(stderr, "%d copies OK, %d BAD\n", ok, bad); return bad ? 1 : 0; } |