diff --git a/sys/fs/ext2fs/ext2_lookup.c b/fs/ext2fs/ext2_lookup.c --- a/sys/fs/ext2fs/ext2_lookup.c +++ b/fs/ext2fs/ext2_lookup.c @@ -811,6 +811,25 @@ mp->mnt_stat.f_mntonname, ip->i_number, offset, how); } +static char* +ext2_check_root_direntry(struct ext2fs_direct_2 *de) +{ + + if (le32toh(de->e2d_ino) != EXT2_ROOTINO) + return ("not EXT2_ROOTINO"); + + if (de->e2d_namlen != 1 && de->e2d_namlen != 2) + return ("EXT2_ROOTINO bad e2d_namelen"); + + if (de->e2d_name[0] != '.') + return ("EXT2_ROOTINO bad e2d_name"); + + if (de->e2d_namlen == 2 && de->e2d_name[1] != '.') + return ("EXT2_ROOTINO bad e2d_name"); + + return (NULL); +} + /* * Do consistency checking on a directory entry: * record length must be multiple of 4 @@ -818,6 +837,8 @@ * record must be large enough to contain entry * name is not longer than MAXNAMLEN * name must be as long as advertised, and null terminated + * inode number less then inode count + * if root inode entry, it have correct name */ static int ext2_check_direntry(struct vnode *dp, struct ext2fs_direct_2 *de, @@ -836,6 +857,8 @@ error_msg = "directory entry across blocks"; else if (le32toh(de->e2d_ino) > fs->e2fs->e2fs_icount) error_msg = "directory entry inode out of bounds"; + else if (le32toh(de->e2d_ino) == EXT2_ROOTINO) + error_msg = ext2_check_root_direntry(de); if (error_msg != NULL) { SDT_PROBE5(ext2fs, , trace, ext2_dirbadentry_error,