iio.c: fix memory leak and out of bound array access issue
authorLay, Kuan Loon <kuan.loon.lay@intel.com>
Thu, 17 Dec 2015 06:53:44 +0000 (14:53 +0800)
committerBrendan Le Foll <brendan.le.foll@intel.com>
Thu, 17 Dec 2015 11:28:26 +0000 (11:28 +0000)
Fix memory leak in mraa_iio_update_channels() and mraa_iio_get_channel_data().
In mraa_iio_update_channels(), we add checking for out of bound array access.

Signed-off-by: Lay, Kuan Loon <kuan.loon.lay@intel.com>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
src/iio/iio.c [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index da6dc59..d8b0546
@@ -154,6 +154,7 @@ mraa_iio_get_channel_data(mraa_iio_context dev)
                 if (fd > 0) {
                     if (read(fd, readbuf, 2 * sizeof(char)) != 2) {
                         syslog(LOG_ERR, "iio: Failed to read a sensible value from sysfs");
+                        free(str);
                         return -1;
                     }
                     chan->enabled = (int) strtol(readbuf, NULL, 10);
@@ -577,29 +578,32 @@ mraa_iio_update_channels(mraa_iio_context dev)
                         break;
                     }
                     chan_num = ((int) strtol(readbuf, NULL, 10));
-                    chan = &dev->channels[chan_num];
-                    chan->index = chan_num;
-                    close(fd);
+                    if (chan_num >= 0 && chan_num < dev->chan_num) {
+                        chan = &dev->channels[chan_num];
+                        chan->index = chan_num;
+                        close(fd);
 
-                    buf[(strlen(buf) - 5)] = '\0';
-                    char* str = strdup(buf);
-                    // grab the enable flag of channel
-                    snprintf(buf, MAX_SIZE, "%sen", str);
-                    fd = open(buf, O_RDONLY);
-                    if (fd > 0) {
-                        if (read(fd, readbuf, 2 * sizeof(char)) != 2) {
-                            syslog(LOG_ERR, "iio: Failed to read a sensible value from sysfs");
-                            return -1;
+                        buf[(strlen(buf) - 5)] = '\0';
+                        char* str = strdup(buf);
+                        // grab the enable flag of channel
+                        snprintf(buf, MAX_SIZE, "%sen", str);
+                        fd = open(buf, O_RDONLY);
+                        if (fd > 0) {
+                            if (read(fd, readbuf, 2 * sizeof(char)) != 2) {
+                                syslog(LOG_ERR, "iio: Failed to read a sensible value from sysfs");
+                                free(str);
+                                return -1;
+                            }
+                            chan->enabled = (int) strtol(readbuf, NULL, 10);
+                            // only calculate enable buffer size for trigger buffer extract data
+                            if (chan->enabled) {
+                                dev->datasize += chan->bytes;
+                            }
+                            close(fd);
                         }
-                        chan->enabled = (int) strtol(readbuf, NULL, 10);
-                        // only calculate enable buffer size for trigger buffer extract data
-                        if (chan->enabled) {
-                            dev->datasize += chan->bytes;
-                        }
-                        close(fd);
+                        // clean up str var
+                        free(str);
                     }
-                    // clean up str var
-                    free(str);
                 }
             }
         }