[PATCH] Fix a drop_nlink warning in minix_rename

Jori Koolstra posted 1 patch 3 months, 1 week ago
fs/minix/namei.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
[PATCH] Fix a drop_nlink warning in minix_rename
Posted by Jori Koolstra 3 months, 1 week ago
Syzbot found a drop_nlink warning that is triggered by an easy to
detect nlink corruption. This patch adds sanity checks to minix_unlink
and minix_rename to prevent the warning and instead return EFSCORRUPTED
to the caller.

The changes were tested using the syzbot reproducer as well as local
testing.

Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
Reported-by: syzbot+a65e824272c5f741247d@syzkaller.appspotmail.com
Closes: https://syzbot.org/bug?extid=a65e824272c5f741247d
---
 fs/minix/namei.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index a8d5a7e22b7b..4bc1d9c31284 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -145,6 +145,12 @@ static int minix_unlink(struct inode * dir, struct dentry *dentry)
 	struct minix_dir_entry * de;
 	int err;
 
+	if (inode->i_nlink < 1) {
+		printk(KERN_CRIT "minix-fs error: inode (ino: %ld) "
+		       "has corrupted nlink", inode->i_ino);
+		return -EFSCORRUPTED;
+	}
+
 	de = minix_find_entry(dentry, &folio);
 	if (!de)
 		return -ENOENT;
@@ -218,6 +224,13 @@ 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)) {
+			printk(KERN_CRIT "minix-fs error: inode (ino: %ld) "
+			       "has corrupted nlink", new_inode->i_ino);
+			goto out_dir;
+		}
+
 		err = -ENOENT;
 		new_de = minix_find_entry(new_dentry, &new_folio);
 		if (!new_de)
-- 
2.51.1.dirty
Re: [PATCH] Fix a drop_nlink warning in minix_rename
Posted by Jan Kara 3 months ago
On Sun 02-11-25 19:25:32, Jori Koolstra wrote:
> Syzbot found a drop_nlink warning that is triggered by an easy to
> detect nlink corruption. This patch adds sanity checks to minix_unlink
> and minix_rename to prevent the warning and instead return EFSCORRUPTED
> to the caller.
> 
> The changes were tested using the syzbot reproducer as well as local
> testing.
> 
> Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
> Reported-by: syzbot+a65e824272c5f741247d@syzkaller.appspotmail.com
> Closes: https://syzbot.org/bug?extid=a65e824272c5f741247d

Two comments below.

> ---
>  fs/minix/namei.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/fs/minix/namei.c b/fs/minix/namei.c
> index a8d5a7e22b7b..4bc1d9c31284 100644
> --- a/fs/minix/namei.c
> +++ b/fs/minix/namei.c
> @@ -145,6 +145,12 @@ static int minix_unlink(struct inode * dir, struct dentry *dentry)
>  	struct minix_dir_entry * de;
>  	int err;
>  
> +	if (inode->i_nlink < 1) {

I guess it makes sense to check here for i_nlink == 0 for consistency.

> +		printk(KERN_CRIT "minix-fs error: inode (ino: %ld) "
> +		       "has corrupted nlink", inode->i_ino);
> +		return -EFSCORRUPTED;
> +	}
> +
>  	de = minix_find_entry(dentry, &folio);
>  	if (!de)
>  		return -ENOENT;
> @@ -218,6 +224,13 @@ 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)) {
> +			printk(KERN_CRIT "minix-fs error: inode (ino: %ld) "
> +			       "has corrupted nlink", new_inode->i_ino);
> +			goto out_dir;
> +		}
> +
>  		err = -ENOENT;
>  		new_de = minix_find_entry(new_dentry, &new_folio);
>  		if (!new_de)

You should also check that 'old_dir' link count is correct. I.e.
		if (dir_de && old_dir->i_nlink <= 2) {
			error out.
		}

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR
Re: [PATCH] Fix a drop_nlink warning in minix_rename
Posted by kernel test robot 3 months ago
Hi Jori,

kernel test robot noticed the following build errors:

