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

xfs: namecheck attribute names before listing them



Actually call namecheck on attribute names before we hand them over to
userspace.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
parent c8476065
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ int xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer,
				 struct xfs_da_args *args);
int	xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer,
				    struct xfs_da_args *args);
void	xfs_attr3_leaf_list_int(struct xfs_buf *bp,
int	xfs_attr3_leaf_list_int(struct xfs_buf *bp,
				struct xfs_attr_list_context *context);

/*
+39 −21
Original line number Diff line number Diff line
@@ -49,14 +49,16 @@ xfs_attr_shortform_compare(const void *a, const void *b)
 * we can begin returning them to the user.
 */
static int
xfs_attr_shortform_list(xfs_attr_list_context_t *context)
xfs_attr_shortform_list(
	struct xfs_attr_list_context	*context)
{
	attrlist_cursor_kern_t *cursor;
	xfs_attr_sf_sort_t *sbuf, *sbp;
	xfs_attr_shortform_t *sf;
	xfs_attr_sf_entry_t *sfe;
	xfs_inode_t *dp;
	struct attrlist_cursor_kern	*cursor;
	struct xfs_attr_sf_sort		*sbuf, *sbp;
	struct xfs_attr_shortform	*sf;
	struct xfs_attr_sf_entry	*sfe;
	struct xfs_inode		*dp;
	int				sbsize, nsbuf, count, i;
	int				error = 0;

	ASSERT(context != NULL);
	dp = context->dp;
@@ -84,6 +86,11 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
	    (XFS_ISRESET_CURSOR(cursor) &&
	     (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
		for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
			if (!xfs_attr_namecheck(sfe->nameval, sfe->namelen)) {
				XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
						 context->dp->i_mount);
				return -EFSCORRUPTED;
			}
			context->put_listent(context,
					     sfe->flags,
					     sfe->nameval,
@@ -161,10 +168,8 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
			break;
		}
	}
	if (i == nsbuf) {
		kmem_free(sbuf);
		return 0;
	}
	if (i == nsbuf)
		goto out;

	/*
	 * Loop putting entries into the user buffer.
@@ -174,6 +179,12 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
			cursor->hashval = sbp->hash;
			cursor->offset = 0;
		}
		if (!xfs_attr_namecheck(sbp->name, sbp->namelen)) {
			XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
					 context->dp->i_mount);
			error = -EFSCORRUPTED;
			goto out;
		}
		context->put_listent(context,
				     sbp->flags,
				     sbp->name,
@@ -183,9 +194,9 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
			break;
		cursor->offset++;
	}

out:
	kmem_free(sbuf);
	return 0;
	return error;
}

/*
@@ -284,7 +295,7 @@ xfs_attr_node_list(
	struct xfs_buf			*bp;
	struct xfs_inode		*dp = context->dp;
	struct xfs_mount		*mp = dp->i_mount;
	int				error;
	int				error = 0;

	trace_xfs_attr_node_list(context);

@@ -358,7 +369,9 @@ xfs_attr_node_list(
	 */
	for (;;) {
		leaf = bp->b_addr;
		xfs_attr3_leaf_list_int(bp, context);
		error = xfs_attr3_leaf_list_int(bp, context);
		if (error)
			break;
		xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
		if (context->seen_enough || leafhdr.forw == 0)
			break;
@@ -369,13 +382,13 @@ xfs_attr_node_list(
			return error;
	}
	xfs_trans_brelse(context->tp, bp);
	return 0;
	return error;
}

/*
 * Copy out attribute list entries for attr_list(), for leaf attribute lists.
 */
void
int
xfs_attr3_leaf_list_int(
	struct xfs_buf			*bp,
	struct xfs_attr_list_context	*context)
@@ -417,7 +430,7 @@ xfs_attr3_leaf_list_int(
		}
		if (i == ichdr.count) {
			trace_xfs_attr_list_notfound(context);
			return;
			return 0;
		}
	} else {
		entry = &entries[0];
@@ -457,6 +470,11 @@ xfs_attr3_leaf_list_int(
			valuelen = be32_to_cpu(name_rmt->valuelen);
		}

		if (!xfs_attr_namecheck(name, namelen)) {
			XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
					 context->dp->i_mount);
			return -EFSCORRUPTED;
		}
		context->put_listent(context, entry->flags,
					      name, namelen, valuelen);
		if (context->seen_enough)
@@ -464,7 +482,7 @@ xfs_attr3_leaf_list_int(
		cursor->offset++;
	}
	trace_xfs_attr_list_leaf_end(context);
	return;
	return 0;
}

/*
@@ -483,9 +501,9 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
	if (error)
		return error;

	xfs_attr3_leaf_list_int(bp, context);
	error = xfs_attr3_leaf_list_int(bp, context);
	xfs_trans_brelse(context->tp, bp);
	return 0;
	return error;
}

int