xfs: fix missing check for invalid attr flags
BugLink: https://bugs.launchpad.net/bugs/2097575
commit f660ec8eaeb50d0317c29601aacabdb15e5f2203 upstream.
[backport: fix build errors in xchk_xattr_listent]
The xattr scrubber doesn't check for undefined flags in shortform attr
entries. Therefore, define a mask XFS_ATTR_ONDISK_MASK that has all
possible XFS_ATTR_* flags in it, and use that to check for unknown bits
in xchk_xattr_actor.
Refactor the check in the dabtree scanner function to use the new mask
as well. The redundant checks need to be in place because the dabtree
check examines the hash mappings and therefore needs to decode the attr
leaf entries to compute the namehash. This happens before the walk of
the xattr entries themselves.
Fixes: ae0506eba7 ("xfs: check used space of shortform xattr structures")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
Acked-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Manuel Diewald <manuel.diewald@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
This commit is contained in:
committed by
Stefan Bader
parent
d9d5d6fbf3
commit
ef2d31906b
@@ -708,8 +708,13 @@ struct xfs_attr3_leafblock {
|
||||
#define XFS_ATTR_ROOT (1u << XFS_ATTR_ROOT_BIT)
|
||||
#define XFS_ATTR_SECURE (1u << XFS_ATTR_SECURE_BIT)
|
||||
#define XFS_ATTR_INCOMPLETE (1u << XFS_ATTR_INCOMPLETE_BIT)
|
||||
|
||||
#define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE)
|
||||
|
||||
#define XFS_ATTR_ONDISK_MASK (XFS_ATTR_NSP_ONDISK_MASK | \
|
||||
XFS_ATTR_LOCAL | \
|
||||
XFS_ATTR_INCOMPLETE)
|
||||
|
||||
/*
|
||||
* Alignment for namelist and valuelist entries (since they are mixed
|
||||
* there can be only one alignment value)
|
||||
|
||||
+9
-4
@@ -182,6 +182,11 @@ xchk_xattr_listent(
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & ~XFS_ATTR_ONDISK_MASK) {
|
||||
xchk_fblock_set_corrupt(sx->sc, XFS_ATTR_FORK, args.blkno);
|
||||
goto fail_xref;
|
||||
}
|
||||
|
||||
if (flags & XFS_ATTR_INCOMPLETE) {
|
||||
/* Incomplete attr key, just mark the inode for preening. */
|
||||
xchk_ino_set_preen(sx->sc, context->dp->i_ino);
|
||||
@@ -463,7 +468,6 @@ xchk_xattr_rec(
|
||||
xfs_dahash_t hash;
|
||||
int nameidx;
|
||||
int hdrsize;
|
||||
unsigned int badflags;
|
||||
int error;
|
||||
|
||||
ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
|
||||
@@ -493,10 +497,11 @@ xchk_xattr_rec(
|
||||
|
||||
/* Retrieve the entry and check it. */
|
||||
hash = be32_to_cpu(ent->hashval);
|
||||
badflags = ~(XFS_ATTR_LOCAL | XFS_ATTR_ROOT | XFS_ATTR_SECURE |
|
||||
XFS_ATTR_INCOMPLETE);
|
||||
if ((ent->flags & badflags) != 0)
|
||||
if (ent->flags & ~XFS_ATTR_ONDISK_MASK) {
|
||||
xchk_da_set_corrupt(ds, level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ent->flags & XFS_ATTR_LOCAL) {
|
||||
lentry = (struct xfs_attr_leaf_name_local *)
|
||||
(((char *)bp->b_addr) + nameidx);
|
||||
|
||||
Reference in New Issue
Block a user