Linux Security Modules development
 help / color / mirror / Atom feed
From: James Bottomley <James.Bottomley@HansenPartnership.com>
To: Christian Brauner <brauner@kernel.org>
Cc: "Ard Biesheuvel" <ardb@kernel.org>,
	"Al Viro" <viro@zeniv.linux.org.uk>,
	"Ryan Lee" <ryan.lee@canonical.com>,
	"Malte Schröder" <malte.schroeder@tnxip.de>,
	linux-security-module@vger.kernel.org,
	apparmor <apparmor@lists.ubuntu.com>,
	linux-efi@vger.kernel.org,
	"John Johansen" <john.johansen@canonical.com>,
	"jk@ozlabs.org" <jk@ozlabs.org>,
	linux-fsdevel@vger.kernel.org
Subject: Re: apparmor NULL pointer dereference on resume [efivarfs]
Date: Tue, 11 Mar 2025 12:20:05 -0400	[thread overview]
Message-ID: <78a59e2a5012bfb2d6a653782ab346b44b211102.camel@HansenPartnership.com> (raw)
In-Reply-To: <20250311-trunk-farben-fe36bebe233a@brauner>

On Tue, 2025-03-11 at 16:55 +0100, Christian Brauner wrote:
> On Tue, Mar 11, 2025 at 09:01:36AM -0400, James Bottomley wrote:
> > On Tue, 2025-03-11 at 09:45 +0100, Christian Brauner wrote:
[...]
> > > efivars as written only has a single global superblock and it
> > > doesn't support idmapped mounts and I don't see why it ever
> > > would.
> > 
> > So that's not quite true: efivarfs currently supports uid and gid
> > mapping as mount options, which certainly looks like they were
> > designed to allow a second mount in a user directory.  I've no idea
> > what the actual use case for this is, but if I go for a single
> > superblock, any reconfigure with new uid/gid would become globally
> > effective (change every current mount) because they're stored in
> > the superblock information.
> > 
> > So what is the use case for this uid/gid parameter?  If no-one can
> > remember and no-one actually uses it, perhaps the whole config path
> > can be simplified by getting rid of the options?  Even if there is
> > a use case, if it's single mount only then we can still go with a
> > global superblock.
> 
> So efivarfs uses get_tree_single(). That means that only a single
> superblock of the filesystem type efivarfs can ever exist on the
> system.
> 
> If efivars is mounted multiple times it will be the exact same
> superblock that's used. IOW, mounting efivars multiple times is akin
> to a bind-mount. It would be a bit ugly but it could be done by
> making sure that any uid/gid changes are reflected. But see below.

OK, so it's a fair bet that either the uid/gid option is never used or
only used once globally.

> > > But since efivars does only ever have a single global superblock,
> > > one possibility is to an internal superblock that always exits
> > > and is resurfaced whenever userspace mounts efivarfs. That's
> > > essentially the devtmpfs model.
> > > 
> > > Then you can stash:
> > > 
> > > static struct vfsmount *efivarfs_mnt;
> > > 
> > > globally and use that in efivarfs_pm_notify() to fill in struct
> > > path.
> > 
> > I didn't see devtmpfs when looking for examples, since it's hiding
> > outside of the fs/ directory.  However, it does seem to be a bit
> > legacy nasty as an example to copy.  However, I get the basics:
> > we'd instantiate the mnt and superblock on init (stashing mnt in
> > the sfi so the notifier gets it).  Then we can do the variable
> > population on reconfigure, just in case an EFI system doesn't want
> > to mount efivarfs to save memory.
> > 
> > I can code that up if I can get an answer to the uid/gid parameter
> > question above.
> 
> I have some questions. efivarfs registers efivarfs_pm_notify even
> before a superblock exists in efivarfs_init_fs_context(). That's
> called during
> fd_context = fsopen("efivarfs") before a superblock even exists:
> 
> (1) Is it guaranteed that efivarfs_pm_notify() is only called once a
>     superblock exists?

Yes (there was a fix that ensured it)

> 
> (2) Is it guaranteed that efivarfs_pm_notify() is only called when  
> and while a mount for the superblock exists?

That's the intention, but I thought the last unmount would trigger the
superblock kill.  However, I was thinking I'd need a new mechanism
based on reconfiguration to do the dentries only if the filesystem got
mounted, so I think I can cope with that.

> If the question to either one of those is "no" then the global
> vfsmount hack will not help.
> 
> From reading efivarfs_pm_notify() it looks like the answer to (1) is
> "yes" because you're dereferencing sfi->sb->s_root in
> efivarfs_pm_notify().
> 
> But I'm not at all certain that (2) isn't a "no" and that
> efivarfs_pm_notify() can be called before a mount exists. IOW, once
> fsconfig(FSCONFIG_CMD_CREATE) is called the notifier seems ready and
> registered but userspace isn't forced to call fsmount(fd_fs) at all.

I'd like to have efivarfs so that if no-one's actually mounted anything
then the reflection of the variables isn't taking up any space, so I
was planning a new mechanism for that anyway.

> They could just not to do it for whatever reason but the notifier
> should already be able to run.
> 
> Another question is whether the superblock can be freed while
> efivarfs_pm_notify() is running? I think that can't happen because
> blocking_notifier_chain_unregister(&efivar_ops_nh, &sfi->nb) will
> block in efivarfs_kill_sb() until all outstanding calls to
> efivarfs_pm_notify() are finished?

That's the way it's supposed to work, yes.  However, if we move to an
always persistent superblock and mnt, I was thinking there'd have to be
an indicator in the sfi about whether the variables were reflected or
not.

Regards,

James

> If (2) isn't guranteed then efivarfs_pm_notify() needs to be
> rewritten without relying on files because there's no guarantee that
> a mount exists at all.
> 


  parent reply	other threads:[~2025-03-11 16:20 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-05 19:04 apparmor NULL pointer dereference on resume Malte Schröder
2025-03-05 19:22 ` Ryan Lee
2025-03-05 21:47   ` Malte Schröder
2025-03-10 19:57     ` Ryan Lee
2025-03-10 21:49       ` apparmor NULL pointer dereference on resume [efivarfs] James Bottomley
2025-03-11  7:16         ` Ard Biesheuvel
2025-03-11  8:45           ` Christian Brauner
2025-03-11 13:01             ` James Bottomley
2025-03-11 15:55               ` Christian Brauner
2025-03-11 16:19                 ` Christian Brauner
2025-03-11 16:20                 ` James Bottomley [this message]
2025-03-11 17:15                   ` Al Viro
2025-03-11 17:46                     ` James Bottomley
2025-03-14 14:59               ` [RFC 1/1] fix NULL mnt [was Re: apparmor NULL pointer dereference on resume [efivarfs]] James Bottomley
2025-03-15 10:04                 ` Christian Brauner
2025-03-15 18:41                   ` James Bottomley
2025-03-16  6:46                     ` Christian Brauner
2025-03-16 14:26                       ` James Bottomley
2025-03-16 19:19                         ` Ard Biesheuvel
2025-03-17  8:56                         ` Christian Brauner

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=78a59e2a5012bfb2d6a653782ab346b44b211102.camel@HansenPartnership.com \
    --to=james.bottomley@hansenpartnership.com \
    --cc=apparmor@lists.ubuntu.com \
    --cc=ardb@kernel.org \
    --cc=brauner@kernel.org \
    --cc=jk@ozlabs.org \
    --cc=john.johansen@canonical.com \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=malte.schroeder@tnxip.de \
    --cc=ryan.lee@canonical.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox