aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
diff options
context:
space:
mode:
authorDan Carpenter <dan.carpenter@oracle.com>2014-12-22 10:52:39 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-01-17 15:46:22 -0800
commit3b66ea435234aab8fd8f389e929baedb556726c4 (patch)
treeacdaffe2b8d8f46d6ba11f62d25102de2cbe479d /drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
parentstaging: lustre: lustre: obdclass: lprocfs_status.c: Tidied up some code in a case statement (diff)
downloadlinux-dev-3b66ea435234aab8fd8f389e929baedb556726c4.tar.xz
linux-dev-3b66ea435234aab8fd8f389e929baedb556726c4.zip
Staging: lustre: error handling tweaks in obd_ioctl_getdata()
1) The places which called copy_from_user() were returning the number of bytes not copied instead of -EFAULT. 2) The user could trigger a memory leak if the condition "(hdr.ioc_len != data->ioc_len)" was true. Instead of adding a new call to OBD_FREE_LARGE(), I created a free_buf label and changed everything to use that label. Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/lustre/lustre/obdclass/linux/linux-module.c')
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-module.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
index b5007b8cbe34..b94aeac18a37 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
@@ -83,9 +83,8 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
int err;
int offset = 0;
- err = copy_from_user(&hdr, (void *)arg, sizeof(hdr));
- if (err)
- return err;
+ if (copy_from_user(&hdr, (void *)arg, sizeof(hdr)))
+ return -EFAULT;
if (hdr.ioc_version != OBD_IOCTL_VERSION) {
CERROR("Version mismatch kernel (%x) vs application (%x)\n",
@@ -117,18 +116,19 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
*len = hdr.ioc_len;
data = (struct obd_ioctl_data *)*buf;
- err = copy_from_user(*buf, (void *)arg, hdr.ioc_len);
- if (err) {
- OBD_FREE_LARGE(*buf, hdr.ioc_len);
- return err;
+ if (copy_from_user(*buf, (void *)arg, hdr.ioc_len)) {
+ err = -EFAULT;
+ goto free_buf;
+ }
+ if (hdr.ioc_len != data->ioc_len) {
+ err = -EINVAL;
+ goto free_buf;
}
- if (hdr.ioc_len != data->ioc_len)
- return -EINVAL;
if (obd_ioctl_is_invalid(data)) {
CERROR("ioctl not correctly formatted\n");
- OBD_FREE_LARGE(*buf, hdr.ioc_len);
- return -EINVAL;
+ err = -EINVAL;
+ goto free_buf;
}
if (data->ioc_inllen1) {
@@ -151,6 +151,10 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
}
return 0;
+
+free_buf:
+ OBD_FREE_LARGE(*buf, hdr.ioc_len);
+ return err;
}
EXPORT_SYMBOL(obd_ioctl_getdata);