Re: [PATCH] overlayfs: Trigger file re-evaluation by IMA / EVM after writes

Dave Chinner
2023-05-21T22:50:00Z

On Sat, May 20, 2023 at 11:17:35AM +0200, Christian Brauner wrote:
> On Fri, May 19, 2023 at 03:42:38PM -0400, Mimi Zohar wrote:
> > On Fri, 2023-04-07 at 10:31 +0200, Christian Brauner wrote:
> > > So, I think we want both; we want the ovl_copyattr() and the
> > > vfs_getattr_nosec() change:
> > >
> > > (1) overlayfs should copy up the inode version in ovl_copyattr(). That
> > > is in line what we do with all other inode attributes. IOW, the
> > > overlayfs inode's i_version counter should aim to mirror the
> > > relevant layer's i_version counter. I wouldn't know why that
> > > shouldn't be the case. Asking the other way around there doesn't
> > > seem to be any use for overlayfs inodes to have an i_version that
> > > isn't just mirroring the relevant layer's i_version.
> > > (2) Jeff's changes for ima to make it rely on vfs_getattr_nosec().
> > > Currently, ima assumes that it will get the correct i_version from
> > > an inode but that just doesn't hold for stacking filesystem.
> > >
> > > While (1) would likely just fix the immediate bug (2) is correct and
> > > _robust_. If we change how attributes are handled vfs_*() helpers will
> > > get updated and ima with it. Poking at raw inodes without using
> > > appropriate helpers is much more likely to get ima into trouble.
> >
> > In addition to properly setting the i_version for IMA, EVM has a
> > similar issue with i_generation and s_uuid. Adding them to
> > ovl_copyattr() seems to resolve it. Does that make sense?
> >
> > diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
> > index 923d66d131c1..cd0aeb828868 100644
> > --- a/fs/overlayfs/util.c
> > +++ b/fs/overlayfs/util.c
> > @@ -1118,5 +1118,8 @@ void ovl_copyattr(struct inode *inode)
> > inode->i_atime = realinode->i_atime;
> > inode->i_mtime = realinode->i_mtime;
> > inode->i_ctime = realinode->i_ctime;
> > + inode->i_generation = realinode->i_generation;
> > + if (inode->i_sb)
> > + uuid_copy(&inode->i_sb->s_uuid, &realinode->i_sb-
>
> Overlayfs can consist of multiple lower layers and each of those lower
> layers may have a different uuid. So everytime you trigger a
> ovl_copyattr() on a different layer this patch would alter the uuid of
> the overlayfs superblock.
>
> In addition the uuid should be set when the filesystem is mounted.
> Unless the filesystem implements a dedicated ioctl() - like ext4 - to
> change the uuid.

IMO, that ext4 functionality is a landmine waiting to be stepped on.

We should not be changing the sb->s_uuid of filesysetms dynamically.
The VFS does not guarantee in any way that it is safe to change the
sb->s_uuid (i.e. no locking, no change notifications, no udev
events, etc). Various subsystems - both in the kernel and in
userspace - use the sb->s_uuid as a canonical and/or persistent
filesystem/device identifier and are unprepared to have it change
while the filesystem is mounted and active.

I commented on this from an XFS perspective here when it was
proposed to copy this ext4 mis-feature in XFS:

https://lore.kernel.org/linux-xfs/20230314062847.GQ360264@dread.disaster.area/

Further to this, I also suspect that changing uuids online will
cause issues with userspace caching of fs uuids (e.g. libblkid and
anything that uses it) and information that uses uuids to identify
the filesystem that are set up at mount time (/dev/disk/by-uuid/
links, etc) by kernel events sent to userspace helpers...

IMO, we shouldn't even be considering dynamic sb->s_uuid changes
without first working through the full system impacts of having
persistent userspace-visible filesystem identifiers change
dynamically...

-Dave.
--
Dave Chinner
david@fromorbit.com