mirror of https://github.com/torvalds/linux.git
vfs-6.19-rc1.minix
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCaSmOZgAKCRCRxhvAZXjc
olEcAP4qG313oT/tm4W3nC4g2k8S//KqET97B80pSX0K3DvQEwD+LSCf1Th3RnsV
EAMHczmCtRlbcFPqYOFVAMS8VxOyVg0=
=7Ca4
-----END PGP SIGNATURE-----
Merge tag 'vfs-6.19-rc1.minix' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull minix fixes from Christian Brauner:
"Fix two syzbot corruption bugs in the minix filesystem.
Syzbot fuzzes filesystems by trying to mount and manipulate
deliberately corrupted images. This should not lead to BUG_ONs and
WARN_ONs for easy to detect corruptions.
- Add error handling to minix filesystem for inode corruption
detection, enabling the filesystem to report such corruptions
cleanly.
- Fix a drop_nlink warning in minix_rmdir() triggered by corrupted
directory link counts.
- Fix a drop_nlink warning in minix_rename() triggered by corrupted
inode link counts"
* tag 'vfs-6.19-rc1.minix' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
Fix a drop_nlink warning in minix_rename
Fix a drop_nlink warning in minix_rmdir
Add error handling to minix filesystem for inode corruption detection
This commit is contained in:
commit
4664fb427c
|
|
@ -26,6 +26,22 @@ static int minix_write_inode(struct inode *inode,
|
|||
struct writeback_control *wbc);
|
||||
static int minix_statfs(struct dentry *dentry, struct kstatfs *buf);
|
||||
|
||||
void __minix_error_inode(struct inode *inode, const char *function,
|
||||
unsigned int line, const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
printk(KERN_CRIT "minix-fs error (device %s): %s:%d: "
|
||||
"inode #%lu: comm %s: %pV\n",
|
||||
inode->i_sb->s_id, function, line, inode->i_ino,
|
||||
current->comm, &vaf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void minix_evict_inode(struct inode *inode)
|
||||
{
|
||||
truncate_inode_pages_final(&inode->i_data);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ struct minix_sb_info {
|
|||
unsigned short s_version;
|
||||
};
|
||||
|
||||
void __minix_error_inode(struct inode *inode, const char *function,
|
||||
unsigned int line, const char *fmt, ...);
|
||||
|
||||
struct inode *minix_iget(struct super_block *, unsigned long);
|
||||
struct minix_inode *minix_V1_raw_inode(struct super_block *, ino_t, struct buffer_head **);
|
||||
struct minix2_inode *minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **);
|
||||
|
|
@ -168,4 +171,10 @@ static inline int minix_test_bit(int nr, const void *vaddr)
|
|||
|
||||
#endif
|
||||
|
||||
#define minix_error_inode(inode, fmt, ...) \
|
||||
__minix_error_inode((inode), __func__, __LINE__, \
|
||||
(fmt), ##__VA_ARGS__)
|
||||
|
||||
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
|
||||
|
||||
#endif /* FS_MINIX_H */
|
||||
|
|
|
|||
|
|
@ -145,6 +145,11 @@ static int minix_unlink(struct inode * dir, struct dentry *dentry)
|
|||
struct minix_dir_entry * de;
|
||||
int err;
|
||||
|
||||
if (inode->i_nlink == 0) {
|
||||
minix_error_inode(inode, "inode has corrupted nlink");
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
de = minix_find_entry(dentry, &folio);
|
||||
if (!de)
|
||||
return -ENOENT;
|
||||
|
|
@ -161,15 +166,24 @@ static int minix_unlink(struct inode * dir, struct dentry *dentry)
|
|||
static int minix_rmdir(struct inode * dir, struct dentry *dentry)
|
||||
{
|
||||
struct inode * inode = d_inode(dentry);
|
||||
int err = -ENOTEMPTY;
|
||||
int err = -EFSCORRUPTED;
|
||||
|
||||
if (minix_empty_dir(inode)) {
|
||||
err = minix_unlink(dir, dentry);
|
||||
if (!err) {
|
||||
inode_dec_link_count(dir);
|
||||
inode_dec_link_count(inode);
|
||||
}
|
||||
if (dir->i_nlink <= 2) {
|
||||
minix_error_inode(dir, "inode has corrupted nlink");
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = -ENOTEMPTY;
|
||||
if (!minix_empty_dir(inode))
|
||||
goto out;
|
||||
|
||||
err = minix_unlink(dir, dentry);
|
||||
if (!err) {
|
||||
inode_dec_link_count(dir);
|
||||
inode_dec_link_count(inode);
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -208,6 +222,17 @@ static int minix_rename(struct mnt_idmap *idmap,
|
|||
if (dir_de && !minix_empty_dir(new_inode))
|
||||
goto out_dir;
|
||||
|
||||
err = -EFSCORRUPTED;
|
||||
if (new_inode->i_nlink == 0 || (dir_de && new_inode->i_nlink != 2)) {
|
||||
minix_error_inode(new_inode, "inode has corrupted nlink");
|
||||
goto out_dir;
|
||||
}
|
||||
|
||||
if (dir_de && old_dir->i_nlink <= 2) {
|
||||
minix_error_inode(old_dir, "inode has corrupted nlink");
|
||||
goto out_dir;
|
||||
}
|
||||
|
||||
err = -ENOENT;
|
||||
new_de = minix_find_entry(new_dentry, &new_folio);
|
||||
if (!new_de)
|
||||
|
|
|
|||
Loading…
Reference in New Issue