aboutsummaryrefslogtreecommitdiff
path: root/sys/geom
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2018-02-16 15:41:03 +0000
committerMark Johnston <markj@FreeBSD.org>2018-02-16 15:41:03 +0000
commit16759360d44b416be38238fb2d5a51bb0934bbf6 (patch)
treee767c12a340c04dc1f4e9c623612687b414de4fc /sys/geom
parent3f060b60b12a5ad3fe7d33f69957ea4a69e9e6e9 (diff)
downloadsrc-16759360d44b416be38238fb2d5a51bb0934bbf6.tar.gz
src-16759360d44b416be38238fb2d5a51bb0934bbf6.zip
Fix a memory leak introduced in r328426.
ffs_sbget() may return a superblock buffer even if it fails, so the caller must be prepared to free it in this case. Moreover, when tasting alternate superblock locations in a loop, ffs_sbget()'s readfunc callback must free the previously allocated buffer. Reported and tested by: pho Reviewed by: kib (previous version) Differential Revision: https://reviews.freebsd.org/D14390
Notes
Notes: svn path=/head/; revision=329375
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/geom_io.c2
-rw-r--r--sys/geom/journal/g_journal_ufs.c3
-rw-r--r--sys/geom/label/g_label_ufs.c7
3 files changed, 11 insertions, 1 deletions
diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c
index bab0041a244c..0f63b1ff31ec 100644
--- a/sys/geom/geom_io.c
+++ b/sys/geom/geom_io.c
@@ -966,6 +966,8 @@ g_use_g_read_data(void *devfd, off_t loc, void **bufp, int size)
*/
if (loc % cp->provider->sectorsize != 0)
return (ENOENT);
+ if (*bufp != NULL)
+ g_free(*bufp);
*bufp = g_read_data(cp, loc, size, NULL);
if (*bufp == NULL)
return (ENOENT);
diff --git a/sys/geom/journal/g_journal_ufs.c b/sys/geom/journal/g_journal_ufs.c
index ec25750c38ac..6672cceb8cb4 100644
--- a/sys/geom/journal/g_journal_ufs.c
+++ b/sys/geom/journal/g_journal_ufs.c
@@ -70,10 +70,13 @@ g_journal_ufs_dirty(struct g_consumer *cp)
struct fs *fs;
int error;
+ fs = NULL;
if (SBLOCKSIZE % cp->provider->sectorsize != 0 ||
ffs_sbget(cp, &fs, -1, NULL, g_use_g_read_data) != 0) {
GJ_DEBUG(0, "Cannot find superblock to mark file system %s "
"as dirty.", cp->provider->name);
+ if (fs != NULL)
+ g_free(fs);
return;
}
GJ_DEBUG(0, "clean=%d flags=0x%x", fs->fs_clean, fs->fs_flags);
diff --git a/sys/geom/label/g_label_ufs.c b/sys/geom/label/g_label_ufs.c
index 8ba49841b359..f32ec4d55c19 100644
--- a/sys/geom/label/g_label_ufs.c
+++ b/sys/geom/label/g_label_ufs.c
@@ -75,9 +75,14 @@ g_label_ufs_taste_common(struct g_consumer *cp, char *label, size_t size, int wh
pp = cp->provider;
label[0] = '\0';
+ fs = NULL;
if (SBLOCKSIZE % pp->sectorsize != 0 ||
- ffs_sbget(cp, &fs, -1, NULL, g_use_g_read_data) != 0)
+ ffs_sbget(cp, &fs, -1, NULL, g_use_g_read_data) != 0) {
+ if (fs != NULL)
+ g_free(fs);
return;
+ }
+
/*
* Check for magic. We also need to check if file system size
* is almost equal to providers size, because sysinstall(8)