Skip to content

Commit 32fe905

Browse files
ubifs: Fix O_TMPFILE corner case in ubifs_link()
It is perfectly fine to link a tmpfile back using linkat(). Since tmpfiles are created with a link count of 0 they appear on the orphan list, upon re-linking the inode has to be removed from the orphan list again. Ralph faced a filesystem corruption in combination with overlayfs due to this bug. Cc: <[email protected]> Cc: Ralph Sennhauser <[email protected]> Cc: Amir Goldstein <[email protected]> Reported-by: Ralph Sennhauser <[email protected]> Tested-by: Ralph Sennhauser <[email protected]> Reported-by: Amir Goldstein <[email protected]> Fixes: 474b937 ("ubifs: Implement O_TMPFILE") Signed-off-by: Richard Weinberger <[email protected]>
1 parent c3d9fda commit 32fe905

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

fs/ubifs/dir.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,11 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
748748
goto out_fname;
749749

750750
lock_2_inodes(dir, inode);
751+
752+
/* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */
753+
if (inode->i_nlink == 0)
754+
ubifs_delete_orphan(c, inode->i_ino);
755+
751756
inc_nlink(inode);
752757
ihold(inode);
753758
inode->i_ctime = ubifs_current_time(inode);
@@ -768,6 +773,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
768773
dir->i_size -= sz_change;
769774
dir_ui->ui_size = dir->i_size;
770775
drop_nlink(inode);
776+
if (inode->i_nlink == 0)
777+
ubifs_add_orphan(c, inode->i_ino);
771778
unlock_2_inodes(dir, inode);
772779
ubifs_release_budget(c, &req);
773780
iput(inode);

0 commit comments

Comments
 (0)