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

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
...@@ -67,7 +67,7 @@ int xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer, ...@@ -67,7 +67,7 @@ int xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer,
struct xfs_da_args *args); struct xfs_da_args *args);
int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer, int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer,
struct xfs_da_args *args); 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); struct xfs_attr_list_context *context);
/* /*
......
...@@ -49,14 +49,16 @@ xfs_attr_shortform_compare(const void *a, const void *b) ...@@ -49,14 +49,16 @@ xfs_attr_shortform_compare(const void *a, const void *b)
* we can begin returning them to the user. * we can begin returning them to the user.
*/ */
static int 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; struct attrlist_cursor_kern *cursor;
xfs_attr_sf_sort_t *sbuf, *sbp; struct xfs_attr_sf_sort *sbuf, *sbp;
xfs_attr_shortform_t *sf; struct xfs_attr_shortform *sf;
xfs_attr_sf_entry_t *sfe; struct xfs_attr_sf_entry *sfe;
xfs_inode_t *dp; struct xfs_inode *dp;
int sbsize, nsbuf, count, i; int sbsize, nsbuf, count, i;
int error = 0;
ASSERT(context != NULL); ASSERT(context != NULL);
dp = context->dp; dp = context->dp;
...@@ -84,6 +86,11 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -84,6 +86,11 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
(XFS_ISRESET_CURSOR(cursor) && (XFS_ISRESET_CURSOR(cursor) &&
(dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { 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, context->put_listent(context,
sfe->flags, sfe->flags,
sfe->nameval, sfe->nameval,
...@@ -161,10 +168,8 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -161,10 +168,8 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
break; break;
} }
} }
if (i == nsbuf) { if (i == nsbuf)
kmem_free(sbuf); goto out;
return 0;
}
/* /*
* Loop putting entries into the user buffer. * Loop putting entries into the user buffer.
...@@ -174,6 +179,12 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -174,6 +179,12 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
cursor->hashval = sbp->hash; cursor->hashval = sbp->hash;
cursor->offset = 0; 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, context->put_listent(context,
sbp->flags, sbp->flags,
sbp->name, sbp->name,
...@@ -183,9 +194,9 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -183,9 +194,9 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
break; break;
cursor->offset++; cursor->offset++;
} }
out:
kmem_free(sbuf); kmem_free(sbuf);
return 0; return error;
} }
/* /*
...@@ -284,7 +295,7 @@ xfs_attr_node_list( ...@@ -284,7 +295,7 @@ xfs_attr_node_list(
struct xfs_buf *bp; struct xfs_buf *bp;
struct xfs_inode *dp = context->dp; struct xfs_inode *dp = context->dp;
struct xfs_mount *mp = dp->i_mount; struct xfs_mount *mp = dp->i_mount;
int error; int error = 0;
trace_xfs_attr_node_list(context); trace_xfs_attr_node_list(context);
...@@ -358,7 +369,9 @@ xfs_attr_node_list( ...@@ -358,7 +369,9 @@ xfs_attr_node_list(
*/ */
for (;;) { for (;;) {
leaf = bp->b_addr; 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); xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
if (context->seen_enough || leafhdr.forw == 0) if (context->seen_enough || leafhdr.forw == 0)
break; break;
...@@ -369,13 +382,13 @@ xfs_attr_node_list( ...@@ -369,13 +382,13 @@ xfs_attr_node_list(
return error; return error;
} }
xfs_trans_brelse(context->tp, bp); xfs_trans_brelse(context->tp, bp);
return 0; return error;
} }
/* /*
* Copy out attribute list entries for attr_list(), for leaf attribute lists. * Copy out attribute list entries for attr_list(), for leaf attribute lists.
*/ */
void int
xfs_attr3_leaf_list_int( xfs_attr3_leaf_list_int(
struct xfs_buf *bp, struct xfs_buf *bp,
struct xfs_attr_list_context *context) struct xfs_attr_list_context *context)
...@@ -417,7 +430,7 @@ xfs_attr3_leaf_list_int( ...@@ -417,7 +430,7 @@ xfs_attr3_leaf_list_int(
} }
if (i == ichdr.count) { if (i == ichdr.count) {
trace_xfs_attr_list_notfound(context); trace_xfs_attr_list_notfound(context);
return; return 0;
} }
} else { } else {
entry = &entries[0]; entry = &entries[0];
...@@ -457,6 +470,11 @@ xfs_attr3_leaf_list_int( ...@@ -457,6 +470,11 @@ xfs_attr3_leaf_list_int(
valuelen = be32_to_cpu(name_rmt->valuelen); 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, context->put_listent(context, entry->flags,
name, namelen, valuelen); name, namelen, valuelen);
if (context->seen_enough) if (context->seen_enough)
...@@ -464,7 +482,7 @@ xfs_attr3_leaf_list_int( ...@@ -464,7 +482,7 @@ xfs_attr3_leaf_list_int(
cursor->offset++; cursor->offset++;
} }
trace_xfs_attr_list_leaf_end(context); trace_xfs_attr_list_leaf_end(context);
return; return 0;
} }
/* /*
...@@ -483,9 +501,9 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context) ...@@ -483,9 +501,9 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
if (error) if (error)
return error; return error;
xfs_attr3_leaf_list_int(bp, context); error = xfs_attr3_leaf_list_int(bp, context);
xfs_trans_brelse(context->tp, bp); xfs_trans_brelse(context->tp, bp);
return 0; return error;
} }
int int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment