mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 00:08:50 +00:00
dm ioctl: Simplify parameter buffer management code
Merge the two DM_PARAMS_[KV]MALLOC flags into a single flag. Doing so avoids the crashes seen with previous attempts to consolidate buffer management to use kvfree() without first flagging that memory had actually been allocated. Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
parent
350b539328
commit
028b39e314
@ -1670,8 +1670,7 @@ static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DM_PARAMS_KMALLOC 0x0001 /* Params alloced with kmalloc */
|
#define DM_PARAMS_MALLOC 0x0001 /* Params allocated with kvmalloc() */
|
||||||
#define DM_PARAMS_VMALLOC 0x0002 /* Params alloced with vmalloc */
|
|
||||||
#define DM_WIPE_BUFFER 0x0010 /* Wipe input buffer before returning from ioctl */
|
#define DM_WIPE_BUFFER 0x0010 /* Wipe input buffer before returning from ioctl */
|
||||||
|
|
||||||
static void free_params(struct dm_ioctl *param, size_t param_size, int param_flags)
|
static void free_params(struct dm_ioctl *param, size_t param_size, int param_flags)
|
||||||
@ -1679,10 +1678,8 @@ static void free_params(struct dm_ioctl *param, size_t param_size, int param_fla
|
|||||||
if (param_flags & DM_WIPE_BUFFER)
|
if (param_flags & DM_WIPE_BUFFER)
|
||||||
memset(param, 0, param_size);
|
memset(param, 0, param_size);
|
||||||
|
|
||||||
if (param_flags & DM_PARAMS_KMALLOC)
|
if (param_flags & DM_PARAMS_MALLOC)
|
||||||
kfree(param);
|
kvfree(param);
|
||||||
if (param_flags & DM_PARAMS_VMALLOC)
|
|
||||||
vfree(param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kernel,
|
static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kernel,
|
||||||
@ -1714,19 +1711,14 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
|
|||||||
* Use kmalloc() rather than vmalloc() when we can.
|
* Use kmalloc() rather than vmalloc() when we can.
|
||||||
*/
|
*/
|
||||||
dmi = NULL;
|
dmi = NULL;
|
||||||
if (param_kernel->data_size <= KMALLOC_MAX_SIZE) {
|
if (param_kernel->data_size <= KMALLOC_MAX_SIZE)
|
||||||
dmi = kmalloc(param_kernel->data_size, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
|
dmi = kmalloc(param_kernel->data_size, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
|
||||||
if (dmi)
|
|
||||||
*param_flags |= DM_PARAMS_KMALLOC;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dmi) {
|
if (!dmi) {
|
||||||
unsigned noio_flag;
|
unsigned noio_flag;
|
||||||
noio_flag = memalloc_noio_save();
|
noio_flag = memalloc_noio_save();
|
||||||
dmi = __vmalloc(param_kernel->data_size, GFP_NOIO | __GFP_HIGH | __GFP_HIGHMEM, PAGE_KERNEL);
|
dmi = __vmalloc(param_kernel->data_size, GFP_NOIO | __GFP_HIGH | __GFP_HIGHMEM, PAGE_KERNEL);
|
||||||
memalloc_noio_restore(noio_flag);
|
memalloc_noio_restore(noio_flag);
|
||||||
if (dmi)
|
|
||||||
*param_flags |= DM_PARAMS_VMALLOC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dmi) {
|
if (!dmi) {
|
||||||
@ -1735,6 +1727,8 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*param_flags |= DM_PARAMS_MALLOC;
|
||||||
|
|
||||||
if (copy_from_user(dmi, user, param_kernel->data_size))
|
if (copy_from_user(dmi, user, param_kernel->data_size))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user