summaryrefslogtreecommitdiff
path: root/mount
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2007-04-13 07:54:38 -0400
committerKarel Zak <kzak@redhat.com>2007-04-26 00:31:39 +0200
commit1510285d494fc8937036027303fcd3305e7873fb (patch)
treeee4cf42589df587f6c0f235c10aab98261d9cd2a /mount
parent3cccadb2f7a842d3296cf5949892177b45946a72 (diff)
downloadutil-linux-old-1510285d494fc8937036027303fcd3305e7873fb.tar.gz
mount: fix memory usage in update_mtab
The update_mtab deallocates memory which was allocated by caller. It's nice opportunity for double-free errors. The patch fix a memory leak if we have to abort before mc0 are freed. The patch also fix a memory leak when we deallocate old (umounted) entry. Signed-off-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: Martin Schlemmer <azarah@gentoo.org> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'mount')
-rw-r--r--mount/fstab.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/mount/fstab.c b/mount/fstab.c
index 1e186c19..8e59c8a0 100644
--- a/mount/fstab.c
+++ b/mount/fstab.c
@@ -102,11 +102,8 @@ my_free(const void *s) {
}
static void
-discard_mntentchn(struct mntentchn *mc0) {
- struct mntentchn *mc, *mc1;
-
- for (mc = mc0->nxt; mc && mc != mc0; mc = mc1) {
- mc1 = mc->nxt;
+my_free_mc(struct mntentchn *mc) {
+ if (mc) {
my_free(mc->m.mnt_fsname);
my_free(mc->m.mnt_dir);
my_free(mc->m.mnt_type);
@@ -115,6 +112,17 @@ discard_mntentchn(struct mntentchn *mc0) {
}
}
+
+static void
+discard_mntentchn(struct mntentchn *mc0) {
+ struct mntentchn *mc, *mc1;
+
+ for (mc = mc0->nxt; mc && mc != mc0; mc = mc1) {
+ mc1 = mc->nxt;
+ my_free_mc(mc);
+ }
+}
+
static void
read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
struct mntentchn *mc = mc0;
@@ -636,11 +644,12 @@ update_mtab (const char *dir, struct my_mntent *instead) {
if (mc && mc != mc0) {
mc->prev->nxt = mc->nxt;
mc->nxt->prev = mc->prev;
- free(mc);
+ my_free_mc(mc);
}
} else if (!strcmp(mc->m.mnt_dir, instead->mnt_dir)) {
/* A remount */
- mc->m.mnt_opts = instead->mnt_opts;
+ my_free(mc->m.mnt_opts);
+ mc->m.mnt_opts = xstrdup(instead->mnt_opts);
} else {
/* A move */
my_free(mc->m.mnt_dir);
@@ -649,7 +658,12 @@ update_mtab (const char *dir, struct my_mntent *instead) {
} else if (instead) {
/* not found, add a new entry */
absent = xmalloc(sizeof(*absent));
- absent->m = *instead;
+ absent->m.mnt_fsname = xstrdup(instead->mnt_fsname);
+ absent->m.mnt_dir = xstrdup(instead->mnt_dir);
+ absent->m.mnt_type = xstrdup(instead->mnt_type);
+ absent->m.mnt_opts = xstrdup(instead->mnt_opts);
+ absent->m.mnt_freq = instead->mnt_freq;
+ absent->m.mnt_passno = instead->mnt_passno;
absent->nxt = mc0;
absent->prev = mc0->prev;
mc0->prev = absent;
@@ -663,6 +677,7 @@ update_mtab (const char *dir, struct my_mntent *instead) {
int errsv = errno;
error (_("cannot open %s (%s) - mtab not updated"),
MOUNTED_TEMP, strerror (errsv));
+ discard_mntentchn(mc0);
goto leave;
}