From patchwork Thu Jun 1 17:01:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 9760547 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CEBD160363 for ; Thu, 1 Jun 2017 17:01:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A81C3284DA for ; Thu, 1 Jun 2017 17:01:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9CF96284F9; Thu, 1 Jun 2017 17:01:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 26490284DA for ; Thu, 1 Jun 2017 17:01:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751539AbdFARBq (ORCPT ); Thu, 1 Jun 2017 13:01:46 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:32991 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751485AbdFARBn (ORCPT ); Thu, 1 Jun 2017 13:01:43 -0400 Received: by mail-wm0-f67.google.com with SMTP id b84so12863960wmh.0; Thu, 01 Jun 2017 10:01:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pipsaUBCN1QQSn3DRmmU+r/pqtK9uhGHm0WyK7YGysU=; b=EiIK+bDKiud8lKJzHPCuTN6eiMOMQ4435Q00KgfxTn4FSOo/yVajBtBX0PPDFXGtt0 Ky5Aaru1ZpwdX5xOPFrhG21N0l7PQplYthabMktNnTGgSvx1Y1z04MmuJT5y7xUCECaE 5RB4S4g2TJuRRJ9qoSb/gqBGw/uj6oaLVunKu1ei0SE+xIFHHd9xIIfwK7r5Ntch4Xhi yasN2kZOMXJ6edGyXXJpx9pVpCSEYVTFu3d/DFGtFil1K7MKxgx19buscCjuaRRjQOei AIpeYNyHMMtBHX7NxLHsxy7NzpDUV//J7psYchVpmlC32FzG1D//ge6XRMjUrRlQquxs +PPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pipsaUBCN1QQSn3DRmmU+r/pqtK9uhGHm0WyK7YGysU=; b=U51KIRrWZKv0PLigxhCyVwE2aLd8H3i72P0MGSTFnB3OVKsMKeB6WCe1qa8MkGPT7z 4gnFUQqOliBorBWOeF7aVwEOHihcDvzX3X+XpfLoZ+1LodHQDki7+n+s+YAOSI8+Q6wG 77Mn7s3vU52p8pO2NGogcfBYe9/RgnFoQx0cqLvimMj7QXyukievfmEYbwbG9QzonJ5k My8vsLbyCcMFg5zbRb43cmp9x246lT/RiNRnRNlLRTN8Mqf1svGO5NyV/e+36G9/hT/E JuhfyBVULkhopwovEbAVWI5TpnrYr7fO1PROYVaxCqr/0JszscOrCqlTN7MDwFJtJssX w/Xg== X-Gm-Message-State: AODbwcAirbjtXs/qmpLTI+INctMq6jwJvP1bVieoWfukeXD0B48AmZGs MkcsXCqbAoT1WoWZ X-Received: by 10.28.236.77 with SMTP id k74mr97349wmh.91.1496336501641; Thu, 01 Jun 2017 10:01:41 -0700 (PDT) Received: from amir-VirtualBox.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id v45sm25964354wrb.68.2017.06.01.10.01.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 01 Jun 2017 10:01:41 -0700 (PDT) From: Amir Goldstein To: Miklos Szeredi Cc: Al Viro , linux-unionfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 2/5] ovl: get exclusive ownership on upper/work dirs Date: Thu, 1 Jun 2017 20:01:51 +0300 Message-Id: <1496336514-11000-3-git-send-email-amir73il@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1496336514-11000-1-git-send-email-amir73il@gmail.com> References: <1496336514-11000-1-git-send-email-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Bad things can happen if several concurrent overlay mounts try to use the same upperdir/workdir path. Try to get the 'inuse' advisory lock on upperdir and workdir. Fail mount if another overlay mount instance or another user holds the 'inuse' lock on these directories. Note that this provides no protection for concurrent overlay mount that use overlapping (i.e. descendant) upper/work dirs. Signed-off-by: Amir Goldstein --- fs/overlayfs/ovl_entry.h | 3 +++ fs/overlayfs/super.c | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index 34bc4a9f5c61..b0e7ee2ae398 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -21,6 +21,9 @@ struct ovl_fs { struct vfsmount *upper_mnt; unsigned numlower; struct vfsmount **lower_mnt; + /* workbasedir is the path at workdir= mount option */ + struct dentry *workbasedir; + /* workdir is the 'work' directory under workbasedir */ struct dentry *workdir; long namelen; /* pathnames of lower and upper dirs, for show_options */ diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 4882ffb37bae..476f021baf2a 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -165,12 +165,28 @@ static const struct dentry_operations ovl_reval_dentry_operations = { .d_weak_revalidate = ovl_dentry_weak_revalidate, }; +/* Get exclusive ownership on upper/work dir among overlay mounts */ +static bool ovl_dir_lock(struct dentry *dentry) +{ + return inode_inuse_trylock(d_inode(dentry)); +} + +static void ovl_dir_unlock(struct dentry *dentry) +{ + if (dentry) + inode_inuse_unlock(d_inode(dentry)); +} + static void ovl_put_super(struct super_block *sb) { struct ovl_fs *ufs = sb->s_fs_info; unsigned i; dput(ufs->workdir); + ovl_dir_unlock(ufs->workbasedir); + dput(ufs->workbasedir); + if (ufs->upper_mnt) + ovl_dir_unlock(ufs->upper_mnt->mnt_root); mntput(ufs->upper_mnt); for (i = 0; i < ufs->numlower; i++) mntput(ufs->lower_mnt[i]); @@ -788,9 +804,15 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) if (err) goto out_put_upperpath; + err = -EBUSY; + if (!ovl_dir_lock(upperpath.dentry)) { + pr_err("overlayfs: upperdir is in-use by another mount\n"); + goto out_put_upperpath; + } + err = ovl_mount_dir(ufs->config.workdir, &workpath); if (err) - goto out_put_upperpath; + goto out_unlock_upperdentry; err = -EINVAL; if (upperpath.mnt != workpath.mnt) { @@ -801,12 +823,20 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) pr_err("overlayfs: workdir and upperdir must be separate subtrees\n"); goto out_put_workpath; } + + err = -EBUSY; + if (!ovl_dir_lock(workpath.dentry)) { + pr_err("overlayfs: workdir is in-use by another mount\n"); + goto out_put_workpath; + } + + ufs->workbasedir = workpath.dentry; sb->s_stack_depth = upperpath.mnt->mnt_sb->s_stack_depth; } err = -ENOMEM; lowertmp = kstrdup(ufs->config.lowerdir, GFP_KERNEL); if (!lowertmp) - goto out_put_workpath; + goto out_unlock_workdentry; err = -EINVAL; stacklen = ovl_split_lowerdirs(lowertmp); @@ -849,6 +879,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) pr_err("overlayfs: failed to clone upperpath\n"); goto out_put_lowerpath; } + /* Don't inherit atime flags */ ufs->upper_mnt->mnt_flags &= ~(MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME); @@ -971,7 +1002,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) mntput(upperpath.mnt); for (i = 0; i < numlower; i++) mntput(stack[i].mnt); - path_put(&workpath); + mntput(workpath.mnt); kfree(lowertmp); if (upperpath.dentry) { @@ -1011,8 +1042,12 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) kfree(stack); out_free_lowertmp: kfree(lowertmp); +out_unlock_workdentry: + ovl_dir_unlock(workpath.dentry); out_put_workpath: path_put(&workpath); +out_unlock_upperdentry: + ovl_dir_unlock(upperpath.dentry); out_put_upperpath: path_put(&upperpath); out_free_config: