All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: Christoph Hellwig <hch@lst.de>
Cc: Christian Brauner <brauner@kernel.org>,
	Heiko Carstens <hca@linux.ibm.com>,
	Vasily Gorbik <gor@linux.ibm.com>,
	Alexander Gordeev <agordeev@linux.ibm.com>,
	Fenghua Yu <fenghua.yu@intel.com>,
	Reinette Chatre <reinette.chatre@intel.com>,
	Miquel Raynal <miquel.raynal@bootlin.com>,
	Richard Weinberger <richard@nod.at>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>,
	Tejun Heo <tj@kernel.org>,
	Trond Myklebust <trond.myklebust@hammerspace.com>,
	Anna Schumaker <anna@kernel.org>,
	Kees Cook <keescook@chromium.org>,
	Damien Le Moal <dlemoal@kernel.org>,
	Naohiro Aota <naohiro.aota@wdc.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-s390@vger.kernel.org, linux-rdma@vger.kernel.org,
	linux-nfs@vger.kernel.org, linux-hardening@vger.kernel.org,
	cgroups@vger.kernel.org
Subject: Re: [PATCH 03/19] fs: release anon dev_t in deactivate_locked_super
Date: Mon, 9 Oct 2023 22:57:54 +0100	[thread overview]
Message-ID: <20231009215754.GL800259@ZenIV> (raw)
In-Reply-To: <20231002064646.GA1799@lst.de>

On Mon, Oct 02, 2023 at 08:46:46AM +0200, Christoph Hellwig wrote:
> On Tue, Sep 26, 2023 at 10:25:15PM +0100, Al Viro wrote:
> > Before your patch: foo_kill_super() calls kill_anon_super(),
> > which calls kill_super_notify(), which removes the sucker from
> > the list, then frees ->s_fs_info.  After your patch:
> > removal from the lists happens via the call of kill_super_notify()
> > *after* both of your methods had been called, while freeing
> > ->s_fs_info happens from the method call.  IOW, you've restored
> > the situation prior to "super: ensure valid info".  The whole
> > point of that commit had been to make sure that we have nothing
> > in the lists with ->s_fs_info pointing to a freed object.
> > 
> > It's not about free_anon_bdev(); that part is fine - it's the
> > "we can drop the weird second call site of kill_super_notify()"
> > thing that is broken.
> 
> The point has been to only release the anon dev_t after
> kill_super_notify, to prevent two of them beeing reused.
> 
> Which we do as the free_anon_bdev is done directly in
> deactivate_locked_super.  The new ->free_sb for non-block file systems
> frees resources, but none of them matter for sget.

We keep talking past each other...  Let me try again:
at the tip of your branch you have

static struct file_system_type ubifs_fs_type = {
        .name    = "ubifs",
	.owner   = THIS_MODULE,
	.mount   = ubifs_mount,
	.free_sb = ubifs_free_sb,
};

static void ubifs_free_sb(struct super_block *s)
{
        kfree(s->s_fs_info);
}

static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags,
                        const char *name, void *data)
{
	...
        sb = sget(fs_type, sb_test, sb_set, flags, c);
	...
}

static int sb_test(struct super_block *sb, void *data)
{
        struct ubifs_info *c1 = data;
        struct ubifs_info *c = sb->s_fs_info;

        return c->vi.cdev == c1->vi.cdev;
}

See the problem?  Mainline has

static void kill_ubifs_super(struct super_block *s)
{
        struct ubifs_info *c = s->s_fs_info;
        kill_anon_super(s);
        kfree(c);
}
and
void kill_anon_super(struct super_block *sb)
{
        dev_t dev = sb->s_dev;
        generic_shutdown_super(sb);
        kill_super_notify(sb);
        free_anon_bdev(dev);
}

That removes the superblock from the list of instances before its
->s_fs_info is freed.  In your branch removal happens here:

        if (fs->shutdown_sb)
                fs->shutdown_sb(s);
        generic_shutdown_super(s);
        if (fs->free_sb)
                fs->free_sb(s);

        kill_super_notify(s);

That comes *after* ubifs_free_sb() has freed ->s_fs_info.  And there's
nothing to stop ubifs_mount() (on a completely unrelated device) to get
called right at that moment.  Doing the sget() call quoted above.  Now,
in sget() we have
                hlist_for_each_entry(old, &type->fs_supers, s_instances) {
                        if (!test(old, data))
and that will hit sb_test(old, data), with old being a superblock still
in ->fs_supers, but with ->s_fs_info already freed.  So in sb_test()
we have c equal to old->s_fs_info and
        return c->vi.cdev == c1->vi.cdev;
is a bloody use after free.

Here we are unlikely to get fucked over - it's a plain fetch from freed
object.  If you look at e.g. nfs, you'll see a lot more than that -
pointer chasing from freed (and possibly reused) object.  The only
difference is that there you have sget_fc() instead of sget() - same
loop anyway.

The bottom line: in the form it is posted, your series reintroduces the
class of UAF that had been added by taking removal from the instances
list out of generic_shutdown_super() and then papered over by adding
that kill_super_notify() into kill_anon_super().

And frankly, I believe that the root cause is the insistence that
list removal should happen after generic_shutdown_super().  Sure, you
want the superblock to serve as bdev holder, which leads to fun
with -EBUSY if mount comes while umount still hadn't closed the
device.  I suspect that it would make a lot more sense to
introduce an intermediate state - "held, but will be released
in a short while".  You already have something similar, but
only for the entire disk ->bd_claiming stuff.

Add a new primitive (will_release_bdev()), so that attempts to
claim the sucker will wait until it gets released instead of
failing with -EBUSY.  And do *that* before generic_shutdown_super()
when unmounting something that is block-based.  Allows to bring
the list removal back where it used to be, no UAF at all...

IMO that direction is a lot more promising.

  reply	other threads:[~2023-10-09 21:58 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-13 11:09 split up ->kill_sb Christoph Hellwig
2023-09-13 11:09 ` Christoph Hellwig
2023-09-13 11:09 ` [PATCH 03/19] fs: release anon dev_t in deactivate_locked_super Christoph Hellwig
2023-09-13 11:09   ` Christoph Hellwig
     [not found]   ` <20230913111013.77623-4-hch-jcswGhMUV9g@public.gmane.org>
2023-09-13 23:27     ` Al Viro
2023-09-13 23:27       ` Al Viro
2023-09-14  2:37       ` Al Viro
2023-09-14  2:37         ` Al Viro
2023-09-14  5:38         ` Al Viro
2023-09-14  5:38           ` Al Viro
2023-09-14  7:56           ` Christian Brauner
2023-09-14  7:56             ` Christian Brauner
2023-09-26  9:31             ` Christoph Hellwig
2023-09-26  9:31               ` Christoph Hellwig
2023-09-14 14:02           ` Christian Brauner
2023-09-14 14:02             ` Christian Brauner
2023-09-14 16:58             ` Al Viro
2023-09-14 16:58               ` Al Viro
2023-09-14 19:23               ` Al Viro
2023-09-14 19:23                 ` Al Viro
2023-09-15  7:40                 ` Christian Brauner
2023-09-15  7:40                   ` Christian Brauner
2023-09-15  9:44               ` Christian Brauner
2023-09-15  9:44                 ` Christian Brauner
2023-09-15 14:12                 ` Christian Brauner
2023-09-15 14:12                   ` Christian Brauner
2023-09-15 14:28                   ` Al Viro
2023-09-15 14:28                     ` Al Viro
2023-09-15 14:33                     ` Al Viro
2023-09-15 14:33                       ` Al Viro
2023-09-15 14:40                     ` Christian Brauner
2023-09-15 14:40                       ` Christian Brauner
2023-09-26  9:41           ` Christoph Hellwig
2023-09-26  9:41             ` Christoph Hellwig
2023-09-26  9:38       ` Christoph Hellwig
2023-09-26  9:38         ` Christoph Hellwig
2023-09-26 21:25         ` Al Viro
2023-09-27 22:29           ` Al Viro
2023-10-02  6:46           ` Christoph Hellwig
2023-10-09 21:57             ` Al Viro [this message]
2023-10-10  8:44               ` Christian Brauner
2023-10-17 19:50                 ` Al Viro
     [not found] ` <20230913111013.77623-1-hch-jcswGhMUV9g@public.gmane.org>
2023-09-13 11:09   ` [PATCH 01/19] fs: reflow deactivate_locked_super Christoph Hellwig
2023-09-13 11:09     ` Christoph Hellwig
     [not found]     ` <20230913111013.77623-2-hch-jcswGhMUV9g@public.gmane.org>
2023-09-13 16:35       ` Christian Brauner
2023-09-13 16:35         ` Christian Brauner
2023-09-26  9:24         ` Christoph Hellwig
2023-09-26  9:24           ` Christoph Hellwig
2023-09-13 11:09   ` [PATCH 02/19] fs: make ->kill_sb optional Christoph Hellwig
2023-09-13 11:09     ` Christoph Hellwig
2023-09-13 11:09   ` [PATCH 04/19] NFS: remove the s_dev field from struct nfs_server Christoph Hellwig
2023-09-13 11:09     ` Christoph Hellwig
2023-09-13 11:09   ` [PATCH 05/19] fs: assign an anon dev_t in common code Christoph Hellwig
2023-09-13 11:09     ` Christoph Hellwig
     [not found]     ` <20230913111013.77623-6-hch-jcswGhMUV9g@public.gmane.org>
2023-09-14  0:34       ` Al Viro
2023-09-14  0:34         ` Al Viro
2023-09-13 11:10   ` [PATCH 06/19] qibfs: use simple_release_fs Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
     [not found]     ` <20230913111013.77623-7-hch-jcswGhMUV9g@public.gmane.org>
2023-09-18 11:41       ` Leon Romanovsky
2023-09-18 11:41         ` Leon Romanovsky
2023-09-13 11:10   ` [PATCH 07/19] hypfs: use d_genocide to kill fs entries Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
2023-09-13 11:10   ` [PATCH 08/19] pstore: shrink the pstore_sb_lock critical section in pstore_kill_sb Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
     [not found]     ` <20230913111013.77623-9-hch-jcswGhMUV9g@public.gmane.org>
2023-09-13 22:07       ` Kees Cook
2023-09-13 22:07         ` Kees Cook
2023-09-13 11:10   ` [PATCH 09/19] zonefs: remove duplicate cleanup in zonefs_fill_super Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
     [not found]     ` <20230913111013.77623-10-hch-jcswGhMUV9g@public.gmane.org>
2023-09-14  0:33       ` Damien Le Moal
2023-09-14  0:33         ` Damien Le Moal
2023-09-14  0:49       ` Al Viro
2023-09-14  0:49         ` Al Viro
2023-09-13 11:10   ` [PATCH 10/19] USB: gadget/legacy: remove sb_mutex Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
     [not found]     ` <20230913111013.77623-11-hch-jcswGhMUV9g@public.gmane.org>
2023-09-13 16:10       ` Alan Stern
2023-09-13 16:10         ` Alan Stern
     [not found]         ` <7f839be1-4898-41ad-8eda-10d5a0350bdf-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org>
2023-09-26  9:24           ` Christoph Hellwig
2023-09-26  9:24             ` Christoph Hellwig
2023-09-14 10:22     ` Sergey Shtylyov
2023-09-14 10:22       ` Sergey Shtylyov
2023-09-13 11:10   ` [PATCH 11/19] fs: add new shutdown_sb and free_sb methods Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
     [not found]     ` <20230913111013.77623-12-hch-jcswGhMUV9g@public.gmane.org>
2023-09-14  2:07       ` Al Viro
2023-09-14  2:07         ` Al Viro
2023-09-13 11:10   ` [PATCH 12/19] fs: convert kill_litter_super to litter_shutdown_sb Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
     [not found]     ` <20230913111013.77623-13-hch-jcswGhMUV9g@public.gmane.org>
2023-09-13 22:07       ` Kees Cook
2023-09-13 22:07         ` Kees Cook
2023-09-13 11:10   ` [PATCH 13/19] fs: convert kill_block_super to block_free_sb Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
     [not found]     ` <20230913111013.77623-14-hch-jcswGhMUV9g@public.gmane.org>
2023-09-14  2:29       ` Al Viro
2023-09-14  2:29         ` Al Viro
2023-09-13 11:10   ` [PATCH 14/19] jffs2: convert to ->shutdown_sb and ->free_sb Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
2023-09-13 11:10   ` [PATCH 15/19] kernfs: split ->kill_sb Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
     [not found]     ` <20230913111013.77623-16-hch-jcswGhMUV9g@public.gmane.org>
2023-09-18 15:24       ` Michal Koutný
2023-09-18 15:24         ` Michal Koutný
2023-09-13 11:10   ` [PATCH 16/19] x86/resctrl: release rdtgroup_mutex and the CPU hotplug lock in rdt_shutdown_sb Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
2023-09-13 11:10   ` [PATCH 17/19] NFS: move nfs_kill_super to fs_context.c Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
2023-09-13 11:10   ` [PATCH 18/19] fs: simple ->shutdown_sb and ->free_sb conversions Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig
2023-09-13 11:10   ` [PATCH 19/19] fs: remove ->kill_sb Christoph Hellwig
2023-09-13 11:10     ` Christoph Hellwig

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=20231009215754.GL800259@ZenIV \
    --to=viro@zeniv.linux.org.uk \
    --cc=agordeev@linux.ibm.com \
    --cc=anna@kernel.org \
    --cc=brauner@kernel.org \
    --cc=cgroups@vger.kernel.org \
    --cc=dennis.dalessandro@cornelisnetworks.com \
    --cc=dlemoal@kernel.org \
    --cc=fenghua.yu@intel.com \
    --cc=gor@linux.ibm.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hca@linux.ibm.com \
    --cc=hch@lst.de \
    --cc=keescook@chromium.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=miquel.raynal@bootlin.com \
    --cc=naohiro.aota@wdc.com \
    --cc=reinette.chatre@intel.com \
    --cc=richard@nod.at \
    --cc=tj@kernel.org \
    --cc=trond.myklebust@hammerspace.com \
    --cc=vigneshr@ti.com \
    /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.