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;