Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+57 -7
+16
fs/minix/inode.c
··· 26 26 struct writeback_control *wbc); 27 27 static int minix_statfs(struct dentry *dentry, struct kstatfs *buf); 28 28 29 + void __minix_error_inode(struct inode *inode, const char *function, 30 + unsigned int line, const char *fmt, ...) 31 + { 32 + struct va_format vaf; 33 + va_list args; 34 + 35 + va_start(args, fmt); 36 + vaf.fmt = fmt; 37 + vaf.va = &args; 38 + printk(KERN_CRIT "minix-fs error (device %s): %s:%d: " 39 + "inode #%lu: comm %s: %pV\n", 40 + inode->i_sb->s_id, function, line, inode->i_ino, 41 + current->comm, &vaf); 42 + va_end(args); 43 + } 44 + 29 45 static void minix_evict_inode(struct inode *inode) 30 46 { 31 47 truncate_inode_pages_final(&inode->i_data);
+9
fs/minix/minix.h
··· 42 42 unsigned short s_version; 43 43 }; 44 44 45 + void __minix_error_inode(struct inode *inode, const char *function, 46 + unsigned int line, const char *fmt, ...); 47 + 45 48 struct inode *minix_iget(struct super_block *, unsigned long); 46 49 struct minix_inode *minix_V1_raw_inode(struct super_block *, ino_t, struct buffer_head **); 47 50 struct minix2_inode *minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **); ··· 170 167 #define minix_find_first_zero_bit find_first_zero_bit_le 171 168 172 169 #endif 170 + 171 + #define minix_error_inode(inode, fmt, ...) \ 172 + __minix_error_inode((inode), __func__, __LINE__, \ 173 + (fmt), ##__VA_ARGS__) 174 + 175 + #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ 173 176 174 177 #endif /* FS_MINIX_H */
+32 -7
fs/minix/namei.c
··· 145 145 struct minix_dir_entry * de; 146 146 int err; 147 147 148 + if (inode->i_nlink == 0) { 149 + minix_error_inode(inode, "inode has corrupted nlink"); 150 + return -EFSCORRUPTED; 151 + } 152 + 148 153 de = minix_find_entry(dentry, &folio); 149 154 if (!de) 150 155 return -ENOENT; ··· 166 161 static int minix_rmdir(struct inode * dir, struct dentry *dentry) 167 162 { 168 163 struct inode * inode = d_inode(dentry); 169 - int err = -ENOTEMPTY; 164 + int err = -EFSCORRUPTED; 170 165 171 - if (minix_empty_dir(inode)) { 172 - err = minix_unlink(dir, dentry); 173 - if (!err) { 174 - inode_dec_link_count(dir); 175 - inode_dec_link_count(inode); 176 - } 166 + if (dir->i_nlink <= 2) { 167 + minix_error_inode(dir, "inode has corrupted nlink"); 168 + goto out; 177 169 } 170 + 171 + err = -ENOTEMPTY; 172 + if (!minix_empty_dir(inode)) 173 + goto out; 174 + 175 + err = minix_unlink(dir, dentry); 176 + if (!err) { 177 + inode_dec_link_count(dir); 178 + inode_dec_link_count(inode); 179 + } 180 + 181 + out: 178 182 return err; 179 183 } 180 184 ··· 221 207 err = -ENOTEMPTY; 222 208 if (dir_de && !minix_empty_dir(new_inode)) 223 209 goto out_dir; 210 + 211 + err = -EFSCORRUPTED; 212 + if (new_inode->i_nlink == 0 || (dir_de && new_inode->i_nlink != 2)) { 213 + minix_error_inode(new_inode, "inode has corrupted nlink"); 214 + goto out_dir; 215 + } 216 + 217 + if (dir_de && old_dir->i_nlink <= 2) { 218 + minix_error_inode(old_dir, "inode has corrupted nlink"); 219 + goto out_dir; 220 + } 224 221 225 222 err = -ENOENT; 226 223 new_de = minix_find_entry(new_dentry, &new_folio);