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:
Родитель
350b539328
Коммит
028b39e314
|
@ -1670,8 +1670,7 @@ static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
|
|||
return r;
|
||||
}
|
||||
|
||||
#define DM_PARAMS_KMALLOC 0x0001 /* Params alloced with kmalloc */
|
||||
#define DM_PARAMS_VMALLOC 0x0002 /* Params alloced with vmalloc */
|
||||
#define DM_PARAMS_MALLOC 0x0001 /* Params allocated with kvmalloc() */
|
||||
#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)
|
||||
|
@ -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)
|
||||
memset(param, 0, param_size);
|
||||
|
||||
if (param_flags & DM_PARAMS_KMALLOC)
|
||||
kfree(param);
|
||||
if (param_flags & DM_PARAMS_VMALLOC)
|
||||
vfree(param);
|
||||
if (param_flags & DM_PARAMS_MALLOC)
|
||||
kvfree(param);
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
if (dmi)
|
||||
*param_flags |= DM_PARAMS_KMALLOC;
|
||||
}
|
||||
|
||||
if (!dmi) {
|
||||
unsigned noio_flag;
|
||||
noio_flag = memalloc_noio_save();
|
||||
dmi = __vmalloc(param_kernel->data_size, GFP_NOIO | __GFP_HIGH | __GFP_HIGHMEM, PAGE_KERNEL);
|
||||
memalloc_noio_restore(noio_flag);
|
||||
if (dmi)
|
||||
*param_flags |= DM_PARAMS_VMALLOC;
|
||||
}
|
||||
|
||||
if (!dmi) {
|
||||
|
@ -1735,6 +1727,8 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*param_flags |= DM_PARAMS_MALLOC;
|
||||
|
||||
if (copy_from_user(dmi, user, param_kernel->data_size))
|
||||
goto bad;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче