hal: miscellaneous fixes
Fixes for the following issues reported by KW
21725, 21726, 21727, 21737, 21738, 21739, 21740, 21750,
21751, 21752, 25317, 30602, 32620, 36778, 41817, 41819,
50942, 54468, 54470, 54479, 55569, 54481, 55570, 55571,
58485, 85112, 85122, 85123
Change-Id: I9abef07db7ccdc19789a201eb268a97e1b360cad
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index 1d1613a..b6f8689 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -148,6 +148,10 @@
ALOGD("%s: enter", __func__);
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
+
+ if (!uc_info)
+ return -ENOMEM;
+
uc_info->id = USECASE_AUDIO_PLAYBACK_FM;
uc_info->type = PCM_PLAYBACK;
uc_info->stream.out = adev->primary_output;
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index 239c975..43557dc 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -136,6 +136,10 @@
ALOGD("%s: enter", __func__);
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
+
+ if (!uc_info)
+ return -ENOMEM;
+
uc_info->id = hfpmod.ucid;
uc_info->type = PCM_HFP_CALL;
uc_info->stream.out = adev->primary_output;
diff --git a/hal/audio_extn/listen.c b/hal/audio_extn/listen.c
index b1ed105..4cb2d2d 100644
--- a/hal/audio_extn/listen.c
+++ b/hal/audio_extn/listen.c
@@ -200,6 +200,11 @@
listen_dev = (struct listen_audio_device*)
calloc(1, sizeof(struct listen_audio_device));
+ if (!listen_dev) {
+ ALOGE("failed to allocate listen_dev mem");
+ return -ENOMEM;
+ }
+
listen_dev->lib_handle = lib_handle;
listen_dev->adev = adev;
diff --git a/hal/audio_extn/ssr.c b/hal/audio_extn/ssr.c
index ac6da8b..f32d217 100644
--- a/hal/audio_extn/ssr.c
+++ b/hal/audio_extn/ssr.c
@@ -294,8 +294,8 @@
if ( ret > 0 ) {
ALOGV("%s: Allocating surroundObj size is %d", __func__, ret);
ssrmod.surround_obj = (void *)malloc(ret);
- memset(ssrmod.surround_obj,0,ret);
if (NULL != ssrmod.surround_obj) {
+ memset(ssrmod.surround_obj,0,ret);
/* initialize after allocating the memory for surround_obj */
ret = ssrmod.surround_filters_init(ssrmod.surround_obj,
6,
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index bc83709..a4ea134 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -159,12 +159,16 @@
char *buffer;
int32_t err = 1;
int32_t size = 0;
- int32_t fd, i, channels_playback;
- char *read_buf, *str_start, *channel_start, *rates_str, *rates_str_for_val,
- *rates_str_start, *next_sr_str, *test, *next_sr_string, *temp_ptr;
+ int32_t fd=-1, i, channels_playback;
+ char *str_start, *channel_start, *rates_str_start, *next_sr_str,
+ *next_sr_string, *temp_ptr;
struct stat st;
- int *rates_supported;
+ char *read_buf = NULL;
+ char *rates_str = NULL;
+ char *rates_str_for_val = NULL;
+ int *rates_supported = NULL;
char path[128];
+ int ret = 0;
memset(&st, 0x0, sizeof(struct stat));
*sample_rate = 0;
@@ -175,45 +179,49 @@
if (fd <0) {
ALOGE("%s: error failed to open config file %s error: %d\n",
__func__, path, errno);
- close(fd);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
if (fstat(fd, &st) < 0) {
ALOGE("%s: error failed to stat %s error %d\n",
__func__, path, errno);
- close(fd);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
file_size = st.st_size;
read_buf = (char *)calloc(1, USB_BUFF_SIZE + 1);
+
+ if (!read_buf) {
+ ALOGE("Failed to create read_buf");
+ ret = -ENOMEM;
+ goto done;
+ }
+
err = read(fd, read_buf, USB_BUFF_SIZE);
str_start = strstr(read_buf, type);
if (str_start == NULL) {
ALOGE("%s: error %s section not found in usb config file",
__func__, type);
- close(fd);
- free(read_buf);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
channel_start = strstr(str_start, "Channels:");
if (channel_start == NULL) {
ALOGE("%s: error could not find Channels information", __func__);
- close(fd);
- free(read_buf);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
channel_start = strstr(channel_start, " ");
if (channel_start == NULL) {
ALOGE("%s: error channel section not found in usb config file",
__func__);
- close(fd);
- free(read_buf);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
channels_playback = atoi(channel_start);
@@ -227,44 +235,38 @@
rates_str_start = strstr(str_start, "Rates:");
if (rates_str_start == NULL) {
ALOGE("%s: error cant find rates information", __func__);
- close(fd);
- free(read_buf);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
rates_str_start = strstr(rates_str_start, " ");
if (rates_str_start == NULL) {
ALOGE("%s: error channel section not found in usb config file",
__func__);
- close(fd);
- free(read_buf);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
char *target = strchr(rates_str_start, '\n');
if (target == NULL) {
ALOGE("%s: error end of line not found", __func__);
- close(fd);
- free(read_buf);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
size = target - rates_str_start;
if ((rates_str = (char *)malloc(size + 1)) == NULL) {
ALOGE("%s: error unable to allocate memory to hold sample rate strings",
__func__);
- close(fd);
- free(read_buf);
- return -ENOMEM;
+ ret = -EINVAL;
+ goto done;
}
if ((rates_str_for_val = (char *)malloc(size + 1)) == NULL) {
ALOGE("%s: error unable to allocate memory to hold sample rate string",
__func__);
- close(fd);
- free(rates_str);
- free(read_buf);
- return -ENOMEM;
+ ret = -EINVAL;
+ goto done;
}
memcpy(rates_str, rates_str_start, size);
@@ -275,23 +277,23 @@
size = usb_get_numof_rates(rates_str);
if (!size) {
ALOGE("%s: error could not get rate size, returning", __func__);
- close(fd);
- free(rates_str_for_val);
- free(rates_str);
- free(read_buf);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
rates_supported = (int *)malloc(sizeof(int) * size);
+
+ if (!rates_supported) {
+ ALOGE("couldn't allocate mem for rates_supported");
+ ret = -EINVAL;
+ goto done;
+ }
+
next_sr_string = strtok_r(rates_str_for_val, " ,", &temp_ptr);
if (next_sr_string == NULL) {
ALOGE("%s: error could not get first rate val", __func__);
- close(fd);
- free(rates_str_for_val);
- free(rates_str);
- free(rates_supported);
- free(read_buf);
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
rates_supported[0] = atoi(next_sr_string);
@@ -299,6 +301,10 @@
__func__, rates_supported[0]);
for (i = 1; i<size; i++) {
next_sr_string = strtok_r(NULL, " ,.-", &temp_ptr);
+ if (next_sr_string == NULL) {
+ rates_supported[i] = -1; // fill in an invalid sr for the rest
+ continue;
+ }
rates_supported[i] = atoi(next_sr_string);
ALOGD("rates_supported[%d] for playback: %d",i, rates_supported[i]);
}
@@ -317,12 +323,13 @@
}
ALOGD("%s: sample_rate: %d", __func__, *sample_rate);
- close(fd);
- free(rates_str_for_val);
- free(rates_str);
- free(rates_supported);
- free(read_buf);
- return 0;
+done:
+ if (fd >= 0) close(fd);
+ if (rates_str_for_val) free(rates_str_for_val);
+ if (rates_str) free(rates_str);
+ if (rates_supported) free(rates_supported);
+ if (read_buf) free(read_buf);
+ return ret;
}
static int32_t usb_playback_entry(void *adev)
@@ -387,7 +394,6 @@
if(usbmod->proxy_pcm_playback_handle
&& !pcm_is_ready(usbmod->proxy_pcm_playback_handle)){
pcm_close(usbmod->proxy_pcm_playback_handle);
- usbmod->proxy_pcm_playback_handle = NULL;
proxy_open_retry_count--;
usleep(USB_PROXY_OPEN_WAIT_TIME * 1000);
ALOGE("%s: pcm_open for proxy failed retrying = %d",
@@ -507,7 +513,6 @@
if(usbmod->proxy_pcm_record_handle
&& !pcm_is_ready(usbmod->proxy_pcm_record_handle)){
pcm_close(usbmod->proxy_pcm_record_handle);
- usbmod->proxy_pcm_record_handle = NULL;
proxy_open_retry_count--;
usleep(USB_PROXY_OPEN_WAIT_TIME * 1000);
ALOGE("%s: pcm_open for proxy(recording) failed retrying = %d",
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index aa66360..e7a57c8 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -141,6 +141,9 @@
ALOGV("%s: format - %d", __func__, format);
if (format != 0) {
sf_info = (struct stream_format *)calloc(1, sizeof(struct stream_format));
+ if (sf_info == NULL)
+ break; /* return whatever was parsed */
+
sf_info->format = format;
list_add_tail(&so_info->format_list, &sf_info->list);
}
@@ -192,6 +195,12 @@
ALOGV("%s", __func__);
so_info = (struct streams_output_cfg *)calloc(1, sizeof(struct streams_output_cfg));
+
+ if (!so_info) {
+ ALOGE("failed to allocate mem for so_info list element");
+ return;
+ }
+
while (node) {
if (strcmp(node->name, FLAGS_TAG) == 0) {
so_info->flags = parse_flag_names((char *)node->value);
@@ -298,6 +307,11 @@
}
root = config_node("", "");
+ if (root == NULL) {
+ ALOGE("cfg_list, NULL config root");
+ return;
+ }
+
config_load(root, data);
load_output(root, platform, streams_output_cfg_list);