xfs: lift cursor copy in/out into xfs_ioc_attr_list
Lift the common code to copy the cursor from and to user space into xfs_ioc_attr_list. Note that this means we copy in twice now as the cursor is in the middle of the conaining structure, but we never touch the memory for the original copy. Doing so keeps the cursor handling isolated in the common helper. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
parent
eb241c7474
commit
53ac39fdb3
@ -355,9 +355,10 @@ xfs_ioc_attr_list(
|
|||||||
void __user *ubuf,
|
void __user *ubuf,
|
||||||
int bufsize,
|
int bufsize,
|
||||||
int flags,
|
int flags,
|
||||||
struct attrlist_cursor_kern *cursor)
|
struct xfs_attrlist_cursor __user *ucursor)
|
||||||
{
|
{
|
||||||
struct xfs_attr_list_context context;
|
struct xfs_attr_list_context context;
|
||||||
|
struct attrlist_cursor_kern cursor;
|
||||||
struct xfs_attrlist *alist;
|
struct xfs_attrlist *alist;
|
||||||
void *buffer;
|
void *buffer;
|
||||||
int error;
|
int error;
|
||||||
@ -377,10 +378,12 @@ xfs_ioc_attr_list(
|
|||||||
/*
|
/*
|
||||||
* Validate the cursor.
|
* Validate the cursor.
|
||||||
*/
|
*/
|
||||||
if (cursor->pad1 || cursor->pad2)
|
if (copy_from_user(&cursor, ucursor, sizeof(cursor)))
|
||||||
|
return -EFAULT;
|
||||||
|
if (cursor.pad1 || cursor.pad2)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if ((cursor->initted == 0) &&
|
if ((cursor.initted == 0) &&
|
||||||
(cursor->hashval || cursor->blkno || cursor->offset))
|
(cursor.hashval || cursor.blkno || cursor.offset))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
buffer = kmem_zalloc_large(bufsize, 0);
|
buffer = kmem_zalloc_large(bufsize, 0);
|
||||||
@ -392,7 +395,7 @@ xfs_ioc_attr_list(
|
|||||||
*/
|
*/
|
||||||
memset(&context, 0, sizeof(context));
|
memset(&context, 0, sizeof(context));
|
||||||
context.dp = dp;
|
context.dp = dp;
|
||||||
context.cursor = cursor;
|
context.cursor = &cursor;
|
||||||
context.resynch = 1;
|
context.resynch = 1;
|
||||||
context.flags = flags;
|
context.flags = flags;
|
||||||
context.buffer = buffer;
|
context.buffer = buffer;
|
||||||
@ -409,7 +412,8 @@ xfs_ioc_attr_list(
|
|||||||
if (error)
|
if (error)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
if (copy_to_user(ubuf, buffer, bufsize))
|
if (copy_to_user(ubuf, buffer, bufsize) ||
|
||||||
|
copy_to_user(ucursor, &cursor, sizeof(cursor)))
|
||||||
error = -EFAULT;
|
error = -EFAULT;
|
||||||
out_free:
|
out_free:
|
||||||
kmem_free(buffer);
|
kmem_free(buffer);
|
||||||
@ -419,33 +423,23 @@ out_free:
|
|||||||
STATIC int
|
STATIC int
|
||||||
xfs_attrlist_by_handle(
|
xfs_attrlist_by_handle(
|
||||||
struct file *parfilp,
|
struct file *parfilp,
|
||||||
void __user *arg)
|
struct xfs_fsop_attrlist_handlereq __user *p)
|
||||||
{
|
{
|
||||||
int error = -ENOMEM;
|
struct xfs_fsop_attrlist_handlereq al_hreq;
|
||||||
attrlist_cursor_kern_t *cursor;
|
|
||||||
struct xfs_fsop_attrlist_handlereq __user *p = arg;
|
|
||||||
xfs_fsop_attrlist_handlereq_t al_hreq;
|
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
int error = -ENOMEM;
|
||||||
|
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
|
if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
|
dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
|
||||||
if (IS_ERR(dentry))
|
if (IS_ERR(dentry))
|
||||||
return PTR_ERR(dentry);
|
return PTR_ERR(dentry);
|
||||||
|
|
||||||
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
|
|
||||||
error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
|
error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
|
||||||
al_hreq.buflen, al_hreq.flags, cursor);
|
al_hreq.buflen, al_hreq.flags, &p->pos);
|
||||||
if (error)
|
|
||||||
goto out_dput;
|
|
||||||
|
|
||||||
if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t)))
|
|
||||||
error = -EFAULT;
|
|
||||||
|
|
||||||
out_dput:
|
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ int xfs_ioc_attrmulti_one(struct file *parfilp, struct inode *inode,
|
|||||||
uint32_t opcode, void __user *uname, void __user *value,
|
uint32_t opcode, void __user *uname, void __user *value,
|
||||||
uint32_t *len, uint32_t flags);
|
uint32_t *len, uint32_t flags);
|
||||||
int xfs_ioc_attr_list(struct xfs_inode *dp, void __user *ubuf, int bufsize,
|
int xfs_ioc_attr_list(struct xfs_inode *dp, void __user *ubuf, int bufsize,
|
||||||
int flags, struct attrlist_cursor_kern *cursor);
|
int flags, struct xfs_attrlist_cursor __user *ucursor);
|
||||||
|
|
||||||
extern struct dentry *
|
extern struct dentry *
|
||||||
xfs_handle_to_dentry(
|
xfs_handle_to_dentry(
|
||||||
|
@ -352,35 +352,24 @@ xfs_compat_handlereq_to_dentry(
|
|||||||
STATIC int
|
STATIC int
|
||||||
xfs_compat_attrlist_by_handle(
|
xfs_compat_attrlist_by_handle(
|
||||||
struct file *parfilp,
|
struct file *parfilp,
|
||||||
void __user *arg)
|
compat_xfs_fsop_attrlist_handlereq_t __user *p)
|
||||||
{
|
{
|
||||||
int error;
|
|
||||||
attrlist_cursor_kern_t *cursor;
|
|
||||||
compat_xfs_fsop_attrlist_handlereq_t __user *p = arg;
|
|
||||||
compat_xfs_fsop_attrlist_handlereq_t al_hreq;
|
compat_xfs_fsop_attrlist_handlereq_t al_hreq;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
int error;
|
||||||
|
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&al_hreq, arg,
|
if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
|
||||||
sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq);
|
dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq);
|
||||||
if (IS_ERR(dentry))
|
if (IS_ERR(dentry))
|
||||||
return PTR_ERR(dentry);
|
return PTR_ERR(dentry);
|
||||||
|
|
||||||
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
|
|
||||||
error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)),
|
error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)),
|
||||||
compat_ptr(al_hreq.buffer), al_hreq.buflen,
|
compat_ptr(al_hreq.buffer), al_hreq.buflen,
|
||||||
al_hreq.flags, cursor);
|
al_hreq.flags, &p->pos);
|
||||||
if (error)
|
|
||||||
goto out_dput;
|
|
||||||
|
|
||||||
if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t)))
|
|
||||||
error = -EFAULT;
|
|
||||||
|
|
||||||
out_dput:
|
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user