6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein amir73il@gmail.com
commit 37f32f52643869131ec01bb69bdf9f404f6109fb upstream.
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-and-tested-by: syzbot+26eedf3631650972f17c@syzkaller.appspotmail.com Fixes: c835110b588a ("ovl: remove unused code in lowerdir param parsing") Co-authored-by: Edward Adam Davis eadavis@qq.com Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Jingbo Xu jefflexu@linux.alibaba.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/overlayfs/params.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
--- a/fs/overlayfs/params.c +++ b/fs/overlayfs/params.c @@ -438,7 +438,7 @@ static int ovl_parse_param_lowerdir(cons 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;
/* @@ -490,6 +490,7 @@ static int ovl_parse_param_lowerdir(cons 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); @@ -506,10 +507,10 @@ static int ovl_parse_param_lowerdir(cons 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; @@ -519,7 +520,7 @@ static int ovl_parse_param_lowerdir(cons * 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; } @@ -532,8 +533,6 @@ static int ovl_parse_param_lowerdir(cons data_layer = true; iter++; } - ctx->nr = nr_lower; - ctx->nr_data += nr_data; kfree(dup); return 0;