[auto build test ERROR on brauner-vfs/vfs.all]
[also build test ERROR on linus/master v6.18-rc4 next-20251103]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Jori-Koolstra/Fix-a-drop_nlink-warning-in-minix_rename/20251103-022646
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git vfs.all
patch link:    https://lore.kernel.org/r/20251102182532.2442670-1-jkoolstra%40xs4all.nl
patch subject: [PATCH] Fix a drop_nlink warning in minix_rename
config: arm-randconfig-004-20251103 (https://download.01.org/0day-ci/archive/20251103/202511031556.5N9lmsZB-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project d2625a438020ad35330cda29c3def102c1687b1b)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251103/202511031556.5N9lmsZB-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511031556.5N9lmsZB-lkp@intel.com/

All errors (new ones prefixed by >>):

>> fs/minix/namei.c:151:11: error: use of undeclared identifier 'EFSCORRUPTED'
     151 |                 return -EFSCORRUPTED;
         |                         ^~~~~~~~~~~~
   fs/minix/namei.c:217:10: error: use of undeclared identifier 'EFSCORRUPTED'
     217 |                 err = -EFSCORRUPTED;
         |                        ^~~~~~~~~~~~
   2 errors generated.


vim +/EFSCORRUPTED +151 fs/minix/namei.c

   140	
   141	static int minix_unlink(struct inode * dir, struct dentry *dentry)
   142	{
   143		struct inode * inode = d_inode(dentry);
   144		struct folio *folio;
   145		struct minix_dir_entry * de;
   146		int err;
   147	
   148		if (inode->i_nlink < 1) {
   149			printk(KERN_CRIT "minix-fs error: inode (ino: %ld) "
   150			       "has corrupted nlink", inode->i_ino);
 > 151			return -EFSCORRUPTED;
   152		}
   153	
   154		de = minix_find_entry(dentry, &folio);
   155		if (!de)
   156			return -ENOENT;
   157		err = minix_delete_entry(de, folio);
   158		folio_release_kmap(folio, de);
   159	
   160		if (err)
   161			return err;
   162		inode_set_ctime_to_ts(inode, inode_get_ctime(dir));
   163		inode_dec_link_count(inode);
   164		return 0;
   165	}
   166	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] Fix a drop_nlink warning in minix_rename
Posted by kernel test robot 3 months ago
Hi Jori,

kernel test robot noticed the following build errors:

[auto build test ERROR on brauner-vfs/vfs.all]
[also build test ERROR on linus/master v6.18-rc4 next-20251031]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Jori-Koolstra/Fix-a-drop_nlink-warning-in-minix_rename/20251103-022646
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git vfs.all
patch link:    https://lore.kernel.org/r/20251102182532.2442670-1-jkoolstra%40xs4all.nl
patch subject: [PATCH] Fix a drop_nlink warning in minix_rename
config: arc-randconfig-r073-20251103 (https://download.01.org/0day-ci/archive/20251103/202511031229.rqpKLU46-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251103/202511031229.rqpKLU46-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511031229.rqpKLU46-lkp@intel.com/

All errors (new ones prefixed by >>):

   fs/minix/namei.c: In function 'minix_unlink':
>> fs/minix/namei.c:151:11: error: 'EFSCORRUPTED' undeclared (first use in this function); did you mean 'FS_NRSUPER'?
      return -EFSCORRUPTED;
              ^~~~~~~~~~~~
              FS_NRSUPER
   fs/minix/namei.c:151:11: note: each undeclared identifier is reported only once for each function it appears in
   fs/minix/namei.c: In function 'minix_rename':
   fs/minix/namei.c:217:10: error: 'EFSCORRUPTED' undeclared (first use in this function); did you mean 'FS_NRSUPER'?
      err = -EFSCORRUPTED;
             ^~~~~~~~~~~~
             FS_NRSUPER


vim +151 fs/minix/namei.c

   140	
   141	static int minix_unlink(struct inode * dir, struct dentry *dentry)
   142	{
   143		struct inode * inode = d_inode(dentry);
   144		struct folio *folio;
   145		struct minix_dir_entry * de;
   146		int err;
   147	
   148		if (inode->i_nlink < 1) {
   149			printk(KERN_CRIT "minix-fs error: inode (ino: %ld) "
   150			       "has corrupted nlink", inode->i_ino);
 > 151			return -EFSCORRUPTED;
   152		}
   153	
   154		de = minix_find_entry(dentry, &folio);
   155		if (!de)
   156			return -ENOENT;
   157		err = minix_delete_entry(de, folio);
   158		folio_release_kmap(folio, de);
   159	
   160		if (err)
   161			return err;
   162		inode_set_ctime_to_ts(inode, inode_get_ctime(dir));
   163		inode_dec_link_count(inode);
   164		return 0;
   165	}
   166	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki