]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
jfs: nlink overflow in jfs_rename
authorJori Koolstra <jkoolstra@xs4all.nl>
Tue, 28 Oct 2025 12:22:12 +0000 (13:22 +0100)
committerDave Kleikamp <dave.kleikamp@oracle.com>
Tue, 2 Dec 2025 16:13:32 +0000 (10:13 -0600)
If nlink is maximal for a directory (-1) and inside that directory you
perform a rename for some child directory (not moving from the parent),
then the nlink of the first directory is first incremented and later
decremented. Normally this is fine, but when nlink = -1 this causes a
wrap around to 0, and then drop_nlink issues a warning.

After applying the patch syzbot no longer issues any warnings. I also
ran some basic fs tests to look for any regressions.

Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
Reported-by: syzbot+9131ddfd7870623b719f@syzkaller.appspotmail.com
Closes: https://syzbot.org/bug?extid=9131ddfd7870623b719f
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
fs/jfs/namei.c

index 65a218eba8faf9508f5727515b812f6de2661618..7879c049632b3deef2fb5a92a44c4b0b4cf94cde 100644 (file)
@@ -1228,7 +1228,7 @@ static int jfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
                                jfs_err("jfs_rename: dtInsert returned -EIO");
                        goto out_tx;
                }
-               if (S_ISDIR(old_ip->i_mode))
+               if (S_ISDIR(old_ip->i_mode) && old_dir != new_dir)
                        inc_nlink(new_dir);
        }
        /*
@@ -1244,7 +1244,9 @@ static int jfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
                goto out_tx;
        }
        if (S_ISDIR(old_ip->i_mode)) {
-               drop_nlink(old_dir);
+               if (new_ip || old_dir != new_dir)
+                       drop_nlink(old_dir);
+
                if (old_dir != new_dir) {
                        /*
                         * Change inode number of parent for moved directory