From patchwork Fri Jul 31 01:12:03 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsheng Yang X-Patchwork-Id: 502381 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D4602140328 for ; Fri, 31 Jul 2015 11:34:16 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZKzAx-0002w8-5t; Fri, 31 Jul 2015 01:31:55 +0000 Received: from [59.151.112.132] (helo=heian.cn.fujitsu.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZKyxW-0003KD-Hr for linux-mtd@lists.infradead.org; Fri, 31 Jul 2015 01:18:03 +0000 X-IronPort-AV: E=Sophos;i="5.15,520,1432569600"; d="scan'208";a="99099492" Received: from unknown (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 31 Jul 2015 09:21:14 +0800 Received: from G08CNEXCHPEKD02.g08.fujitsu.local (localhost.localdomain [127.0.0.1]) by edo.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id t6V1FnMM007766; Fri, 31 Jul 2015 09:15:49 +0800 Received: from yds-PC.g08.fujitsu.local (10.167.226.66) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.181.6; Fri, 31 Jul 2015 09:17:40 +0800 From: Dongsheng Yang To: , Subject: [PATCH v2] ubifs: make ubifs_[get|set]xattr atomic Date: Fri, 31 Jul 2015 09:12:03 +0800 Message-ID: <1438305123-31675-1-git-send-email-yangds.fnst@cn.fujitsu.com> X-Mailer: git-send-email 1.8.4.2 In-Reply-To: <55BABB80.9080406@cn.fujitsu.com> References: <55BABB80.9080406@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.226.66] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150730_181802_744848_A7C7E2E7 X-CRM114-Status: UNSURE ( 8.15 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -1.1 (-) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-1.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.8 RDNS_NONE Delivered to internal network by a host with no rDNS X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dongsheng Yang , linux-mtd@lists.infradead.org Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This commit make the ubifs_[get|set]xattr protected by ui_mutex. Originally, there is a possibility that ubifs_getxattr to get a wrong value. P1 P2 ---------- ---------- ubifs_getxattr ubifs_setxattr - kfree() - memcpy() - kmemdup() Then ubifs_getxattr() would get a non-sense data. To solve this problem, this commit make the xattr of ubifs_inode updated in atomic. Signed-off-by: Dongsheng Yang --- -v2: Add more description in commit message fs/ubifs/xattr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index 96f3448..dec1afd 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c @@ -208,6 +208,7 @@ static int change_xattr(struct ubifs_info *c, struct inode *host, if (err) return err; + mutex_lock(&ui->ui_mutex); kfree(ui->data); ui->data = kmemdup(value, size, GFP_NOFS); if (!ui->data) { @@ -216,6 +217,7 @@ static int change_xattr(struct ubifs_info *c, struct inode *host, } inode->i_size = ui->ui_size = size; ui->data_len = size; + mutex_unlock(&ui->ui_mutex); mutex_lock(&host_ui->ui_mutex); host->i_ctime = ubifs_current_time(host); @@ -409,6 +411,7 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, ubifs_assert(inode->i_size == ui->data_len); ubifs_assert(ubifs_inode(host)->xattr_size > ui->data_len); + mutex_lock(&ui->ui_mutex); if (buf) { /* If @buf is %NULL we are supposed to return the length */ if (ui->data_len > size) { @@ -423,6 +426,7 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, err = ui->data_len; out_iput: + mutex_unlock(&ui->ui_mutex); iput(inode); out_unlock: kfree(xent);