diff options
Diffstat (limited to 'sound/core/compress_offload.c')
-rw-r--r-- | sound/core/compress_offload.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index eb60cb8dbb8..ad11dc99479 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -100,12 +100,15 @@ static int snd_compr_open(struct inode *inode, struct file *f) if (dirn != compr->direction) { pr_err("this device doesn't support this direction\n"); + snd_card_unref(compr->card); return -EINVAL; } data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) + if (!data) { + snd_card_unref(compr->card); return -ENOMEM; + } data->stream.ops = compr->ops; data->stream.direction = dirn; data->stream.private_data = compr->private_data; @@ -113,6 +116,7 @@ static int snd_compr_open(struct inode *inode, struct file *f) runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); if (!runtime) { kfree(data); + snd_card_unref(compr->card); return -ENOMEM; } runtime->state = SNDRV_PCM_STATE_OPEN; @@ -126,7 +130,8 @@ static int snd_compr_open(struct inode *inode, struct file *f) kfree(runtime); kfree(data); } - return ret; + snd_card_unref(compr->card); + return 0; } static int snd_compr_free(struct inode *inode, struct file *f) @@ -425,6 +430,26 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream, return 0; } +static int snd_compress_check_input(struct snd_compr_params *params) +{ + /* first let's check the buffer parameter's */ + if (params->buffer.fragment_size == 0 || + params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size) + return -EINVAL; + + /* now codec parameters */ + if (params->codec.id == 0 || params->codec.id > SND_AUDIOCODEC_MAX) + return -EINVAL; + + if (params->codec.ch_in == 0 || params->codec.ch_out == 0) + return -EINVAL; + + if (!(params->codec.sample_rate & SNDRV_PCM_RATE_8000_192000)) + return -EINVAL; + + return 0; +} + static int snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) { @@ -443,11 +468,17 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) retval = -EFAULT; goto out; } + + retval = snd_compress_check_input(params); + if (retval) + goto out; + retval = snd_compr_allocate_buffer(stream, params); if (retval) { retval = -ENOMEM; goto out; } + retval = stream->ops->set_params(stream, params); if (retval) goto out; |