DF-0798 / fix.diff
diff --git a/sys/vfs/hammer/hammer_vfsops.c b/sys/vfs/hammer/hammer_vfsops.c --- a/sys/vfs/hammer/hammer_vfsops.c +++ b/sys/vfs/hammer/hammer_vfsops.c @@ -735,6 +735,22 @@ sizeof(hmp->blockmap)); hmp->copy_stat_freebigblocks = rootvol->ondisk->vol0_stat_freebigblocks; + /* DF-0798: validate vol0_btree_root before any btree access. + * A crafted image can supply a malformed offset whose low 14 + * bits exceed the bounds of a HAMMER_BUFSIZE-byte buffer minus + * a hammer_node_ondisk, which would cause hammer_load_node() to + * compute an out-of-bounds node->ondisk pointer and then run + * hammer_crc_test_btree() past the end of the buffer. Reject + * the mount cleanly in that case. */ + if (!hammer_is_zone_btree(rootvol->ondisk->vol0_btree_root) || + (rootvol->ondisk->vol0_btree_root & HAMMER_BUFMASK) > + HAMMER_BUFSIZE - sizeof(struct hammer_node_ondisk)) { + hkprintf("malformed vol0_btree_root %016jx\n", + (intmax_t)rootvol->ondisk->vol0_btree_root); + error = EINVAL; + goto done; + } + hammer_flusher_create(hmp); /* |