From nobody Fri Dec 19 20:13:12 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 51303130AFA; Sun, 24 Mar 2024 23:02:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711321367; cv=none; b=ZyPt7l4sOWxXq6oUoYlxT8aVQ7bjeyWo5jzhXmNk9UDEFUKf8YjqzSPwaApTE1Pu+02H1QAU9nS+asOxCJSRDcm8by81m/BQTm/RLMjqkz0aYxt2DxnJKvgVaCn7mVMU/v/gO10/hEQBN46QXYp+gTfRXe73gJ2df4Zbz4EEovY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711321367; c=relaxed/simple; bh=+qbaCAofjncVFu4+vwJQ5PxTT816Cw4fc9hpPcujUto=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Toi1Gfnfq8QpVu0arX2Sdr1Lzj/ldYqQPcUV7Xn8bhR2peEuniFStAflQTaGNpN3FN1GMS+rMDniaaaNEujn58eUZTAAUAplgFLRa7yS0fIOIY9CCCGMDuBSjrammXlfLsKViYrb59EUE+xdaa5yz1iQA0+6vZSQ6SrDv1RFNIY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=j6nUrM4T; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="j6nUrM4T" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4D786C43399; Sun, 24 Mar 2024 23:02:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1711321366; bh=+qbaCAofjncVFu4+vwJQ5PxTT816Cw4fc9hpPcujUto=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j6nUrM4TixKJfqyL3tJ+UwVDWQy4BZvxsHh0SvgrDu0Nk9H125VubcM0W7nOLeLsB YgHym2ml/lhfY9lccxma1cFqN8Op4fY18sJIHPNFQmSxAaZ1QN/4JvuQPOV8TBlwsf nugvgiid19SSAIk1O4AIdrC43bmILipZijnCi8nvbg42xhwXrlOYaocPf6xcxktbb/ aVSZei7SCX9+uwaRf5vn3QNrMgUM7oJcILyYzEh5m2sowS4UiLaBNe5QTPX/7VnuSE CF7d03fGSTk03r/d5GOYeyvRdvyR7jTXV+58iZDW1dFDTZkHp5XZJJRhY/E+c06ffm MgruhU27gi+lA== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Amir Goldstein , Miklos Szeredi , Sasha Levin Subject: [PATCH 6.6 091/638] ovl: refactor layer parsing helpers Date: Sun, 24 Mar 2024 18:52:08 -0400 Message-ID: <20240324230116.1348576-92-sashal@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240324230116.1348576-1-sashal@kernel.org> References: <20240324230116.1348576-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Amir Goldstein [ Upstream commit 819829f0319a759e8a6ccb7e4f1113f3f9f07aa3 ] In preparation for new mount options to add lowerdirs one by one, generalize ovl_parse_param_upperdir() into helper ovl_parse_layer() that will be used for parsing a single lower layers. Suggested-by: Miklos Szeredi Link: https://lore.kernel.org/r/CAJfpegt7VC94KkRtb1dfHG8+4OzwPBLYqhtc8=3DQF= UxpFJE+=3DRQ@mail.gmail.com/ Signed-off-by: Amir Goldstein Stable-dep-of: 2824083db76c ("ovl: Always reject mounting over case-insensi= tive directories") Signed-off-by: Sasha Levin --- fs/overlayfs/params.c | 121 +++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 54 deletions(-) diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c index 0bf754a69e919..88725982b6dd3 100644 --- a/fs/overlayfs/params.c +++ b/fs/overlayfs/params.c @@ -43,7 +43,7 @@ module_param_named(metacopy, ovl_metacopy_def, bool, 0644= ); MODULE_PARM_DESC(metacopy, "Default to on or off for the metadata only copy up feature"); =20 -enum { +enum ovl_opt { Opt_lowerdir, Opt_upperdir, Opt_workdir, @@ -238,19 +238,8 @@ static int ovl_mount_dir_noesc(const char *name, struc= t path *path) pr_err("failed to resolve '%s': %i\n", name, err); goto out; } - err =3D -EINVAL; - if (ovl_dentry_weird(path->dentry)) { - pr_err("filesystem on '%s' not supported\n", name); - goto out_put; - } - if (!d_is_dir(path->dentry)) { - pr_err("'%s' not a directory\n", name); - goto out_put; - } return 0; =20 -out_put: - path_put_init(path); out: return err; } @@ -268,7 +257,7 @@ static void ovl_unescape(char *s) } } =20 -static int ovl_mount_dir(const char *name, struct path *path, bool upper) +static int ovl_mount_dir(const char *name, struct path *path) { int err =3D -ENOMEM; char *tmp =3D kstrdup(name, GFP_KERNEL); @@ -276,60 +265,82 @@ static int ovl_mount_dir(const char *name, struct pat= h *path, bool upper) if (tmp) { ovl_unescape(tmp); err =3D ovl_mount_dir_noesc(tmp, path); - - if (!err && upper && path->dentry->d_flags & DCACHE_OP_REAL) { - pr_err("filesystem on '%s' not supported as upperdir\n", - tmp); - path_put_init(path); - err =3D -EINVAL; - } kfree(tmp); } return err; } =20 -static int ovl_parse_param_upperdir(const char *name, struct fs_context *f= c, - bool workdir) +static int ovl_mount_dir_check(struct fs_context *fc, const struct path *p= ath, + enum ovl_opt layer, const char *name, bool upper) { - int err; - struct ovl_fs *ofs =3D fc->s_fs_info; - struct ovl_config *config =3D &ofs->config; - struct ovl_fs_context *ctx =3D fc->fs_private; - struct path path; - char *dup; + if (ovl_dentry_weird(path->dentry)) + return invalfc(fc, "filesystem on %s not supported", name); =20 - err =3D ovl_mount_dir(name, &path, true); - if (err) - return err; + if (!d_is_dir(path->dentry)) + return invalfc(fc, "%s is not a directory", name); =20 /* * Check whether upper path is read-only here to report failures * early. Don't forget to recheck when the superblock is created * as the mount attributes could change. */ - if (__mnt_is_readonly(path.mnt)) { - path_put(&path); - return -EINVAL; + if (upper) { + if (path->dentry->d_flags & DCACHE_OP_REAL) + return invalfc(fc, "filesystem on %s not supported as upperdir", name); + if (__mnt_is_readonly(path->mnt)) + return invalfc(fc, "filesystem on %s is read-only", name); } + return 0; +} =20 - dup =3D kstrdup(name, GFP_KERNEL); - if (!dup) { - path_put(&path); - return -ENOMEM; - } +static void ovl_add_layer(struct fs_context *fc, enum ovl_opt layer, + struct path *path, char **pname) +{ + struct ovl_fs *ofs =3D fc->s_fs_info; + struct ovl_config *config =3D &ofs->config; + struct ovl_fs_context *ctx =3D fc->fs_private; =20 - if (workdir) { - kfree(config->workdir); - config->workdir =3D dup; - path_put(&ctx->work); - ctx->work =3D path; - } else { - kfree(config->upperdir); - config->upperdir =3D dup; - path_put(&ctx->upper); - ctx->upper =3D path; + switch (layer) { + case Opt_workdir: + swap(config->workdir, *pname); + swap(ctx->work, *path); + break; + case Opt_upperdir: + swap(config->upperdir, *pname); + swap(ctx->upper, *path); + break; + default: + WARN_ON(1); } - return 0; +} + +static int ovl_parse_layer(struct fs_context *fc, struct fs_parameter *par= am, + enum ovl_opt layer) +{ + char *name =3D kstrdup(param->string, GFP_KERNEL); + bool upper =3D (layer =3D=3D Opt_upperdir || layer =3D=3D Opt_workdir); + struct path path; + int err; + + if (!name) + return -ENOMEM; + + err =3D ovl_mount_dir(name, &path); + if (err) + goto out_free; + + err =3D ovl_mount_dir_check(fc, &path, layer, name, upper); + if (err) + goto out_put; + + /* Store the user provided path string in ctx to show in mountinfo */ + ovl_add_layer(fc, layer, &path, &name); + +out_put: + path_put(&path); +out_free: + kfree(name); + return err; } =20 static void ovl_reset_lowerdirs(struct ovl_fs_context *ctx) @@ -417,7 +428,11 @@ static int ovl_parse_param_lowerdir(const char *name, = struct fs_context *fc) for (nr =3D 0; nr < nr_lower; nr++, l++) { memset(l, 0, sizeof(*l)); =20 - err =3D ovl_mount_dir(iter, &l->path, false); + err =3D ovl_mount_dir(iter, &l->path); + if (err) + goto out_put; + + err =3D ovl_mount_dir_check(fc, &l->path, Opt_lowerdir, iter, false); if (err) goto out_put; =20 @@ -505,10 +520,8 @@ static int ovl_parse_param(struct fs_context *fc, stru= ct fs_parameter *param) err =3D ovl_parse_param_lowerdir(param->string, fc); break; case Opt_upperdir: - fallthrough; case Opt_workdir: - err =3D ovl_parse_param_upperdir(param->string, fc, - (Opt_workdir =3D=3D opt)); + err =3D ovl_parse_layer(fc, param, opt); break; case Opt_default_permissions: config->default_permissions =3D true; --=20 2.43.0