DF-2562 / fix.diff
diff --git a/sys/vfs/hammer2/hammer2_vnops.c b/sys/vfs/hammer2/hammer2_vnops.c --- a/sys/vfs/hammer2/hammer2_vnops.c +++ b/sys/vfs/hammer2/hammer2_vnops.c @@ -700,14 +700,24 @@ hammer2_cluster_bref(&xop->head.cluster, &bref); if (bref.type == HAMMER2_BREF_TYPE_INODE) { + uint16_t name_len; + ripdata = &hammer2_xop_gdata(&xop->head)->ipdata; dtype = hammer2_get_dtype(ripdata->meta.type); saveoff = bref.key & HAMMER2_DIRHASH_USERMSK; + name_len = ripdata->meta.name_len; + if (name_len > HAMMER2_INODE_MAXNAME) { + kprintf("hammer2_readdir: ignoring inode " + "with corrupt name_len %u\n", + name_len); + hammer2_xop_pdata(&xop->head); + goto next_entry; + } r = vop_write_dirent(&error, uio, ripdata->meta.inum & HAMMER2_DIRHASH_USERMSK, dtype, - ripdata->meta.name_len, + name_len, ripdata->filename); hammer2_xop_pdata(&xop->head); if (r) @@ -721,6 +731,12 @@ dtype = hammer2_get_dtype(bref.embed.dirent.type); saveoff = bref.key & HAMMER2_DIRHASH_USERMSK; namlen = bref.embed.dirent.namlen; + if (namlen > HAMMER2_INODE_MAXNAME) { + kprintf("hammer2_readdir: ignoring dirent " + "with corrupt namlen %u\n", + namlen); + goto next_entry; + } if (namlen <= sizeof(bref.check.buf)) { dname = bref.check.buf; } else { @@ -740,6 +756,9 @@ /* XXX chain error */ kprintf("bad chain type readdir %d\n", bref.type); } + next_entry: + /* label for skipping corrupt entries */ + ; } hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP); if (error == ENOENT) { |