[syslinux:master] extlinux: fix memory leak

syslinux-bot for Imran Zaman imran.zaman at intel.com
Sun Sep 27 15:06:03 PDT 2015


Commit-ID:  4f2f680ab3793052d9eac49f1b60e90185619601
Gitweb:     http://www.syslinux.org/commit/4f2f680ab3793052d9eac49f1b60e90185619601
Author:     Imran Zaman <imran.zaman at intel.com>
AuthorDate: Sun, 27 Sep 2015 14:19:27 -0400
Committer:  Gene Cumm <gene.cumm at gmail.com>
CommitDate: Sun, 27 Sep 2015 14:20:19 -0400

extlinux: fix memory leak

devname is put on heap for all cases to avoid memory
leak, and ease of use in future as well

Signed-off-by: Imran Zaman <imran.zaman at intel.com>
Reviewed-by: Paulo Alcantara <pcacjr at zytor.com>

---
 extlinux/main.c | 44 ++++++++++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/extlinux/main.c b/extlinux/main.c
index 09740bd..6ba16e1 100644
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -1032,12 +1032,12 @@ err:
 }
 
 #ifndef __KLIBC__
-static const char *find_device(const char *mtab_file, dev_t dev)
+static char *find_device(const char *mtab_file, dev_t dev)
 {
     struct mntent *mnt;
     struct stat dst;
     FILE *mtab;
-    const char *devname = NULL;
+    char *devname = NULL;
     bool done;
 
     mtab = setmntent(mtab_file, "r");
@@ -1119,7 +1119,7 @@ static const char *find_device(const char *mtab_file, dev_t dev)
  * On newer Linux kernels we can use sysfs to get a backwards mapping
  * from device names to standard filenames
  */
-static const char *find_device_sysfs(dev_t dev)
+static char *find_device_sysfs(dev_t dev)
 {
     char sysname[64];
     char linkname[PATH_MAX];
@@ -1269,9 +1269,20 @@ err:
     return rv;
 }
 
-static const char *get_devname(const char *path)
+static char *dupname(const char *name)
 {
-    const char *devname = NULL;
+    char *out = NULL;
+    int len = 0;
+    if (name)
+        len = strlen(name);
+    if (len > 0)
+        out = strndup(name, len);
+    return out;
+}
+
+static char *get_devname(const char *path)
+{
+    char *devname = NULL;
     struct stat st;
     struct statfs sfs;
 
@@ -1285,17 +1296,17 @@ static const char *get_devname(const char *path)
     }
 
     if (opt.device)
-	devname = opt.device;
+	devname = strdup(opt.device);
 
     if (!devname){
 	if (fs_type == BTRFS) {
 	    /* For btrfs try to get the device name from btrfs itself */
-	    devname = find_device_btrfs(path);
+	    devname = dupname(find_device_btrfs(path));
 	}
     }
 
     if (!devname) {
-	devname = find_device_mountinfo(path, st.st_dev);
+	devname = dupname(find_device_mountinfo(path, st.st_dev));
     }
 
 #ifdef __KLIBC__
@@ -1314,7 +1325,7 @@ static const char *get_devname(const char *path)
 	}
 
 	atexit(device_cleanup);	/* unlink the device node on exit */
-	devname = devname_buf;
+	devname = dupname(devname_buf);
     }
 
 #else
@@ -1338,10 +1349,10 @@ static const char *get_devname(const char *path)
     return devname;
 }
 
-static int open_device(const char *path, struct stat *st, const char **_devname)
+static int open_device(const char *path, struct stat *st, char **_devname)
 {
     int devfd;
-    const char *devname = NULL;
+    char *devname = NULL;
     struct statfs sfs;
 
     if (st)
@@ -1381,11 +1392,10 @@ static int open_device(const char *path, struct stat *st, const char **_devname)
 
     devfd = -1;
     devname = get_devname(path);
-    if (_devname)
-	*_devname = devname;
 
     if ((devfd = open(devname, O_RDWR | O_SYNC)) < 0) {
 	fprintf(stderr, "%s: cannot open device %s\n", program, devname);
+	free(devname);
 	return -1;
     }
 
@@ -1393,9 +1403,14 @@ static int open_device(const char *path, struct stat *st, const char **_devname)
     if (validate_device(path, devfd)) {
 	fprintf(stderr, "%s: path %s doesn't match device %s\n",
 		program, path, devname);
+	free(devname);
 	close(devfd);
 	return -1;
     }
+    if (_devname)
+        *_devname = devname;
+    else
+        free(devname);
     return devfd;
 }
 
@@ -1456,7 +1471,7 @@ static int install_loader(const char *path, int update_only)
 {
     struct stat st, fst;
     int devfd, rv;
-    const char *devname;
+    char *devname = NULL;
 
     devfd = open_device(path, &st, &devname);
     if (devfd < 0)
@@ -1496,6 +1511,7 @@ static int install_loader(const char *path, int update_only)
 
     sync();
     rv = install_bootblock(devfd, devname);
+    free(devname);
     close(devfd);
     sync();
 


More information about the Syslinux-commits mailing list