summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ioctl32.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2020-02-26 17:30:31 -0800
committerDarrick J. Wong <darrick.wong@oracle.com>2020-03-02 20:55:52 -0800
commit2282a9e65177b425aaab4d8228f98f5c09fc778a (patch)
treeb78179d9a41eecbe80df4ad0aeff7e136da23be5 /fs/xfs/xfs_ioctl32.c
parent6cc4f4fff10d38e95994e740f1b1d260c6fe8506 (diff)
downloadlinux-2282a9e65177b425aaab4d8228f98f5c09fc778a.tar.gz
linux-2282a9e65177b425aaab4d8228f98f5c09fc778a.tar.bz2
linux-2282a9e65177b425aaab4d8228f98f5c09fc778a.zip
xfs: use strndup_user in XFS_IOC_ATTRMULTI_BY_HANDLE
Simplify the user copy code by using strndup_user. This means that we now do one memory allocation per operation instead of one per ioctl, but memory allocations are cheap compared to the actual file system operations. Also the error for an invalid path is now EINVAL or EFAULT instead of the previous odd and undocumented ERANGE. 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>
Diffstat (limited to 'fs/xfs/xfs_ioctl32.c')
-rw-r--r--fs/xfs/xfs_ioctl32.c17
1 files changed, 5 insertions, 12 deletions
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index e085f304e539..936c2f62fb6c 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -445,11 +445,6 @@ xfs_compat_attrmulti_by_handle(
goto out_dput;
}
- error = -ENOMEM;
- attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
- if (!attr_name)
- goto out_kfree_ops;
-
error = 0;
for (i = 0; i < am_hreq.opcount; i++) {
if ((ops[i].am_flags & ATTR_ROOT) &&
@@ -459,13 +454,12 @@ xfs_compat_attrmulti_by_handle(
}
ops[i].am_flags &= ~ATTR_KERNEL_FLAGS;
- ops[i].am_error = strncpy_from_user((char *)attr_name,
- compat_ptr(ops[i].am_attrname),
+ attr_name = strndup_user(compat_ptr(ops[i].am_attrname),
MAXNAMELEN);
- if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
- error = -ERANGE;
- if (ops[i].am_error < 0)
+ if (IS_ERR(attr_name)) {
+ ops[i].am_error = PTR_ERR(attr_name);
break;
+ }
switch (ops[i].am_opcode) {
case ATTR_OP_GET:
@@ -496,13 +490,12 @@ xfs_compat_attrmulti_by_handle(
default:
ops[i].am_error = -EINVAL;
}
+ kfree(attr_name);
}
if (copy_to_user(compat_ptr(am_hreq.ops), ops, size))
error = -EFAULT;
- kfree(attr_name);
- out_kfree_ops:
kfree(ops);
out_dput:
dput(dentry);