FAILED: patch "[PATCH] ubifs: xattr: Don't operate on deleted inodes" failed to apply to 4.9-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
11a6fc3dc743e22fb50f2196ec55bee5140d3c52Mon Sep 17 00:00:00 2001
From: Richard Weinberger <[email protected]>
Date: Sun, 8 Jul 2018 23:33:25 +0200
Subject: [PATCH] ubifs: xattr: Don't operate on deleted inodes
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 1e51764a3c2a ("UBIFS: add new flash file system")
Signed-off-by Richard Weinberger <[email protected]>
fs/ubifs/xattr.c +24 -0
@@ -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));
@@ -184,6 +190,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host, 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);
@@ -235,6 +242,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);
@@ -256,6 +269,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:
@@ -482,6 +496,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));
@@ -501,6 +521,7 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host, 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);
@@ -540,6 +561,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 ;