xfs: salvage parent pointers when rebuilding xattr structures

When we're salvaging extended attributes, make sure we validate the ones
that claim to be parent pointers before adding them to the salvage pile.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Darrick J. Wong 2024-04-22 09:48:08 -07:00
parent bf61c36a45
commit 086e934fe9
2 changed files with 65 additions and 9 deletions

View File

@ -28,6 +28,7 @@
#include "xfs_exchmaps.h"
#include "xfs_exchrange.h"
#include "xfs_acl.h"
#include "xfs_parent.h"
#include "scrub/xfs_scrub.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
@ -127,6 +128,9 @@ xrep_xattr_want_salvage(
return false;
if (valuelen > XATTR_SIZE_MAX || valuelen < 0)
return false;
if (attr_flags & XFS_ATTR_PARENT)
return xfs_parent_valuecheck(rx->sc->mp, value, valuelen);
return true;
}
@ -154,14 +158,21 @@ xrep_xattr_salvage_key(
* Truncate the name to the first character that would trip namecheck.
* If we no longer have a name after that, ignore this attribute.
*/
while (i < namelen && name[i] != 0)
i++;
if (i == 0)
return 0;
key.namelen = i;
if (flags & XFS_ATTR_PARENT) {
key.namelen = namelen;
trace_xrep_xattr_salvage_rec(rx->sc->ip, flags, name, key.namelen,
valuelen);
trace_xrep_xattr_salvage_pptr(rx->sc->ip, flags, name,
key.namelen, value, valuelen);
} else {
while (i < namelen && name[i] != 0)
i++;
if (i == 0)
return 0;
key.namelen = i;
trace_xrep_xattr_salvage_rec(rx->sc->ip, flags, name,
key.namelen, valuelen);
}
error = xfblob_store(rx->xattr_blobs, &key.name_cookie, name,
key.namelen);
@ -598,8 +609,15 @@ xrep_xattr_insert_rec(
ab->name[key->namelen] = 0;
trace_xrep_xattr_insert_rec(rx->sc->tempip, key->flags, ab->name,
key->namelen, key->valuelen);
if (key->flags & XFS_ATTR_PARENT) {
trace_xrep_xattr_insert_pptr(rx->sc->tempip, key->flags,
ab->name, key->namelen, ab->value,
key->valuelen);
args.op_flags |= XFS_DA_OP_LOGGED;
} else {
trace_xrep_xattr_insert_rec(rx->sc->tempip, key->flags,
ab->name, key->namelen, key->valuelen);
}
/*
* xfs_attr_set creates and commits its own transaction. If the attr

View File

@ -2540,6 +2540,44 @@ DEFINE_EVENT(xrep_xattr_salvage_class, name, \
DEFINE_XREP_XATTR_SALVAGE_EVENT(xrep_xattr_salvage_rec);
DEFINE_XREP_XATTR_SALVAGE_EVENT(xrep_xattr_insert_rec);
DECLARE_EVENT_CLASS(xrep_pptr_salvage_class,
TP_PROTO(struct xfs_inode *ip, unsigned int flags, const void *name,
unsigned int namelen, const void *value, unsigned int valuelen),
TP_ARGS(ip, flags, name, namelen, value, valuelen),
TP_STRUCT__entry(
__field(dev_t, dev)
__field(xfs_ino_t, ino)
__field(xfs_ino_t, parent_ino)
__field(unsigned int, parent_gen)
__field(unsigned int, namelen)
__dynamic_array(char, name, namelen)
),
TP_fast_assign(
const struct xfs_parent_rec *rec = value;
__entry->dev = ip->i_mount->m_super->s_dev;
__entry->ino = ip->i_ino;
__entry->parent_ino = be64_to_cpu(rec->p_ino);
__entry->parent_gen = be32_to_cpu(rec->p_gen);
__entry->namelen = namelen;
memcpy(__get_str(name), name, namelen);
),
TP_printk("dev %d:%d ino 0x%llx parent_ino 0x%llx parent_gen 0x%x name '%.*s'",
MAJOR(__entry->dev), MINOR(__entry->dev),
__entry->ino,
__entry->parent_ino,
__entry->parent_gen,
__entry->namelen,
__get_str(name))
)
#define DEFINE_XREP_PPTR_SALVAGE_EVENT(name) \
DEFINE_EVENT(xrep_pptr_salvage_class, name, \
TP_PROTO(struct xfs_inode *ip, unsigned int flags, const void *name, \
unsigned int namelen, const void *value, unsigned int valuelen), \
TP_ARGS(ip, flags, name, namelen, value, valuelen))
DEFINE_XREP_PPTR_SALVAGE_EVENT(xrep_xattr_salvage_pptr);
DEFINE_XREP_PPTR_SALVAGE_EVENT(xrep_xattr_insert_pptr);
TRACE_EVENT(xrep_xattr_class,
TP_PROTO(struct xfs_inode *ip, struct xfs_inode *arg_ip),
TP_ARGS(ip, arg_ip),