aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorImran Zaman <imran.zaman@intel.com>2015-09-27 14:19:27 -0400
committerGene Cumm <gene.cumm@gmail.com>2015-09-27 14:20:19 -0400
commit4f2f680ab3793052d9eac49f1b60e90185619601 (patch)
treef252388e40d852f31b647d3f8a4f80db37ac9374
parenta8cb6dfc231f4ed1fe97fd49800b984738a26ffd (diff)
downloadsyslinux-4f2f680ab3793052d9eac49f1b60e90185619601.tar.gz
syslinux-4f2f680ab3793052d9eac49f1b60e90185619601.tar.xz
syslinux-4f2f680ab3793052d9eac49f1b60e90185619601.zip
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@intel.com> Reviewed-by: Paulo Alcantara <pcacjr@zytor.com>
-rw-r--r--extlinux/main.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/extlinux/main.c b/extlinux/main.c
index 09740bd7..6ba16e1e 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();