mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
ubifs: xattr: Don't operate on deleted inodes
commit11a6fc3dc7upstream. xattr operations can race with unlink and the following assert triggers: UBIFS assert failed in ubifs_jnl_change_xattr at 1606 (pid 6256) Fix this by checking i_nlink before working on the host inode. Cc: <stable@vger.kernel.org> Fixes:1e51764a3c("UBIFS: add new flash file system") Signed-off-by: Richard Weinberger <richard@nod.at> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
f6d7acc1d9
commit
8a23348d76
@@ -152,6 +152,12 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
|
||||
ui->data_len = size;
|
||||
|
||||
mutex_lock(&host_ui->ui_mutex);
|
||||
|
||||
if (!host->i_nlink) {
|
||||
err = -ENOENT;
|
||||
goto out_noent;
|
||||
}
|
||||
|
||||
host->i_ctime = current_time(host);
|
||||
host_ui->xattr_cnt += 1;
|
||||
host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
|
||||
@@ -183,6 +189,7 @@ out_cancel:
|
||||
host_ui->xattr_size -= CALC_XATTR_BYTES(size);
|
||||
host_ui->xattr_names -= fname_len(nm);
|
||||
host_ui->flags &= ~UBIFS_CRYPT_FL;
|
||||
out_noent:
|
||||
mutex_unlock(&host_ui->ui_mutex);
|
||||
out_free:
|
||||
make_bad_inode(inode);
|
||||
@@ -234,6 +241,12 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
|
||||
mutex_unlock(&ui->ui_mutex);
|
||||
|
||||
mutex_lock(&host_ui->ui_mutex);
|
||||
|
||||
if (!host->i_nlink) {
|
||||
err = -ENOENT;
|
||||
goto out_noent;
|
||||
}
|
||||
|
||||
host->i_ctime = current_time(host);
|
||||
host_ui->xattr_size -= CALC_XATTR_BYTES(old_size);
|
||||
host_ui->xattr_size += CALC_XATTR_BYTES(size);
|
||||
@@ -255,6 +268,7 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
|
||||
out_cancel:
|
||||
host_ui->xattr_size -= CALC_XATTR_BYTES(size);
|
||||
host_ui->xattr_size += CALC_XATTR_BYTES(old_size);
|
||||
out_noent:
|
||||
mutex_unlock(&host_ui->ui_mutex);
|
||||
make_bad_inode(inode);
|
||||
out_free:
|
||||
@@ -483,6 +497,12 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host,
|
||||
return err;
|
||||
|
||||
mutex_lock(&host_ui->ui_mutex);
|
||||
|
||||
if (!host->i_nlink) {
|
||||
err = -ENOENT;
|
||||
goto out_noent;
|
||||
}
|
||||
|
||||
host->i_ctime = current_time(host);
|
||||
host_ui->xattr_cnt -= 1;
|
||||
host_ui->xattr_size -= CALC_DENT_SIZE(fname_len(nm));
|
||||
@@ -502,6 +522,7 @@ out_cancel:
|
||||
host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
|
||||
host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
|
||||
host_ui->xattr_names += fname_len(nm);
|
||||
out_noent:
|
||||
mutex_unlock(&host_ui->ui_mutex);
|
||||
ubifs_release_budget(c, &req);
|
||||
make_bad_inode(inode);
|
||||
@@ -541,6 +562,9 @@ static int ubifs_xattr_remove(struct inode *host, const char *name)
|
||||
|
||||
ubifs_assert(inode_is_locked(host));
|
||||
|
||||
if (!host->i_nlink)
|
||||
return -ENOENT;
|
||||
|
||||
if (fname_len(&nm) > UBIFS_MAX_NLEN)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user