Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b66ea43 authored by Dan Carpenter's avatar Dan Carpenter Committed by Greg Kroah-Hartman
Browse files

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: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 466fc15c
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -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);