Skip to content

Commit

Permalink
ovl: fix memory leak in ovl_parse_param()
Browse files Browse the repository at this point in the history
On failure to parse parameters in ovl_parse_param_lowerdir(), it is
necessary to update ctx->nr with the correct nr before using
ovl_reset_lowerdirs() to release l->name.

Reported-by: syzbot+26eedf3631650972f17c@syzkaller.appspotmail.com
Fixes: 0cea4c0 ("ovl: store and show the user provided lowerdir mount option")
Co-authored-by: Edward Adam Davis <eadavis@qq.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
  • Loading branch information
amir73il and Edward Adam Davis committed Nov 12, 2023
1 parent 4d3d328 commit 97d5899
Showing 1 changed file with 5 additions and 6 deletions.
11 changes: 5 additions & 6 deletions fs/overlayfs/params.c
Expand Up @@ -430,7 +430,7 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
struct ovl_fs_context *ctx = fc->fs_private;
struct ovl_fs_context_layer *l;
char *dup = NULL, *iter;
ssize_t nr_lower = 0, nr = 0, nr_data = 0;
ssize_t nr_lower, nr;
bool data_layer = false;

/*
Expand Down Expand Up @@ -482,6 +482,7 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
iter = dup;
l = ctx->lower;
for (nr = 0; nr < nr_lower; nr++, l++) {
ctx->nr++;
memset(l, 0, sizeof(*l));

err = ovl_mount_dir(iter, &l->path);
Expand All @@ -498,10 +499,10 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
goto out_put;

if (data_layer)
nr_data++;
ctx->nr_data++;

/* Calling strchr() again would overrun. */
if ((nr + 1) == nr_lower)
if (ctx->nr == nr_lower)
break;

err = -EINVAL;
Expand All @@ -511,7 +512,7 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
* This is a regular layer so we require that
* there are no data layers.
*/
if ((ctx->nr_data + nr_data) > 0) {
if (ctx->nr_data > 0) {
pr_err("regular lower layers cannot follow data lower layers");
goto out_put;
}
Expand All @@ -524,8 +525,6 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
data_layer = true;
iter++;
}
ctx->nr = nr_lower;
ctx->nr_data += nr_data;
kfree(dup);
return 0;

Expand Down

0 comments on commit 97d5899

Please sign in to comment.