From df855e804886f2846d0bdb6d8b1aad506452f051 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Tue, 2 Jun 2020 11:41:13 +0530 Subject: mixer: Fix memory leak and other issues in mixer event Fix memory leak in mixer_wait_event(). Also, poll should be unblocked after increasing event_cnt in mixer_plugin, otherwise event_cnt can become negative during read_event. Fix the same. --- src/mixer.c | 29 +++++++++++++++++++---------- src/mixer_plugin.c | 2 +- 2 files changed, 20 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/mixer.c b/src/mixer.c index 582d8c1..c8480d7 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -475,7 +475,7 @@ int mixer_wait_event(struct mixer *mixer, int timeout) { struct pollfd *pfd; struct mixer_ctl_group *grp; - int count = 0, num_fds = 0, i; + int count = 0, num_fds = 0, i, ret = 0; if (mixer->fd >= 0) num_fds++; @@ -485,7 +485,7 @@ int mixer_wait_event(struct mixer *mixer, int timeout) num_fds++; #endif - pfd = (struct pollfd *)calloc(sizeof(struct pollfd), num_fds); + pfd = (struct pollfd *)calloc(num_fds, sizeof(struct pollfd)); if (!pfd) return -ENOMEM; @@ -506,33 +506,42 @@ int mixer_wait_event(struct mixer *mixer, int timeout) #endif if (!count) - return 0; + goto exit; for (;;) { int err; err = poll(pfd, count, timeout); - if (err < 0) - return -errno; + if (err < 0) { + ret = -errno; + goto exit; + } if (!err) - return 0; + goto exit; + for (i = 0; i < count; i++) { - if (pfd[i].revents & (POLLERR | POLLNVAL)) - return -EIO; + if (pfd[i].revents & (POLLERR | POLLNVAL)) { + ret = -EIO; + goto exit; + } if (pfd[i].revents & (POLLIN | POLLOUT)) { if ((i == 0) && mixer->fd >= 0) { grp = mixer->h_grp; grp->event_cnt++; } #ifdef TINYALSA_USES_PLUGINS - else { + else { grp = mixer->v_grp; grp->event_cnt++; } #endif - return 1; + ret = 1; + goto exit; } } } +exit: + free(pfd); + return ret; } /** Consume a mixer event. diff --git a/src/mixer_plugin.c b/src/mixer_plugin.c index 389003e..9f22b7e 100644 --- a/src/mixer_plugin.c +++ b/src/mixer_plugin.c @@ -137,8 +137,8 @@ static int mixer_plug_info_integer(struct snd_control *ctl, void mixer_plug_notifier_cb(struct mixer_plugin *plugin) { - eventfd_write(plugin->eventfd, 1); plugin->event_cnt++; + eventfd_write(plugin->eventfd, 1); } /* In consume_event/read, do not call eventfd_read until all events are read from list. -- cgit v1.2.3