Skip to content

Commit 8a23348

Browse files
richardweinbergergregkh
authored andcommitted
ubifs: xattr: Don't operate on deleted inodes
commit 11a6fc3 upstream. 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: <[email protected]> Fixes: 1e51764 ("UBIFS: add new flash file system") Signed-off-by: Richard Weinberger <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent f6d7acc commit 8a23348

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

fs/ubifs/xattr.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
152152
ui->data_len = size;
153153

154154
mutex_lock(&host_ui->ui_mutex);
155+
156+
if (!host->i_nlink) {
157+
err = -ENOENT;
158+
goto out_noent;
159+
}
160+
155161
host->i_ctime = current_time(host);
156162
host_ui->xattr_cnt += 1;
157163
host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
@@ -183,6 +189,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
183189
host_ui->xattr_size -= CALC_XATTR_BYTES(size);
184190
host_ui->xattr_names -= fname_len(nm);
185191
host_ui->flags &= ~UBIFS_CRYPT_FL;
192+
out_noent:
186193
mutex_unlock(&host_ui->ui_mutex);
187194
out_free:
188195
make_bad_inode(inode);
@@ -234,6 +241,12 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
234241
mutex_unlock(&ui->ui_mutex);
235242

236243
mutex_lock(&host_ui->ui_mutex);
244+
245+
if (!host->i_nlink) {
246+
err = -ENOENT;
247+
goto out_noent;
248+
}
249+
237250
host->i_ctime = current_time(host);
238251
host_ui->xattr_size -= CALC_XATTR_BYTES(old_size);
239252
host_ui->xattr_size += CALC_XATTR_BYTES(size);
@@ -255,6 +268,7 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
255268
out_cancel:
256269
host_ui->xattr_size -= CALC_XATTR_BYTES(size);
257270
host_ui->xattr_size += CALC_XATTR_BYTES(old_size);
271+
out_noent:
258272
mutex_unlock(&host_ui->ui_mutex);
259273
make_bad_inode(inode);
260274
out_free:
@@ -483,6 +497,12 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host,
483497
return err;
484498

485499
mutex_lock(&host_ui->ui_mutex);
500+
501+
if (!host->i_nlink) {
502+
err = -ENOENT;
503+
goto out_noent;
504+
}
505+
486506
host->i_ctime = current_time(host);
487507
host_ui->xattr_cnt -= 1;
488508
host_ui->xattr_size -= CALC_DENT_SIZE(fname_len(nm));
@@ -502,6 +522,7 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host,
502522
host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
503523
host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
504524
host_ui->xattr_names += fname_len(nm);
525+
out_noent:
505526
mutex_unlock(&host_ui->ui_mutex);
506527
ubifs_release_budget(c, &req);
507528
make_bad_inode(inode);
@@ -541,6 +562,9 @@ static int ubifs_xattr_remove(struct inode *host, const char *name)
541562

542563
ubifs_assert(inode_is_locked(host));
543564

565+
if (!host->i_nlink)
566+
return -ENOENT;
567+
544568
if (fname_len(&nm) > UBIFS_MAX_NLEN)
545569
return -ENAMETOOLONG;
546570

0 commit comments

Comments
 (0)