BTNodeDescriptor *srcDesc = src->buffer;
u_int16_t *srcOffs = NULL;
BTreeControlBlockPtr btcb = (BTreeControlBlockPtr)VTOF(vp)->fcbBTCBPtr;
- u_int32_t i;
+ u_int16_t i; /* index to match srcDesc->numRecords */
int error = 0;
#ifdef ENDIAN_DEBUG
if (direction == kSwapBTNodeBigToHost) {
- printf ("BE -> Native Swap\n");
+ printf ("hfs: BE -> Native Swap\n");
} else if (direction == kSwapBTNodeHostToBig) {
- printf ("Native -> BE Swap\n");
+ printf ("hfs: Native -> BE Swap\n");
} else if (direction == kSwapBTNodeHeaderRecordOnly) {
- printf ("Not swapping descriptors\n");
+ printf ("hfs: Not swapping descriptors\n");
} else {
panic ("hfs_swap_BTNode: This is impossible");
}
/*
* When first opening a BTree, we have to read the header node before the
* control block is initialized. In this case, totalNodes will be zero,
- * so skip the bounds checking.
+ * so skip the bounds checking. Also, we should ignore the header node when
+ * checking for invalid forwards and backwards links, since the header node's
+ * links can point back to itself legitimately.
*/
if (btcb->totalNodes != 0) {
if (srcDesc->fLink >= btcb->totalNodes) {
error = fsBTInvalidHeaderErr;
goto fail;
}
+
+ if ((src->blockNum != 0) && (srcDesc->fLink == (u_int32_t) src->blockNum)) {
+ printf("hfs_swap_BTNode: invalid forward link (0x%08x == 0x%08x)\n",
+ srcDesc->fLink, (u_int32_t) src->blockNum);
+ error = fsBTInvalidHeaderErr;
+ goto fail;
+ }
+ if ((src->blockNum != 0) && (srcDesc->bLink == (u_int32_t) src->blockNum)) {
+ printf("hfs_swap_BTNode: invalid backward link (0x%08x == 0x%08x)\n",
+ srcDesc->bLink, (u_int32_t) src->blockNum);
+ error = fsBTInvalidHeaderErr;
+ goto fail;
+ }
+
+
}
/*
if (direction == kSwapBTNodeHostToBig) {
/*
* Sanity check and swap the forward and backward links.
+ * Ignore the header node since its forward and backwards links can legitimately
+ * point to itself.
*/
if (srcDesc->fLink >= btcb->totalNodes) {
panic("hfs_UNswap_BTNode: invalid forward link (0x%08X)\n", srcDesc->fLink);
error = fsBTInvalidHeaderErr;
goto fail;
}
+ if ((src->blockNum != 0) && (srcDesc->fLink == (u_int32_t) src->blockNum)) {
+ panic ("hfs_UNswap_BTNode: invalid forward link (0x%08x == 0x%08x)\n",
+ srcDesc->fLink, (u_int32_t) src->blockNum);
+ error = fsBTInvalidHeaderErr;
+ goto fail;
+ }
+
if (srcDesc->bLink >= btcb->totalNodes) {
panic("hfs_UNswap_BTNode: invalid backward link (0x%08X)\n", srcDesc->bLink);
error = fsBTInvalidHeaderErr;
goto fail;
}
+ if ((src->blockNum != 0) && (srcDesc->bLink == (u_int32_t) src->blockNum)) {
+ panic ("hfs_UNswap_BTNode: invalid backward link (0x%08x == 0x%08x)\n",
+ srcDesc->bLink, (u_int32_t) src->blockNum);
+ error = fsBTInvalidHeaderErr;
+ goto fail;
+ }
+
+
srcDesc->fLink = SWAP_BE32 (srcDesc->fLink);
srcDesc->bLink = SWAP_BE32 (srcDesc->bLink);
/*
* Log some useful information about where the corrupt node is.
*/
- printf("node=%lld fileID=%u volume=%s device=%s\n", src->blockNum, VTOC(vp)->c_fileid,
+ printf("hfs: node=%lld fileID=%u volume=%s device=%s\n", src->blockNum, VTOC(vp)->c_fileid,
VTOVCB(vp)->vcbVN, vfs_statfs(vnode_mount(vp))->f_mntfromname);
hfs_mark_volume_inconsistent(VTOVCB(vp));
}
* to be sure the current record doesn't overflow into the next
* record.
*/
- nextRecord = (char *)src->buffer + srcOffs[i-1];
+ nextRecord = (char *)src->buffer + (uintptr_t)(srcOffs[i-1]);
/*
* Make sure we can safely dereference the keyLength and parentID fields.