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

xfs: create a separate hashname function for extended attributes



Create a separate function to compute name hashvalues for extended
attributes.  When we get to parent pointers we'll be altering the rules
so that metadump obfuscation doesn't turn heinous.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 9713dc88
Loading
Loading
Loading
Loading
+26 −2
Original line number Diff line number Diff line
@@ -280,7 +280,7 @@ xfs_attr_get(
		args->owner = args->dp->i_ino;
	args->geo = args->dp->i_mount->m_attr_geo;
	args->whichfork = XFS_ATTR_FORK;
	args->hashval = xfs_da_hashname(args->name, args->namelen);
	xfs_attr_sethash(args);

	/* Entirely possible to look up a name which doesn't exist */
	args->op_flags = XFS_DA_OP_OKNOENT;
@@ -415,6 +415,30 @@ xfs_attr_sf_addname(
	return error;
}

/* Compute the hash value for a user/root/secure extended attribute */
xfs_dahash_t
xfs_attr_hashname(
	const uint8_t		*name,
	int			namelen)
{
	return xfs_da_hashname(name, namelen);
}

/* Compute the hash value for any extended attribute from any namespace. */
xfs_dahash_t
xfs_attr_hashval(
	struct xfs_mount	*mp,
	unsigned int		attr_flags,
	const uint8_t		*name,
	int			namelen,
	const void		*value,
	int			valuelen)
{
	ASSERT(xfs_attr_check_namespace(attr_flags));

	return xfs_attr_hashname(name, namelen);
}

/*
 * Handle the state change on completion of a multi-state attr operation.
 *
@@ -925,7 +949,7 @@ xfs_attr_set(
		args->owner = args->dp->i_ino;
	args->geo = mp->m_attr_geo;
	args->whichfork = XFS_ATTR_FORK;
	args->hashval = xfs_da_hashname(args->name, args->namelen);
	xfs_attr_sethash(args);

	/*
	 * We have no control over the attribute names that userspace passes us
+14 −0
Original line number Diff line number Diff line
@@ -628,6 +628,20 @@ xfs_attr_init_replace_state(struct xfs_da_args *args)
	return xfs_attr_init_add_state(args);
}

xfs_dahash_t xfs_attr_hashname(const uint8_t *name, int namelen);

xfs_dahash_t xfs_attr_hashval(struct xfs_mount *mp, unsigned int attr_flags,
		const uint8_t *name, int namelen, const void *value,
		int valuelen);

/* Set the hash value for any extended attribute from any namespace. */
static inline void xfs_attr_sethash(struct xfs_da_args *args)
{
	args->hashval = xfs_attr_hashval(args->dp->i_mount, args->attr_filter,
					 args->name, args->namelen,
					 args->value, args->valuelen);
}

extern struct kmem_cache *xfs_attr_intent_cache;
int __init xfs_attr_intent_init_cache(void);
void xfs_attr_intent_destroy_cache(void);
+1 −2
Original line number Diff line number Diff line
@@ -948,14 +948,13 @@ xfs_attr_shortform_to_leaf(
		nargs.namelen = sfe->namelen;
		nargs.value = &sfe->nameval[nargs.namelen];
		nargs.valuelen = sfe->valuelen;
		nargs.hashval = xfs_da_hashname(sfe->nameval,
						sfe->namelen);
		nargs.attr_filter = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK;
		if (!xfs_attr_check_namespace(sfe->flags)) {
			xfs_da_mark_sick(args);
			error = -EFSCORRUPTED;
			goto out;
		}
		xfs_attr_sethash(&nargs);
		error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
		ASSERT(error == -ENOATTR);
		error = xfs_attr3_leaf_add(bp, &nargs);
+8 −3
Original line number Diff line number Diff line
@@ -179,7 +179,6 @@ xchk_xattr_actor(
		.dp			= ip,
		.name			= name,
		.namelen		= namelen,
		.hashval		= xfs_da_hashname(name, namelen),
		.trans			= sc->tp,
		.valuelen		= valuelen,
		.owner			= ip->i_ino,
@@ -230,6 +229,7 @@ xchk_xattr_actor(

	args.value = ab->value;

	xfs_attr_sethash(&args);
	error = xfs_attr_get_ilocked(&args);
	/* ENODATA means the hash lookup failed and the attr is bad */
	if (error == -ENODATA)
@@ -525,7 +525,10 @@ xchk_xattr_rec(
			xchk_da_set_corrupt(ds, level);
			goto out;
		}
		calc_hash = xfs_da_hashname(lentry->nameval, lentry->namelen);
		calc_hash = xfs_attr_hashval(mp, ent->flags, lentry->nameval,
					     lentry->namelen,
					     lentry->nameval + lentry->namelen,
					     be16_to_cpu(lentry->valuelen));
	} else {
		rentry = (struct xfs_attr_leaf_name_remote *)
				(((char *)bp->b_addr) + nameidx);
@@ -533,7 +536,9 @@ xchk_xattr_rec(
			xchk_da_set_corrupt(ds, level);
			goto out;
		}
		calc_hash = xfs_da_hashname(rentry->name, rentry->namelen);
		calc_hash = xfs_attr_hashval(mp, ent->flags, rentry->name,
					     rentry->namelen, NULL,
					     be32_to_cpu(rentry->valuelen));
	}
	if (calc_hash != hash)
		xchk_da_set_corrupt(ds, level);
+1 −1
Original line number Diff line number Diff line
@@ -582,13 +582,13 @@ xfs_attri_recover_work(
	args->whichfork = XFS_ATTR_FORK;
	args->name = nv->name.i_addr;
	args->namelen = nv->name.i_len;
	args->hashval = xfs_da_hashname(args->name, args->namelen);
	args->value = nv->value.i_addr;
	args->valuelen = nv->value.i_len;
	args->attr_filter = attrp->alfi_attr_filter & XFS_ATTRI_FILTER_MASK;
	args->op_flags = XFS_DA_OP_RECOVERY | XFS_DA_OP_OKNOENT |
			 XFS_DA_OP_LOGGED;
	args->owner = args->dp->i_ino;
	xfs_attr_sethash(args);

	switch (xfs_attr_intent_op(attr)) {
	case XFS_ATTRI_OP_FLAGS_SET:
Loading