ALSA: control_compat: Don't dynamically allocate single-use structs

All of these dynamically-allocated structs can be simply placed on the
stack, eliminating the overhead of dynamic memory allocation entirely.

Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
This commit is contained in:
Sultan Alsawaf 2021-02-04 21:54:02 -08:00 committed by spakkkk
parent 7781d6b3bd
commit 21ef075aef

View File

@ -94,55 +94,52 @@ struct snd_ctl_elem_info32 {
static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
struct snd_ctl_elem_info32 __user *data32)
{
struct snd_ctl_elem_info *data;
struct snd_ctl_elem_info data;
int err;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (! data)
return -ENOMEM;
memset(&data, 0, sizeof(data));
err = -EFAULT;
/* copy id */
if (copy_from_user(&data->id, &data32->id, sizeof(data->id)))
if (copy_from_user(&data.id, &data32->id, sizeof(data.id)))
goto error;
/* we need to copy the item index.
* hope this doesn't break anything..
*/
if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
if (get_user(data.value.enumerated.item, &data32->value.enumerated.item))
goto error;
err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
if (err < 0)
goto error;
err = snd_ctl_elem_info(ctl, data);
err = snd_ctl_elem_info(ctl, &data);
if (err < 0)
goto error;
/* restore info to 32bit */
err = -EFAULT;
/* id, type, access, count */
if (copy_to_user(&data32->id, &data->id, sizeof(data->id)) ||
copy_to_user(&data32->type, &data->type, 3 * sizeof(u32)))
if (copy_to_user(&data32->id, &data.id, sizeof(data.id)) ||
copy_to_user(&data32->type, &data.type, 3 * sizeof(u32)))
goto error;
if (put_user(data->owner, &data32->owner))
if (put_user(data.owner, &data32->owner))
goto error;
switch (data->type) {
switch (data.type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER:
if (put_user(data->value.integer.min, &data32->value.integer.min) ||
put_user(data->value.integer.max, &data32->value.integer.max) ||
put_user(data->value.integer.step, &data32->value.integer.step))
if (put_user(data.value.integer.min, &data32->value.integer.min) ||
put_user(data.value.integer.max, &data32->value.integer.max) ||
put_user(data.value.integer.step, &data32->value.integer.step))
goto error;
break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64:
if (copy_to_user(&data32->value.integer64,
&data->value.integer64,
sizeof(data->value.integer64)))
&data.value.integer64,
sizeof(data.value.integer64)))
goto error;
break;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
if (copy_to_user(&data32->value.enumerated,
&data->value.enumerated,
sizeof(data->value.enumerated)))
&data.value.enumerated,
sizeof(data.value.enumerated)))
goto error;
break;
default:
@ -150,7 +147,6 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
}
err = 0;
error:
kfree(data);
return err;
}
@ -187,7 +183,7 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
int *countp)
{
struct snd_kcontrol *kctl;
struct snd_ctl_elem_info *info;
struct snd_ctl_elem_info info;
int err;
down_read(&card->controls_rwsem);
@ -196,19 +192,13 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
up_read(&card->controls_rwsem);
return -ENOENT;
}
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (info == NULL) {
up_read(&card->controls_rwsem);
return -ENOMEM;
}
info->id = *id;
err = kctl->info(kctl, info);
info = (typeof(info)){ .id = *id };
err = kctl->info(kctl, &info);
up_read(&card->controls_rwsem);
if (err >= 0) {
err = info->type;
*countp = info->count;
err = info.type;
*countp = info.count;
}
kfree(info);
return err;
}
@ -304,14 +294,11 @@ static int copy_ctl_value_to_user(void __user *userdata,
static int ctl_elem_read_user(struct snd_card *card,
void __user *userdata, void __user *valuep)
{
struct snd_ctl_elem_value *data;
struct snd_ctl_elem_value data;
int err, type, count;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
err = copy_ctl_value_from_user(card, data, userdata, valuep,
memset(&data, 0, sizeof(data));
err = copy_ctl_value_from_user(card, &data, userdata, valuep,
&type, &count);
if (err < 0)
goto error;
@ -319,27 +306,23 @@ static int ctl_elem_read_user(struct snd_card *card,
err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
if (err < 0)
goto error;
err = snd_ctl_elem_read(card, data);
err = snd_ctl_elem_read(card, &data);
if (err < 0)
goto error;
err = copy_ctl_value_to_user(userdata, valuep, data, type, count);
err = copy_ctl_value_to_user(userdata, valuep, &data, type, count);
error:
kfree(data);
return err;
}
static int ctl_elem_write_user(struct snd_ctl_file *file,
void __user *userdata, void __user *valuep)
{
struct snd_ctl_elem_value *data;
struct snd_ctl_elem_value data;
struct snd_card *card = file->card;
int err, type, count;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
err = copy_ctl_value_from_user(card, data, userdata, valuep,
memset(&data, 0, sizeof(data));
err = copy_ctl_value_from_user(card, &data, userdata, valuep,
&type, &count);
if (err < 0)
goto error;
@ -347,12 +330,11 @@ static int ctl_elem_write_user(struct snd_ctl_file *file,
err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
if (err < 0)
goto error;
err = snd_ctl_elem_write(card, file, data);
err = snd_ctl_elem_write(card, file, &data);
if (err < 0)
goto error;
err = copy_ctl_value_to_user(userdata, valuep, data, type, count);
err = copy_ctl_value_to_user(userdata, valuep, &data, type, count);
error:
kfree(data);
return err;
}
@ -387,48 +369,44 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
struct snd_ctl_elem_info32 __user *data32,
int replace)
{
struct snd_ctl_elem_info *data;
struct snd_ctl_elem_info data;
int err;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (! data)
return -ENOMEM;
memset(&data, 0, sizeof(data));
err = -EFAULT;
/* id, type, access, count */ \
if (copy_from_user(&data->id, &data32->id, sizeof(data->id)) ||
copy_from_user(&data->type, &data32->type, 3 * sizeof(u32)))
if (copy_from_user(&data.id, &data32->id, sizeof(data.id)) ||
copy_from_user(&data.type, &data32->type, 3 * sizeof(u32)))
goto error;
if (get_user(data->owner, &data32->owner))
if (get_user(data.owner, &data32->owner))
goto error;
switch (data->type) {
switch (data.type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER:
if (get_user(data->value.integer.min, &data32->value.integer.min) ||
get_user(data->value.integer.max, &data32->value.integer.max) ||
get_user(data->value.integer.step, &data32->value.integer.step))
if (get_user(data.value.integer.min, &data32->value.integer.min) ||
get_user(data.value.integer.max, &data32->value.integer.max) ||
get_user(data.value.integer.step, &data32->value.integer.step))
goto error;
break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64:
if (copy_from_user(&data->value.integer64,
if (copy_from_user(&data.value.integer64,
&data32->value.integer64,
sizeof(data->value.integer64)))
sizeof(data.value.integer64)))
goto error;
break;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
if (copy_from_user(&data->value.enumerated,
if (copy_from_user(&data.value.enumerated,
&data32->value.enumerated,
sizeof(data->value.enumerated)))
sizeof(data.value.enumerated)))
goto error;
data->value.enumerated.names_ptr =
(uintptr_t)compat_ptr(data->value.enumerated.names_ptr);
data.value.enumerated.names_ptr =
(uintptr_t)compat_ptr(data.value.enumerated.names_ptr);
break;
default:
break;
}
err = snd_ctl_elem_add(file, data, replace);
err = snd_ctl_elem_add(file, &data, replace);
error:
kfree(data);
return err;
}