git: ced217282230 - main - Add more accurate check for root inode
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 30 Dec 2021 06:15:19 UTC
The branch main has been updated by fsu: URL: https://cgit.FreeBSD.org/src/commit/?id=ced21728223016429242d1f7cd5e8a160c8a88cb commit ced21728223016429242d1f7cd5e8a160c8a88cb Author: Fedor Uporov <fsu@FreeBSD.org> AuthorDate: 2021-12-24 14:11:25 +0000 Commit: Fedor Uporov <fsu@FreeBSD.org> CommitDate: 2021-12-30 06:14:45 +0000 Add more accurate check for root inode Check that root inode has links and is directory. PR: 259105 Reported by: Robert Morris MFC after: 2 weeks --- sys/fs/ext2fs/ext2_inode_cnv.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c index 181ea3e04622..445000c509db 100644 --- a/sys/fs/ext2fs/ext2_inode_cnv.c +++ b/sys/fs/ext2fs/ext2_inode_cnv.c @@ -157,9 +157,17 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) return (EINVAL); } + /* + * Godmar thinks - if the link count is zero, then the inode is + * unused - according to ext2 standards. Ufs marks this fact by + * setting i_mode to zero - why ? I can see that this might lead to + * problems in an undelete. + */ ip->i_nlink = le16toh(ei->e2di_nlink); - if (ip->i_number == EXT2_ROOTINO && ip->i_nlink == 0) { - SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "root inode unallocated"); + ip->i_mode = ip->i_nlink ? le16toh(ei->e2di_mode) : 0; + if (ip->i_number == EXT2_ROOTINO && + (ip->i_nlink < 2 || !S_ISDIR(ip->i_mode))) { + SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "root inode invalid"); return (EINVAL); } @@ -174,13 +182,6 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) } } - /* - * Godmar thinks - if the link count is zero, then the inode is - * unused - according to ext2 standards. Ufs marks this fact by - * setting i_mode to zero - why ? I can see that this might lead to - * problems in an undelete. - */ - ip->i_mode = ip->i_nlink ? le16toh(ei->e2di_mode) : 0; ip->i_size = le32toh(ei->e2di_size); if (S_ISREG(ip->i_mode)) ip->i_size |= (uint64_t)le32toh(ei->e2di_size_high) << 32;