Skip to content

Commit 0422c55

Browse files
FreddieChopingeky
authored andcommitted
Fix memory leaks in lfs_mount and lfs_format
Squashed: - Change lfs_deinit() return to void to simplify error handling - Move lfs_deinit() before lfs_init() - Fix memory leaks in lfs_init() - Fix memory leaks in lfs_format() - Fix memory leaks in lfs_mount()
1 parent 11ad3a2 commit 0422c55

File tree

1 file changed

+45
-31
lines changed

1 file changed

+45
-31
lines changed

lfs.c

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,21 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
20162016

20172017

20182018
/// Filesystem operations ///
2019+
static void lfs_deinit(lfs_t *lfs) {
2020+
// free allocated memory
2021+
if (!lfs->cfg->read_buffer) {
2022+
lfs_free(lfs->rcache.buffer);
2023+
}
2024+
2025+
if (!lfs->cfg->prog_buffer) {
2026+
lfs_free(lfs->pcache.buffer);
2027+
}
2028+
2029+
if (!lfs->cfg->lookahead_buffer) {
2030+
lfs_free(lfs->free.buffer);
2031+
}
2032+
}
2033+
20192034
static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
20202035
lfs->cfg = cfg;
20212036

@@ -2025,7 +2040,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
20252040
} else {
20262041
lfs->rcache.buffer = lfs_malloc(lfs->cfg->read_size);
20272042
if (!lfs->rcache.buffer) {
2028-
return LFS_ERR_NOMEM;
2043+
goto cleanup;
20292044
}
20302045
}
20312046

@@ -2035,7 +2050,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
20352050
} else {
20362051
lfs->pcache.buffer = lfs_malloc(lfs->cfg->prog_size);
20372052
if (!lfs->pcache.buffer) {
2038-
return LFS_ERR_NOMEM;
2053+
goto cleanup;
20392054
}
20402055
}
20412056

@@ -2051,7 +2066,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
20512066
} else {
20522067
lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead/8);
20532068
if (!lfs->free.buffer) {
2054-
return LFS_ERR_NOMEM;
2069+
goto cleanup;
20552070
}
20562071
}
20572072

@@ -2071,23 +2086,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
20712086
lfs->deorphaned = false;
20722087

20732088
return 0;
2074-
}
20752089

2076-
static int lfs_deinit(lfs_t *lfs) {
2077-
// free allocated memory
2078-
if (!lfs->cfg->read_buffer) {
2079-
lfs_free(lfs->rcache.buffer);
2080-
}
2081-
2082-
if (!lfs->cfg->prog_buffer) {
2083-
lfs_free(lfs->pcache.buffer);
2084-
}
2085-
2086-
if (!lfs->cfg->lookahead_buffer) {
2087-
lfs_free(lfs->free.buffer);
2088-
}
2089-
2090-
return 0;
2090+
cleanup:
2091+
lfs_deinit(lfs);
2092+
return LFS_ERR_NOMEM;
20912093
}
20922094

20932095
int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
@@ -2107,19 +2109,19 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
21072109
lfs_dir_t superdir;
21082110
err = lfs_dir_alloc(lfs, &superdir);
21092111
if (err) {
2110-
return err;
2112+
goto cleanup;
21112113
}
21122114

21132115
// write root directory
21142116
lfs_dir_t root;
21152117
err = lfs_dir_alloc(lfs, &root);
21162118
if (err) {
2117-
return err;
2119+
goto cleanup;
21182120
}
21192121

21202122
err = lfs_dir_commit(lfs, &root, NULL, 0);
21212123
if (err) {
2122-
return err;
2124+
goto cleanup;
21232125
}
21242126

21252127
lfs->root[0] = root.pair[0];
@@ -2150,24 +2152,28 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
21502152
&superblock.d, sizeof(superblock.d)}
21512153
}, 1);
21522154
if (err && err != LFS_ERR_CORRUPT) {
2153-
return err;
2155+
goto cleanup;
21542156
}
21552157

21562158
valid = valid || !err;
21572159
}
21582160

21592161
if (!valid) {
2160-
return LFS_ERR_CORRUPT;
2162+
err = LFS_ERR_CORRUPT;
2163+
goto cleanup;
21612164
}
21622165

21632166
// sanity check that fetch works
21642167
err = lfs_dir_fetch(lfs, &superdir, (const lfs_block_t[2]){0, 1});
21652168
if (err) {
2166-
return err;
2169+
goto cleanup;
21672170
}
21682171

21692172
lfs_alloc_ack(lfs);
2170-
return lfs_deinit(lfs);
2173+
2174+
cleanup:
2175+
lfs_deinit(lfs);
2176+
return err;
21712177
}
21722178

21732179
int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
@@ -2187,15 +2193,15 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
21872193
lfs_superblock_t superblock;
21882194
err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1});
21892195
if (err && err != LFS_ERR_CORRUPT) {
2190-
return err;
2196+
goto cleanup;
21912197
}
21922198

21932199
if (!err) {
21942200
err = lfs_bd_read(lfs, dir.pair[0], sizeof(dir.d),
21952201
&superblock.d, sizeof(superblock.d));
21962202
lfs_superblock_fromle32(&superblock.d);
21972203
if (err) {
2198-
return err;
2204+
goto cleanup;
21992205
}
22002206

22012207
lfs->root[0] = superblock.d.root[0];
@@ -2204,22 +2210,30 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
22042210

22052211
if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) {
22062212
LFS_ERROR("Invalid superblock at %d %d", 0, 1);
2207-
return LFS_ERR_CORRUPT;
2213+
err = LFS_ERR_CORRUPT;
2214+
goto cleanup;
22082215
}
22092216

22102217
uint16_t major_version = (0xffff & (superblock.d.version >> 16));
22112218
uint16_t minor_version = (0xffff & (superblock.d.version >> 0));
22122219
if ((major_version != LFS_DISK_VERSION_MAJOR ||
22132220
minor_version > LFS_DISK_VERSION_MINOR)) {
22142221
LFS_ERROR("Invalid version %d.%d", major_version, minor_version);
2215-
return LFS_ERR_INVAL;
2222+
err = LFS_ERR_INVAL;
2223+
goto cleanup;
22162224
}
22172225

22182226
return 0;
2227+
2228+
cleanup:
2229+
2230+
lfs_deinit(lfs);
2231+
return err;
22192232
}
22202233

22212234
int lfs_unmount(lfs_t *lfs) {
2222-
return lfs_deinit(lfs);
2235+
lfs_deinit(lfs);
2236+
return 0;
22232237
}
22242238

22252239

0 commit comments

Comments
 (0)