Linux-EROFS Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: gregkh@linuxfoundation.org (gregkh@linuxfoundation.org)
Subject: Patch "staging: erofs: fix race of initializing xattrs of a inode at the same time" has been added to the 4.19-stable tree
Date: Tue, 12 Mar 2019 05:57:36 -0700	[thread overview]
Message-ID: <1552395456224210@kroah.com> (raw)
In-Reply-To: <20190311060858.28654-4-gaoxiang25@huawei.com>


This is a note to let you know that I've just added the patch titled

    staging: erofs: fix race of initializing xattrs of a inode at the same time

to the 4.19-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     staging-erofs-fix-race-of-initializing-xattrs-of-a-inode-at-the-same-time.patch
and it can be found in the queue-4.19 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Tue Mar 12 05:46:41 PDT 2019
From: Gao Xiang <gaoxiang25@huawei.com>
Date: Mon, 11 Mar 2019 14:08:57 +0800
Subject: staging: erofs: fix race of initializing xattrs of a inode at the same time
To: <stable at vger.kernel.org>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>, LKML <linux-kernel at vger.kernel.org>, <linux-erofs at lists.ozlabs.org>, Chao Yu <yuchao0 at huawei.com>, Chao Yu <chao at kernel.org>, Miao Xie <miaoxie at huawei.com>, Fang Wei <fangwei1 at huawei.com>, Gao Xiang <gaoxiang25 at huawei.com>
Message-ID: <20190311060858.28654-4-gaoxiang25 at huawei.com>

From: Gao Xiang <gaoxiang25@huawei.com>

commit 62dc45979f3f8cb0ea67302a93bff686f0c46c5a upstream.

In real scenario, there could be several threads accessing xattrs
of the same xattr-uninitialized inode, and init_inode_xattrs()
almost at the same time.

That's actually an unexpected behavior, this patch closes the race.

Fixes: b17500a0fdba ("staging: erofs: introduce xattr & acl support")
Cc: <stable at vger.kernel.org> # 4.19+
Reviewed-by: Chao Yu <yuchao0 at huawei.com>
Signed-off-by: Gao Xiang <gaoxiang25 at huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/staging/erofs/internal.h |   11 +++++++---
 drivers/staging/erofs/xattr.c    |   41 +++++++++++++++++++++++++++------------
 2 files changed, 37 insertions(+), 15 deletions(-)

--- a/drivers/staging/erofs/internal.h
+++ b/drivers/staging/erofs/internal.h
@@ -327,12 +327,17 @@ static inline erofs_off_t iloc(struct er
 	return blknr_to_addr(sbi->meta_blkaddr) + (nid << sbi->islotbits);
 }
 
