dsp: codecs: check buffer size before copy

check audio node buffer size if it is sufficient
enough to copy the meta data before copying the meta
data contents to it.

Change-Id: I0bd67bddf902659ddd533a6f0d9440e873d51329
Signed-off-by: Karthikeyan Mani <kmani@codeaurora.org>
This commit is contained in:
Karthikeyan Mani
2018-09-25 17:41:30 -07:00
committed by Gerrit - the friendly Code Review server
parent a984bd8837
commit 0c79439a2f
3 changed files with 24 additions and 9 deletions

View File

@@ -1181,7 +1181,13 @@ static int audio_aio_buf_add_shared(struct q6audio_aio *audio, u32 dir,
kfree(buf_node); kfree(buf_node);
return -EINVAL; return -EINVAL;
} }
extract_meta_out_info(audio, buf_node, 1); ret = extract_meta_out_info(audio, buf_node, 1);
if (ret) {
pr_debug("%s: extract meta failed with %d\n",
__func__, ret);
kfree(buf_node);
return ret;
}
/* Not a EOS buffer */ /* Not a EOS buffer */
if (!(buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOS_SET)) { if (!(buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOS_SET)) {
spin_lock_irqsave(&audio->dsp_lock, flags); spin_lock_irqsave(&audio->dsp_lock, flags);
@@ -1683,7 +1689,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd,
case AUDIO_SET_CONFIG: { case AUDIO_SET_CONFIG: {
struct msm_audio_config config; struct msm_audio_config config;
pr_err("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); pr_debug("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio);
mutex_lock(&audio->lock); mutex_lock(&audio->lock);
if (copy_from_user(&config, (void *)arg, sizeof(config))) { if (copy_from_user(&config, (void *)arg, sizeof(config))) {
pr_err( pr_err(
@@ -2010,7 +2016,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd,
mutex_unlock(&audio->lock); mutex_unlock(&audio->lock);
break; break;
} }
pr_err("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); pr_debug("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio);
if (copy_from_user(&config_32, (void *)arg, if (copy_from_user(&config_32, (void *)arg,
sizeof(config_32))) { sizeof(config_32))) {
pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n", pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n",

View File

@@ -210,7 +210,7 @@ void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token,
int insert_eos_buf(struct q6audio_aio *audio, int insert_eos_buf(struct q6audio_aio *audio,
struct audio_aio_buffer_node *buf_node); struct audio_aio_buffer_node *buf_node);
void extract_meta_out_info(struct q6audio_aio *audio, int extract_meta_out_info(struct q6audio_aio *audio,
struct audio_aio_buffer_node *buf_node, int dir); struct audio_aio_buffer_node *buf_node, int dir);
int audio_aio_open(struct q6audio_aio *audio, struct file *file); int audio_aio_open(struct q6audio_aio *audio, struct file *file);

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@@ -118,19 +118,26 @@ void audio_aio_cb(uint32_t opcode, uint32_t token,
} }
} }
void extract_meta_out_info(struct q6audio_aio *audio, int extract_meta_out_info(struct q6audio_aio *audio,
struct audio_aio_buffer_node *buf_node, int dir) struct audio_aio_buffer_node *buf_node, int dir)
{ {
struct dec_meta_out *meta_data = buf_node->kvaddr; struct dec_meta_out *meta_data = buf_node->kvaddr;
uint32_t temp; uint32_t temp;
if (dir) { /* input buffer - Write */ if (dir) { /* input buffer - Write */
if (audio->buf_cfg.meta_info_enable) if (audio->buf_cfg.meta_info_enable) {
if (buf_node->buf.buf_len <
sizeof(struct dec_meta_in)) {
pr_debug("%s: invalid buf len %d\n",
__func__, buf_node->buf.buf_len);
return -EINVAL;
}
memcpy(&buf_node->meta_info.meta_in, memcpy(&buf_node->meta_info.meta_in,
(char *)buf_node->kvaddr, sizeof(struct dec_meta_in)); (char *)buf_node->kvaddr, sizeof(struct dec_meta_in));
else } else {
memset(&buf_node->meta_info.meta_in, memset(&buf_node->meta_info.meta_in,
0, sizeof(struct dec_meta_in)); 0, sizeof(struct dec_meta_in));
}
pr_debug("%s[%pK]:i/p: msw_ts %d lsw_ts %d nflags 0x%8x\n", pr_debug("%s[%pK]:i/p: msw_ts %d lsw_ts %d nflags 0x%8x\n",
__func__, audio, __func__, audio,
buf_node->meta_info.meta_in.ntimestamp.highpart, buf_node->meta_info.meta_in.ntimestamp.highpart,
@@ -156,6 +163,7 @@ void extract_meta_out_info(struct q6audio_aio *audio,
meta_out_dsp[0].nflags, meta_out_dsp[0].nflags,
((struct dec_meta_out *)buf_node->kvaddr)->num_of_frames); ((struct dec_meta_out *)buf_node->kvaddr)->num_of_frames);
} }
return 0;
} }
/* Read buffer from DSP / Handle Ack from DSP */ /* Read buffer from DSP / Handle Ack from DSP */
@@ -165,6 +173,7 @@ void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token,
unsigned long flags; unsigned long flags;
union msm_audio_event_payload event_payload; union msm_audio_event_payload event_payload;
struct audio_aio_buffer_node *filled_buf; struct audio_aio_buffer_node *filled_buf;
int ret;
pr_debug("%s\n", __func__); pr_debug("%s\n", __func__);
@@ -208,7 +217,7 @@ void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token,
__func__, audio, __func__, audio,
filled_buf->meta_info.meta_out.num_of_frames, filled_buf->meta_info.meta_out.num_of_frames,
event_payload.aio_buf.data_len); event_payload.aio_buf.data_len);
extract_meta_out_info(audio, filled_buf, 0); ret = extract_meta_out_info(audio, filled_buf, 0);
audio->eos_rsp = 0; audio->eos_rsp = 0;
} }
pr_debug("%s, posting read done to the app here\n", __func__); pr_debug("%s, posting read done to the app here\n", __func__);