* [PATCH] shmem: don't call put_super() when fill_super() failed.
@ 2018-05-14 6:57 Tetsuo Handa
2018-05-14 17:04 ` Eric Biggers
0 siblings, 1 reply; 9+ messages in thread
From: Tetsuo Handa @ 2018-05-14 6:57 UTC (permalink / raw)
To: syzbot+d2586fde8fdcead3647f, viro; +Cc: hughd, syzkaller-bugs, linux-mm
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] shmem: don't call put_super() when fill_super() failed.
2018-05-14 6:57 [PATCH] shmem: don't call put_super() when fill_super() failed Tetsuo Handa
@ 2018-05-14 17:04 ` Eric Biggers
2018-05-14 17:11 ` Eric Biggers
0 siblings, 1 reply; 9+ messages in thread
From: Eric Biggers @ 2018-05-14 17:04 UTC (permalink / raw)
To: Tetsuo Handa
Cc: syzbot+d2586fde8fdcead3647f, viro, hughd, syzkaller-bugs, linux-mm
Hi Tetsuo,
On Mon, May 14, 2018 at 03:57:31PM +0900, Tetsuo Handa wrote:
> From 193d9cb8b5dfc50c693d4bdd345cedb615bbf5ae Mon Sep 17 00:00:00 2001
> From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Date: Mon, 14 May 2018 15:25:13 +0900
> Subject: [PATCH] shmem: don't call put_super() when fill_super() failed.
>
> syzbot is reporting NULL pointer dereference at shmem_unused_huge_count()
> [1]. This is because shmem_fill_super() is calling shmem_put_super() which
> immediately releases memory before unregister_shrinker() is called by
> deactivate_locked_super() after fill_super() in mount_nodev() failed.
> Fix this by leaving the call to shmem_put_super() to
> generic_shutdown_super() from kill_anon_super() from kill_litter_super()
> from deactivate_locked_super().
>
> [1] https://syzkaller.appspot.com/bug?id=46e792849791f4abbac898880e8522054e032391
>
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Reported-by: syzbot <syzbot+d2586fde8fdcead3647f@syzkaller.appspotmail.com>
> Cc: Al Viro <viro@ZenIV.linux.org.uk>
> ---
> mm/shmem.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/mm/shmem.c b/mm/shmem.c
> index 9d6c7e5..18e134c 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -3843,7 +3843,6 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
> return 0;
>
> failed:
> - shmem_put_super(sb);
> return err;
> }
>
> --
> 1.8.3.1
I'm not following, since generic_shutdown_super() only calls ->put_super() if
->s_root is set, which only happens at the end of shmem_fill_super(). Isn't the
real problem that s_shrink is registered too early, causing super_cache_count()
and shmem_unused_huge_count() to potentially run before shmem_fill_super() has
completed? Or alternatively, the problem is that super_cache_count() doesn't
check for SB_ACTIVE.
Eric
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] shmem: don't call put_super() when fill_super() failed.
2018-05-14 17:04 ` Eric Biggers
@ 2018-05-14 17:11 ` Eric Biggers
2018-05-14 18:07 ` Al Viro
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Eric Biggers @ 2018-05-14 17:11 UTC (permalink / raw)
To: Tetsuo Handa
Cc: syzbot+d2586fde8fdcead3647f, viro, hughd, syzkaller-bugs,
linux-mm, Dave Chinner
On Mon, May 14, 2018 at 10:04:23AM -0700, Eric Biggers wrote:
> Hi Tetsuo,
>
> On Mon, May 14, 2018 at 03:57:31PM +0900, Tetsuo Handa wrote:
> > From 193d9cb8b5dfc50c693d4bdd345cedb615bbf5ae Mon Sep 17 00:00:00 2001
> > From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > Date: Mon, 14 May 2018 15:25:13 +0900
> > Subject: [PATCH] shmem: don't call put_super() when fill_super() failed.
> >
> > syzbot is reporting NULL pointer dereference at shmem_unused_huge_count()
> > [1]. This is because shmem_fill_super() is calling shmem_put_super() which
> > immediately releases memory before unregister_shrinker() is called by
> > deactivate_locked_super() after fill_super() in mount_nodev() failed.
> > Fix this by leaving the call to shmem_put_super() to
> > generic_shutdown_super() from kill_anon_super() from kill_litter_super()
> > from deactivate_locked_super().
> >
> > [1] https://syzkaller.appspot.com/bug?id=46e792849791f4abbac898880e8522054e032391
> >
> > Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > Reported-by: syzbot <syzbot+d2586fde8fdcead3647f@syzkaller.appspotmail.com>
> > Cc: Al Viro <viro@ZenIV.linux.org.uk>
> > ---
> > mm/shmem.c | 1 -
> > 1 file changed, 1 deletion(-)
> >
> > diff --git a/mm/shmem.c b/mm/shmem.c
> > index 9d6c7e5..18e134c 100644
> > --- a/mm/shmem.c
> > +++ b/mm/shmem.c
> > @@ -3843,7 +3843,6 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
> > return 0;
> >
> > failed:
> > - shmem_put_super(sb);
> > return err;
> > }
> >
> > --
> > 1.8.3.1
>
> I'm not following, since generic_shutdown_super() only calls ->put_super() if
> ->s_root is set, which only happens at the end of shmem_fill_super(). Isn't the
> real problem that s_shrink is registered too early, causing super_cache_count()
> and shmem_unused_huge_count() to potentially run before shmem_fill_super() has
> completed? Or alternatively, the problem is that super_cache_count() doesn't
> check for SB_ACTIVE.
>
Coincidentally, this is already going to be fixed by commit 79f546a696bff259
("fs: don't scan the inode cache before SB_BORN is set") in vfs/for-linus.
- Eric
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] shmem: don't call put_super() when fill_super() failed.
2018-05-14 17:11 ` Eric Biggers
@ 2018-05-14 18:07 ` Al Viro
2018-05-14 20:59 ` Tetsuo Handa
2018-05-15 0:27 ` Tetsuo Handa
2 siblings, 0 replies; 9+ messages in thread
From: Al Viro @ 2018-05-14 18:07 UTC (permalink / raw)
To: Eric Biggers
Cc: Tetsuo Handa, syzbot+d2586fde8fdcead3647f, hughd, syzkaller-bugs,
linux-mm, Dave Chinner
On Mon, May 14, 2018 at 10:11:54AM -0700, Eric Biggers wrote:
> > I'm not following, since generic_shutdown_super() only calls ->put_super() if
> > ->s_root is set, which only happens at the end of shmem_fill_super(). Isn't the
> > real problem that s_shrink is registered too early, causing super_cache_count()
> > and shmem_unused_huge_count() to potentially run before shmem_fill_super() has
> > completed? Or alternatively, the problem is that super_cache_count() doesn't
> > check for SB_ACTIVE.
> >
>
> Coincidentally, this is already going to be fixed by commit 79f546a696bff259
> ("fs: don't scan the inode cache before SB_BORN is set") in vfs/for-linus.
Exactly. While we are at it, we could add
static void shmem_kill_super(struct super_block *sb)
{
struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
kill_litter_super(sb);
if (sbinfo) {
percpu_counter_destroy(&sbinfo->used_blocks);
mpol_put(sbinfo->mpol);
kfree(sbinfo);
}
}
use that for ->kill_sb() and to hell with shmem_put_super() *and* its call in
cleanup path of shmem_fill_super() - these err = -E...; goto failed; in there
become simply return -E...;
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] shmem: don't call put_super() when fill_super() failed.
2018-05-14 17:11 ` Eric Biggers
2018-05-14 18:07 ` Al Viro
@ 2018-05-14 20:59 ` Tetsuo Handa
2018-05-15 0:27 ` Tetsuo Handa
2 siblings, 0 replies; 9+ messages in thread
From: Tetsuo Handa @ 2018-05-14 20:59 UTC (permalink / raw)
To: ebiggers3
Cc: syzbot+d2586fde8fdcead3647f, viro, hughd, syzkaller-bugs,
linux-mm, dchinner
Eric Biggers wrote:
> > I'm not following, since generic_shutdown_super() only calls ->put_super() if
> > ->s_root is set, which only happens at the end of shmem_fill_super(). Isn't the
> > real problem that s_shrink is registered too early, causing super_cache_count()
> > and shmem_unused_huge_count() to potentially run before shmem_fill_super() has
> > completed? Or alternatively, the problem is that super_cache_count() doesn't
> > check for SB_ACTIVE.
> >
>
> Coincidentally, this is already going to be fixed by commit 79f546a696bff259
> ("fs: don't scan the inode cache before SB_BORN is set") in vfs/for-linus.
Indeed. This is use before initialisation bug which will be fixed by commit 79f546a696bff259.
#syz fix: fs: don't scan the inode cache before SB_BORN is set
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] shmem: don't call put_super() when fill_super() failed.
2018-05-14 17:11 ` Eric Biggers
2018-05-14 18:07 ` Al Viro
2018-05-14 20:59 ` Tetsuo Handa
@ 2018-05-15 0:27 ` Tetsuo Handa
2018-05-15 0:39 ` Al Viro
2 siblings, 1 reply; 9+ messages in thread
From: Tetsuo Handa @ 2018-05-15 0:27 UTC (permalink / raw)
To: Eric Biggers
Cc: syzbot+d2586fde8fdcead3647f, viro, hughd, syzkaller-bugs,
linux-mm, Dave Chinner
Eric Biggers wrote:
> > I'm not following, since generic_shutdown_super() only calls ->put_super() if
> > ->s_root is set, which only happens at the end of shmem_fill_super(). Isn't the
> > real problem that s_shrink is registered too early, causing super_cache_count()
> > and shmem_unused_huge_count() to potentially run before shmem_fill_super() has
> > completed? Or alternatively, the problem is that super_cache_count() doesn't
> > check for SB_ACTIVE.
> >
>
> Coincidentally, this is already going to be fixed by commit 79f546a696bff259
> ("fs: don't scan the inode cache before SB_BORN is set") in vfs/for-linus.
>
Just an idea, but if shrinker registration is too early, can't we postpone it
like below?
--- a/fs/super.c
+++ b/fs/super.c
@@ -521,7 +521,6 @@ struct super_block *sget_userns(struct file_system_type *type,
hlist_add_head(&s->s_instances, &type->fs_supers);
spin_unlock(&sb_lock);
get_filesystem(type);
- register_shrinker_prepared(&s->s_shrink);
return s;
}
@@ -1287,6 +1286,7 @@ struct dentry *
WARN((sb->s_maxbytes < 0), "%s set sb->s_maxbytes to "
"negative value (%lld)\n", type->name, sb->s_maxbytes);
+ register_shrinker_prepared(&sb->s_shrink);
up_write(&sb->s_umount);
free_secdata(secdata);
return root;
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -313,6 +313,7 @@ int prealloc_shrinker(struct shrinker *shrinker)
shrinker->nr_deferred = kzalloc(size, GFP_KERNEL);
if (!shrinker->nr_deferred)
return -ENOMEM;
+ INIT_LIST_HEAD(&shrinker->list);
return 0;
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] shmem: don't call put_super() when fill_super() failed.
2018-05-15 0:27 ` Tetsuo Handa
@ 2018-05-15 0:39 ` Al Viro
2018-05-15 0:52 ` Tetsuo Handa
0 siblings, 1 reply; 9+ messages in thread
From: Al Viro @ 2018-05-15 0:39 UTC (permalink / raw)
To: Tetsuo Handa
Cc: Eric Biggers, syzbot+d2586fde8fdcead3647f, hughd, syzkaller-bugs,
linux-mm, Dave Chinner
On Tue, May 15, 2018 at 09:27:35AM +0900, Tetsuo Handa wrote:
> Eric Biggers wrote:
> > > I'm not following, since generic_shutdown_super() only calls ->put_super() if
> > > ->s_root is set, which only happens at the end of shmem_fill_super(). Isn't the
> > > real problem that s_shrink is registered too early, causing super_cache_count()
> > > and shmem_unused_huge_count() to potentially run before shmem_fill_super() has
> > > completed? Or alternatively, the problem is that super_cache_count() doesn't
> > > check for SB_ACTIVE.
> > >
> >
> > Coincidentally, this is already going to be fixed by commit 79f546a696bff259
> > ("fs: don't scan the inode cache before SB_BORN is set") in vfs/for-linus.
> >
>
> Just an idea, but if shrinker registration is too early, can't we postpone it
> like below?
Wonderful. And when ->mount() returns you a subtree of the same filesystem again,
that will do what, exactly?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] shmem: don't call put_super() when fill_super() failed.
2018-05-15 0:39 ` Al Viro
@ 2018-05-15 0:52 ` Tetsuo Handa
2018-05-15 1:13 ` Al Viro
0 siblings, 1 reply; 9+ messages in thread
From: Tetsuo Handa @ 2018-05-15 0:52 UTC (permalink / raw)
To: Al Viro
Cc: Eric Biggers, syzbot+d2586fde8fdcead3647f, hughd, syzkaller-bugs,
linux-mm, Dave Chinner
> On Tue, May 15, 2018 at 09:27:35AM +0900, Tetsuo Handa wrote:
> > Eric Biggers wrote:
> > > > I'm not following, since generic_shutdown_super() only calls ->put_super() if
> > > > ->s_root is set, which only happens at the end of shmem_fill_super(). Isn't the
> > > > real problem that s_shrink is registered too early, causing super_cache_count()
> > > > and shmem_unused_huge_count() to potentially run before shmem_fill_super() has
> > > > completed? Or alternatively, the problem is that super_cache_count() doesn't
> > > > check for SB_ACTIVE.
> > > >
> > >
> > > Coincidentally, this is already going to be fixed by commit 79f546a696bff259
> > > ("fs: don't scan the inode cache before SB_BORN is set") in vfs/for-linus.
> > >
> >
> > Just an idea, but if shrinker registration is too early, can't we postpone it
> > like below?
>
> Wonderful. And when ->mount() returns you a subtree of the same filesystem again,
> that will do what, exactly?
>
Can't we detect it via list_empty(&sb->s_shrink.list) test
before calling register_shrinker_prepared(&sb->s_shrink) ?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] shmem: don't call put_super() when fill_super() failed.
2018-05-15 0:52 ` Tetsuo Handa
@ 2018-05-15 1:13 ` Al Viro
0 siblings, 0 replies; 9+ messages in thread
From: Al Viro @ 2018-05-15 1:13 UTC (permalink / raw)
To: Tetsuo Handa
Cc: Eric Biggers, syzbot+d2586fde8fdcead3647f, hughd, syzkaller-bugs,
linux-mm, Dave Chinner
On Tue, May 15, 2018 at 09:52:37AM +0900, Tetsuo Handa wrote:
> > On Tue, May 15, 2018 at 09:27:35AM +0900, Tetsuo Handa wrote:
> > > Eric Biggers wrote:
> > > > > I'm not following, since generic_shutdown_super() only calls ->put_super() if
> > > > > ->s_root is set, which only happens at the end of shmem_fill_super(). Isn't the
> > > > > real problem that s_shrink is registered too early, causing super_cache_count()
> > > > > and shmem_unused_huge_count() to potentially run before shmem_fill_super() has
> > > > > completed? Or alternatively, the problem is that super_cache_count() doesn't
> > > > > check for SB_ACTIVE.
> > > > >
> > > >
> > > > Coincidentally, this is already going to be fixed by commit 79f546a696bff259
> > > > ("fs: don't scan the inode cache before SB_BORN is set") in vfs/for-linus.
> > > >
> > >
> > > Just an idea, but if shrinker registration is too early, can't we postpone it
> > > like below?
> >
> > Wonderful. And when ->mount() returns you a subtree of the same filesystem again,
> > that will do what, exactly?
> >
> Can't we detect it via list_empty(&sb->s_shrink.list) test
> before calling register_shrinker_prepared(&sb->s_shrink) ?
What for? Seriously, what's the benefit of doing that in such a convoluted way?
Avoiding a trivial check in super_cache_count()? The same check we normally
do in places where we are not holding an active reference to superblock and
want to make sure it's alive, at that...
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2018-05-15 1:14 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-14 6:57 [PATCH] shmem: don't call put_super() when fill_super() failed Tetsuo Handa
2018-05-14 17:04 ` Eric Biggers
2018-05-14 17:11 ` Eric Biggers
2018-05-14 18:07 ` Al Viro
2018-05-14 20:59 ` Tetsuo Handa
2018-05-15 0:27 ` Tetsuo Handa
2018-05-15 0:39 ` Al Viro
2018-05-15 0:52 ` Tetsuo Handa
2018-05-15 1:13 ` Al Viro
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.