Commit bb6cdd55 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: hide metadata inodes from everyone because they are special



Metadata inodes are private files and therefore cannot be exposed to
userspace.  This means no bulkstat, no open-by-handle, no linking them
into the directory tree, and no feeding them to LSMs.  As such, we mark
them S_PRIVATE, which stops all that.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 8651b410
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -844,6 +844,14 @@ xrep_is_tempfile(
	const struct xfs_inode	*ip)
{
	const struct inode	*inode = &ip->i_vnode;
	struct xfs_mount	*mp = ip->i_mount;

	/*
	 * Files in the metadata directory tree also have S_PRIVATE set and
	 * IOP_XATTR unset, so we must distinguish them separately.
	 */
	if (xfs_has_metadir(mp) && (ip->i_diflags2 & XFS_DIFLAG2_METADATA))
		return false;

	if (IS_PRIVATE(inode) && !(inode->i_opflags & IOP_XATTR))
		return true;
+14 −1
Original line number Diff line number Diff line
@@ -42,7 +42,9 @@
 * held. For regular files, the lock order is the other way around - the
 * mmap_lock is taken during the page fault, and then we lock the ilock to do
 * block mapping. Hence we need a different class for the directory ilock so
 * that lockdep can tell them apart.
 * that lockdep can tell them apart.  Directories in the metadata directory
 * tree get a separate class so that lockdep reports will warn us if someone
 * ever tries to lock regular directories after locking metadata directories.
 */
static struct lock_class_key xfs_nondir_ilock_class;
static struct lock_class_key xfs_dir_ilock_class;
@@ -1289,6 +1291,7 @@ xfs_setup_inode(
{
	struct inode		*inode = &ip->i_vnode;
	gfp_t			gfp_mask;
	bool			is_meta = xfs_is_internal_inode(ip);

	inode->i_ino = ip->i_ino;
	inode->i_state |= I_NEW;
@@ -1300,6 +1303,16 @@ xfs_setup_inode(
	i_size_write(inode, ip->i_disk_size);
	xfs_diflags_to_iflags(ip, true);

	/*
	 * Mark our metadata files as private so that LSMs and the ACL code
	 * don't try to add their own metadata or reason about these files,
	 * and users cannot ever obtain file handles to them.
	 */
	if (is_meta) {
		inode->i_flags |= S_PRIVATE;
		inode->i_opflags &= ~IOP_XATTR;
	}

	if (S_ISDIR(inode->i_mode)) {
		/*
		 * We set the i_rwsem class here to avoid potential races with