All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miklos Szeredi <miklos@szeredi.hu>
To: Erez Zadok <ezk@fsl.cs.sunysb.edu>
Cc: "viro\@ZenIV.linux.org.uk" <viro@ZenIV.linux.org.uk>,
	"linux-fsdevel\@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
	"linux-kernel\@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"akpm\@linux-foundation.org" <akpm@linux-foundation.org>,
	"apw\@canonical.com" <apw@canonical.com>,
	"nbd\@openwrt.org" <nbd@openwrt.org>,
	"neilb\@suse.de" <neilb@suse.de>,
	"hramrach\@centrum.cz" <hramrach@centrum.cz>,
	"jordipujolp\@gmail.com" <jordipujolp@gmail.com>
Subject: Re: [PATCH 5/7] overlay filesystem (inode.c bad error path)
Date: Fri, 20 May 2011 16:17:30 +0200	[thread overview]
Message-ID: <87mxihmp6t.fsf@tucsk.pomaz.szeredi.hu> (raw)
In-Reply-To: <87wrhlah1e.fsf@tucsk.pomaz.szeredi.hu> (Miklos Szeredi's message of "Fri, 20 May 2011 10:54:21 +0200")

Miklos Szeredi <miklos@szeredi.hu> writes:

> Erez Zadok <ezk@fsl.cs.sunysb.edu> writes:
>
>> I tried your overlayfs.v9 git repo w/ racer, using two separate ext3
>> filesystems (one for lowerdir and another for upperdir).  I got the
>> WARN_ON in ovl_permission to trigger within about 10 minutes of
>> testing.  Looking at the code, I see a problem in returning w/o
>> cleaning up an dput-ing the alias dentry.  Simple patch enclosed
>> below.
>
> Hmm, thanks.  The more interesting question is: why does that WARN_ON
> trigger?  I'll look into it.

I think I found the cause of all the bug and oopsen you are seeing.

Overlayfs expects upper and lower dentries to be always positive, it
never stores negative dentries there, there's no point, instead it
stores NULL.

There are basically two ways a positive dentry can become negative:

 A) dentry becomes unhashed with d_count == 0

 B) d_delete with d_count == 1

Case A is not possible in our case, since overlayfs keeps a ref on the
upper/lower dentries for the lifetime of the overlayfs dentry.

Case B is however possible, since no extra ref is taken before calling
vfs_unlink/vfs_rmdir.  So it looks like this is being triggered.

This is easy to solve, just grab a ref to upperdentry before
unlink/rmdir.  Equivalent is if we grab an extra reference from the
start.  The below patch does this.

With the patch I can't trigger the bugs anymore.

Erez, could you please also check if reverting your patches and applying
this one fixes all the bugs?

Thanks,
Miklos



commit 9192816148e2c6b1d610226b1fc1c04c36216370
Author: Miklos Szeredi <mszeredi@suse.cz>
Date:   Fri May 20 16:07:34 2011 +0200

    ovl: don't allow upperdentry to go negative
    
    Upperdentry can become negative if the file/directory is removed,
    since d_delete checks for d_count == 1 (we are the only user of this
    dentry) and changes it to negative in that case.
    
    However users of overlayfs expect upper and lower dentries to be
    either NULL or positive, and finding a negative dentry will trigger a
    WARNING or Oops.
    
    Fix this by keeping double reference on upperdentry which prevents
    d_delete() turning the dentry into negative.
    
    Reported-by: Erez Zadok <ezk@fsl.cs.sunysb.edu>
    Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>

diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index a9a09a6..c9db954 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -27,6 +27,10 @@ struct ovl_fs {
 };
 
 struct ovl_entry {
+	/*
+	 * Keep "double reference" on upper dentries, so that
+	 * d_delete() doesn't think it's OK to reset d_inode to NULL.
+	 */
 	struct dentry *__upperdentry;
 	struct dentry *lowerdentry;
 	union {
@@ -152,8 +156,9 @@ void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry)
 
 	WARN_ON(!mutex_is_locked(&upperdentry->d_parent->d_inode->i_mutex));
 	WARN_ON(oe->__upperdentry);
+	BUG_ON(!upperdentry->d_inode);
 	smp_wmb();
-	oe->__upperdentry = upperdentry;
+	oe->__upperdentry = dget(upperdentry);
 }
 
 void ovl_dentry_version_inc(struct dentry *dentry)
@@ -218,6 +223,7 @@ static void ovl_dentry_release(struct dentry *dentry)
 
 	if (oe) {
 		dput(oe->__upperdentry);
+		dput(oe->__upperdentry);
 		dput(oe->lowerdentry);
 		call_rcu(&oe->rcu, ovl_entry_free);
 	}
@@ -326,7 +332,7 @@ int ovl_do_lookup(struct dentry *dentry)
 	}
 
 	if (upperdentry)
-		oe->__upperdentry = upperdentry;
+		oe->__upperdentry = dget(upperdentry);
 
 	if (lowerdentry)
 		oe->lowerdentry = lowerdentry;
@@ -533,7 +539,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 	mntput(upperpath.mnt);
 	mntput(lowerpath.mnt);
 
-	oe->__upperdentry = upperpath.dentry;
+	oe->__upperdentry = dget(upperpath.dentry);
 	oe->lowerdentry = lowerpath.dentry;
 
 	root_dentry->d_fsdata = oe;

  reply	other threads:[~2011-05-20 14:17 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-17 12:30 [PATCH 0/7] overlay filesystem v9 Miklos Szeredi
2011-05-17 12:30 ` [PATCH 1/7] tmpfs: implement generic xattr support Miklos Szeredi
2011-05-17 12:30 ` [PATCH 2/7] vfs: add i_op->open() Miklos Szeredi
2011-05-17 12:30 ` [PATCH 3/7] vfs: export do_splice_direct() to modules Miklos Szeredi
2011-05-17 12:30 ` [PATCH 4/7] vfs: introduce clone_private_mount() Miklos Szeredi
2011-05-17 12:30 ` [PATCH 5/7] overlay filesystem Miklos Szeredi
2011-05-17 12:30 ` [PATCH 6/7] overlayfs: add statfs support Miklos Szeredi
2011-05-17 12:30 ` [PATCH 7/7] overlay: overlay filesystem documentation Miklos Szeredi
2011-05-17 15:13 ` [PATCH 0/7] overlay filesystem v9 Michal Suchanek
2011-05-19 16:37 ` Andy Whitcroft
2011-05-19 17:44   ` Miklos Szeredi
2011-05-19 18:05     ` Andy Whitcroft
2011-05-19 22:12       ` NeilBrown
2011-05-20  8:18         ` Miklos Szeredi
2011-05-20 12:43           ` Andy Whitcroft
2011-05-19 19:04     ` John Stoffel
2011-05-19 20:30       ` Andy Whitcroft
2011-05-19 20:34         ` John Stoffel
2011-05-19 18:04   ` Andy Whitcroft
2011-05-20  8:56   ` Michal Suchanek
     [not found] ` <103d3f78e2d3478d8bb93f5dda3a4a08@HUBCAS1.cs.stonybrook.edu>
2011-05-20  5:39   ` [PATCH 5/7] overlay filesystem (inode.c bad error path) Erez Zadok
2011-05-20  5:55     ` Erez Zadok
2011-05-20 14:25       ` Miklos Szeredi
     [not found]       ` <efad20cd4c664cd78e153b0fda2de605@HUBCAS2.cs.stonybrook.edu>
2011-05-21  5:15         ` Erez Zadok
2011-05-20  8:54     ` Miklos Szeredi
2011-05-20 14:17       ` Miklos Szeredi [this message]
     [not found]       ` <7dcd9c4e62864bc6aae66f5a4e3f3752@HUBCAS1.cs.stonybrook.edu>
2011-05-21  4:26         ` Erez Zadok
2011-05-21  4:26           ` Erez Zadok
2011-05-23  8:57           ` Miklos Szeredi
     [not found]           ` <b11ac28b818740a8b3f619e756735e41@HUBCAS2.cs.stonybrook.edu>
2011-05-24  1:02             ` Erez Zadok
2011-05-20  5:58   ` [PATCH 5/7] overlay filesystem (negative dentries cause OOPS on NULL inode) Erez Zadok

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=87mxihmp6t.fsf@tucsk.pomaz.szeredi.hu \
    --to=miklos@szeredi.hu \
    --cc=akpm@linux-foundation.org \
    --cc=apw@canonical.com \
    --cc=ezk@fsl.cs.sunysb.edu \
    --cc=hramrach@centrum.cz \
    --cc=jordipujolp@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nbd@openwrt.org \
    --cc=neilb@suse.de \
    --cc=viro@ZenIV.linux.org.uk \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.