Commit b9385855 authored by Richard Weinberger's avatar Richard Weinberger Committed by Greg Kroah-Hartman

ubifs: Fix O_TMPFILE corner case in ubifs_link()

commit 32fe905c upstream.

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: Ralph Sennhauser <ralph.sennhauser@gmail.com>
Cc: Amir Goldstein <amir73il@gmail.com>
Reported-by: default avatarRalph Sennhauser <ralph.sennhauser@gmail.com>
Tested-by: default avatarRalph Sennhauser <ralph.sennhauser@gmail.com>
Reported-by: default avatarAmir Goldstein <amir73il@gmail.com>
Fixes: 474b9370 ("ubifs: Implement O_TMPFILE")
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a260ff50
...@@ -622,6 +622,11 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, ...@@ -622,6 +622,11 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
return err; return err;
lock_2_inodes(dir, inode); lock_2_inodes(dir, inode);
/* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */
if (inode->i_nlink == 0)
ubifs_delete_orphan(c, inode->i_ino);
inc_nlink(inode); inc_nlink(inode);
ihold(inode); ihold(inode);
inode->i_ctime = ubifs_current_time(inode); inode->i_ctime = ubifs_current_time(inode);
...@@ -641,6 +646,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, ...@@ -641,6 +646,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
dir->i_size -= sz_change; dir->i_size -= sz_change;
dir_ui->ui_size = dir->i_size; dir_ui->ui_size = dir->i_size;
drop_nlink(inode); drop_nlink(inode);
if (inode->i_nlink == 0)
ubifs_add_orphan(c, inode->i_ino);
unlock_2_inodes(dir, inode); unlock_2_inodes(dir, inode);
ubifs_release_budget(c, &req); ubifs_release_budget(c, &req);
iput(inode); iput(inode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment