|
|
@@ -1720,8 +1720,7 @@ static void free_params(struct dm_ioctl *param, size_t param_size, int param_fla
|
|
|
}
|
|
|
|
|
|
static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kernel,
|
|
|
- int ioctl_flags,
|
|
|
- struct dm_ioctl **param, int *param_flags)
|
|
|
+ int ioctl_flags, struct dm_ioctl **param, int *param_flags)
|
|
|
{
|
|
|
struct dm_ioctl *dmi;
|
|
|
int secure_data;
|
|
|
@@ -1762,18 +1761,13 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
|
|
|
|
|
|
*param_flags |= DM_PARAMS_MALLOC;
|
|
|
|
|
|
- if (copy_from_user(dmi, user, param_kernel->data_size))
|
|
|
- goto bad;
|
|
|
+ /* Copy from param_kernel (which was already copied from user) */
|
|
|
+ memcpy(dmi, param_kernel, minimum_data_size);
|
|
|
|
|
|
-data_copied:
|
|
|
- /*
|
|
|
- * Abort if something changed the ioctl data while it was being copied.
|
|
|
- */
|
|
|
- if (dmi->data_size != param_kernel->data_size) {
|
|
|
- DMERR("rejecting ioctl: data size modified while processing parameters");
|
|
|
+ if (copy_from_user(&dmi->data, (char __user *)user + minimum_data_size,
|
|
|
+ param_kernel->data_size - minimum_data_size))
|
|
|
goto bad;
|
|
|
- }
|
|
|
-
|
|
|
+data_copied:
|
|
|
/* Wipe the user buffer so we do not return it to userspace */
|
|
|
if (secure_data && clear_user(user, param_kernel->data_size))
|
|
|
goto bad;
|