-#define inode_set_inited_xattr(inode)   (EROFS_V(inode)->flags |= 1)
-#define inode_has_inited_xattr(inode)   (EROFS_V(inode)->flags & 1)
+/* atomic flag definitions */
+#define EROFS_V_EA_INITED_BIT	0
+
+/* bitlock definitions (arranged in reverse order) */
+#define EROFS_V_BL_XATTR_BIT	(BITS_PER_LONG - 1)
 
 struct erofs_vnode {
 	erofs_nid_t nid;
-	unsigned int flags;
+
+	/* atomic flags (including bitlocks) */
+	unsigned long flags;
 
 	unsigned char data_mapping_mode;
 	/* inline size in bytes */
--- a/drivers/staging/erofs/xattr.c
+++ b/drivers/staging/erofs/xattr.c
@@ -44,17 +44,24 @@ static inline void xattr_iter_end_final(
 
 static int init_inode_xattrs(struct inode *inode)
 {
+	struct erofs_vnode *const vi = EROFS_V(inode);
 	struct xattr_iter it;
 	unsigned i;
 	struct erofs_xattr_ibody_header *ih;
 	struct erofs_sb_info *sbi;
-	struct erofs_vnode *vi;
 	bool atomic_map;
+	int ret = 0;
 
-	if (likely(inode_has_inited_xattr(inode)))
+	/* the most case is that xattrs of this inode are initialized. */
+	if (test_bit(EROFS_V_EA_INITED_BIT, &vi->flags))
 		return 0;
 
-	vi = EROFS_V(inode);
+	if (wait_on_bit_lock(&vi->flags, EROFS_V_BL_XATTR_BIT, TASK_KILLABLE))
+		return -ERESTARTSYS;
+
+	/* someone has initialized xattrs for us? */
+	if (test_bit(EROFS_V_EA_INITED_BIT, &vi->flags))
+		goto out_unlock;
 
 	/*
 	 * bypass all xattr operations if ->xattr_isize is not greater than
@@ -67,13 +74,16 @@ static int init_inode_xattrs(struct inod
 	if (vi->xattr_isize == sizeof(struct erofs_xattr_ibody_header)) {
 		errln("xattr_isize %d of nid %llu is not supported yet",
 		      vi->xattr_isize, vi->nid);
-		return -ENOTSUPP;
+		ret = -ENOTSUPP;
+		goto out_unlock;
 	} else if (vi->xattr_isize < sizeof(struct erofs_xattr_ibody_header)) {
 		if (unlikely(vi->xattr_isize)) {
 			DBG_BUGON(1);
-			return -EIO;	/* xattr ondisk layout error */
+			ret = -EIO;
+			goto out_unlock;	/* xattr ondisk layout error */
 		}
-		return -ENOATTR;
+		ret = -ENOATTR;
+		goto out_unlock;
 	}
 
 	sbi = EROFS_I_SB(inode);
@@ -81,8 +91,10 @@ static int init_inode_xattrs(struct inod
 	it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize);
 
 	it.page = erofs_get_inline_page(inode, it.blkaddr);
-	if (IS_ERR(it.page))
-		return PTR_ERR(it.page);
+	if (IS_ERR(it.page)) {
+		ret = PTR_ERR(it.page);
+		goto out_unlock;
+	}
 
 	/* read in shared xattr array (non-atomic, see kmalloc below) */
 	it.kaddr = kmap(it.page);
@@ -95,7 +107,8 @@ static int init_inode_xattrs(struct inod
 						sizeof(uint), GFP_KERNEL);
 	if (!vi->xattr_shared_xattrs) {
 		xattr_iter_end(&it, atomic_map);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto out_unlock;
 	}
 
 	/* let's skip ibody header */
@@ -112,7 +125,8 @@ static int init_inode_xattrs(struct inod
 			if (IS_ERR(it.page)) {
 				kfree(vi->xattr_shared_xattrs);
 				vi->xattr_shared_xattrs = NULL;
-				return PTR_ERR(it.page);
+				ret = PTR_ERR(it.page);
+				goto out_unlock;
 			}
 
 			it.kaddr = kmap_atomic(it.page);
@@ -125,8 +139,11 @@ static int init_inode_xattrs(struct inod
 	}
 	xattr_iter_end(&it, atomic_map);
 
-	inode_set_inited_xattr(inode);
-	return 0;
+	set_bit(EROFS_V_EA_INITED_BIT, &vi->flags);
+
+out_unlock:
+	clear_and_wake_up_bit(EROFS_V_BL_XATTR_BIT, &vi->flags);
+	return ret;
 }
 
 struct xattr_iter_handlers {


Patches currently in stable-queue which might be from gaoxiang25 at huawei.com are

queue-4.19/staging-erofs-fix-fast-symlink-w-o-xattr-when-fs-xattr-is-on.patch
queue-4.19/staging-erofs-fix-race-of-initializing-xattrs-of-a-inode-at-the-same-time.patch
queue-4.19/staging-erofs-add-error-handling-for-xattr-submodule.patch
queue-4.19/staging-erofs-keep-corrupted-fs-from-crashing-kernel-in-erofs_namei.patch
queue-4.19/staging-erofs-fix-memleak-of-inode-s-shared-xattr-array.patch

  reply	other threads:[~2019-03-12 12:57 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-11  6:08 [PATCH 4.19 1/5] staging: erofs: add error handling for xattr submodule Gao Xiang
2019-03-11  6:08 ` [PATCH 4.19 2/5] staging: erofs: fix fast symlink w/o xattr when fs xattr is on Gao Xiang
2019-03-12 12:57   ` Patch "staging: erofs: fix fast symlink w/o xattr when fs xattr is on" has been added to the 4.19-stable tree gregkh
2019-03-11  6:08 ` [PATCH 4.19 3/5] staging: erofs: fix memleak of inode's shared xattr array Gao Xiang
2019-03-12 12:57   ` Patch "staging: erofs: fix memleak of inode's shared xattr array" has been added to the 4.19-stable tree gregkh
2019-03-11  6:08 ` [PATCH 4.19 4/5] staging: erofs: fix race of initializing xattrs of a inode at the same time Gao Xiang
2019-03-12 12:57   ` gregkh [this message]
2019-03-11  6:08 ` [PATCH 4.19 5/5] staging: erofs: keep corrupted fs from crashing kernel in erofs_namei() Gao Xiang
2019-03-12 12:57   ` Patch "staging: erofs: keep corrupted fs from crashing kernel in erofs_namei()" has been added to the 4.19-stable tree gregkh
2019-03-12 12:48 ` [PATCH 4.19 1/5] staging: erofs: add error handling for xattr submodule Greg Kroah-Hartman
2019-03-12 12:57 ` Patch "staging: erofs: add error handling for xattr submodule" has been added to the 4.19-stable tree gregkh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1552395456224210@kroah.com \
    --to=gregkh@linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox