From patchwork Wed May 3 08:51:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Larsson X-Patchwork-Id: 13229880 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 D8D50746A for ; Wed, 3 May 2023 08:52:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683103923; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XcZpe9ed/2DgEtdKmYSxZXm5GbtnSqwudyk8sYUYNa8=; b=MN0swA+GnJsSgzE3ccngM5yOmq40umICY18SmAZuER3u2BaG6j+1VTd30vvotAE95mY1So CF60Hu0+ydymVIKt577ixVoa3dvMYzuLu9IAn4HRNeHYbVtNahawf8jMNQ25bmBrScdZ50 cgd0E4rSySgXIYDxiVkOQ18ZeWPmMyA= Received: from mail-lf1-f70.google.com (mail-lf1-f70.google.com [209.85.167.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-126-slH5fSj5P5GKDgPv4ShqBA-1; Wed, 03 May 2023 04:52:02 -0400 X-MC-Unique: slH5fSj5P5GKDgPv4ShqBA-1 Received: by mail-lf1-f70.google.com with SMTP id 2adb3069b0e04-4edc7406cb5so3092296e87.3 for ; Wed, 03 May 2023 01:52:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683103920; x=1685695920; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XcZpe9ed/2DgEtdKmYSxZXm5GbtnSqwudyk8sYUYNa8=; b=IFVPqcox9TTOPcYVs93nuSWMAIRlV0wDXM2kAZvZOfupfhYqLP42V6Cr+Xe/eLP5zm D0WDvPZVZ5uuCW4fOhFAe/zbkmfE7Es0DfA4QsjDFpgoX4lS0ehv17RvvQ9coc4fpoW1 V0ItfuO0ComMRBDOlBeWRQO73bBwQdD6YoV4eMcjpRyd9E9iVRJlB1L4SEolm9QmPphG O4Ow0QqD5Iz2DDniMmR0B1k2FxXwDzWQot0kLbSaqrNN9jXPAWPHhDxrw8Jjv37OpQoE ifWyVGqGRnUyf3f8tzaZPfJVjJ+oORXm8I/CQC8UBXhqTTyQlX6J7fuSsrUAfYV4Bv69 FPdA== X-Gm-Message-State: AC+VfDwFIOlb8+oY1gi9NEaV9yZL9/RSPT8h3XWMkYQscO1SXUWtMbif yiuF5CYgn/ju8pPUkWT6umIBSgSe3iiBDuzXYwjQ2yo9gI6OuZTlj/rtXj7I35ak+d/dHEp3BjQ yQi42Wv7KUIq07n9g87J/9l6rBKs= X-Received: by 2002:ac2:50d9:0:b0:4e7:4a3c:697 with SMTP id h25-20020ac250d9000000b004e74a3c0697mr782105lfm.38.1683103920542; Wed, 03 May 2023 01:52:00 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ55En8e7OtdlbEsGEP0e/C2sTHWVsKpOrmye9Vk8xtDyMKlu69mVOHIlm0te4cEtTwOBD45lg== X-Received: by 2002:ac2:50d9:0:b0:4e7:4a3c:697 with SMTP id h25-20020ac250d9000000b004e74a3c0697mr782098lfm.38.1683103920355; Wed, 03 May 2023 01:52:00 -0700 (PDT) Received: from localhost.localdomain (c-e6a5e255.022-110-73746f36.bbcust.telenor.se. [85.226.165.230]) by smtp.googlemail.com with ESMTPSA id j6-20020ac24546000000b004ed4fa5f20fsm5907089lfm.25.2023.05.03.01.51.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 May 2023 01:51:59 -0700 (PDT) From: Alexander Larsson To: miklos@szeredi.hu Cc: linux-unionfs@vger.kernel.org, amir73il@gmail.com, ebiggers@kernel.org, tytso@mit.edu, fsverity@lists.linux.dev, Alexander Larsson Subject: [PATCH v2 6/6] ovl: Handle verity during copy-up Date: Wed, 3 May 2023 10:51:39 +0200 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: fsverity@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com During regular metacopy, if lowerdata file has fs-verity enabled, set the new overlay.verity xattr (if enabled). During real data copy up, remove any old overlay.verity xattr. If verity is required, and lowerdata does not have fs-verity enabled, fall back to full copy-up (or the generated metacopy would not validate). Signed-off-by: Alexander Larsson Reviewed-by: Amir Goldstein --- fs/overlayfs/copy_up.c | 31 +++++++++++++++++++++++++++++++ fs/overlayfs/overlayfs.h | 3 +++ fs/overlayfs/util.c | 39 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index eb266fb68730..e25bdc2baef3 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "overlayfs.h" #define OVL_COPY_UP_CHUNK_SIZE (1 << 20) @@ -644,6 +645,18 @@ static int ovl_copy_up_metadata(struct ovl_copy_up_ctx *c, struct dentry *temp) if (c->metacopy) { err = ovl_check_setxattr(ofs, temp, OVL_XATTR_METACOPY, NULL, 0, -EOPNOTSUPP); + + /* Copy the verity digest if any so we can validate the copy-up later */ + if (!err) { + struct path lowerdatapath; + + ovl_path_lowerdata(c->dentry, &lowerdatapath); + if (WARN_ON_ONCE(lowerdatapath.dentry == NULL)) + err = -EIO; + else + err = ovl_set_verity_xattr_from(ofs, temp, &lowerdatapath); + } + if (err) return err; } @@ -919,6 +932,19 @@ static bool ovl_need_meta_copy_up(struct dentry *dentry, umode_t mode, if (flags && ((OPEN_FMODE(flags) & FMODE_WRITE) || (flags & O_TRUNC))) return false; + /* Fall back to full copy if no fsverity on source data and we require verity */ + if (ofs->config.require_verity) { + struct path lowerdata; + + ovl_path_lowerdata(dentry, &lowerdata); + + if (WARN_ON_ONCE(lowerdata.dentry == NULL) || + ovl_ensure_verity_loaded(&lowerdata) || + !fsverity_get_info(d_inode(lowerdata.dentry))) { + return false; + } + } + return true; } @@ -985,6 +1011,11 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c) if (err) goto out_free; + err = ovl_removexattr(ofs, upperpath.dentry, OVL_XATTR_VERITY); + if (err && err != -ENODATA) + goto out_free; + + err = 0; ovl_set_upperdata(d_inode(c->dentry)); out_free: kfree(capability); diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 07475eaae2ca..1cc3c8df3a4d 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -464,11 +464,14 @@ int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir); int ovl_check_metacopy_xattr(struct ovl_fs *ofs, const struct path *path); bool ovl_is_metacopy_dentry(struct dentry *dentry); char *ovl_get_redirect_xattr(struct ovl_fs *ofs, const struct path *path, int padding); +int ovl_ensure_verity_loaded(struct path *path); int ovl_get_verity_xattr(struct ovl_fs *ofs, const struct path *path, u8 *digest_buf, int *buf_length); int ovl_validate_verity(struct ovl_fs *ofs, struct path *metapath, struct path *datapath); +int ovl_set_verity_xattr_from(struct ovl_fs *ofs, struct dentry *dst, + struct path *src); int ovl_sync_status(struct ovl_fs *ofs); static inline void ovl_set_flag(unsigned long flag, struct inode *inode) diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index ee296614bd73..733871775b80 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -1188,7 +1188,7 @@ int ovl_get_verity_xattr(struct ovl_fs *ofs, const struct path *path, } /* Call with mounter creds as it may open the file */ -static int ovl_ensure_verity_loaded(struct path *datapath) +int ovl_ensure_verity_loaded(struct path *datapath) { struct inode *inode = d_inode(datapath->dentry); const struct fsverity_info *vi; @@ -1262,6 +1262,43 @@ int ovl_validate_verity(struct ovl_fs *ofs, return 0; } +int ovl_set_verity_xattr_from(struct ovl_fs *ofs, struct dentry *dst, + struct path *src) +{ + int err; + u8 src_digest[1+FS_VERITY_MAX_DIGEST_SIZE]; + enum hash_algo verity_algo; + + if (!ofs->config.verity || !S_ISREG(d_inode(dst)->i_mode)) + return 0; + + err = -EIO; + if (src) { + err = ovl_ensure_verity_loaded(src); + if (err < 0) { + pr_warn_ratelimited("lower file '%pd' failed to load fs-verity info\n", + src->dentry); + return -EIO; + } + + err = fsverity_get_digest(d_inode(src->dentry), src_digest + 1, &verity_algo); + } + if (err == -ENODATA) { + if (ofs->config.require_verity) { + pr_warn_ratelimited("lower file '%pd' has no fs-verity digest\n", + src->dentry); + return -EIO; + } + return 0; + } + if (err < 0) + return err; + + src_digest[0] = (u8)verity_algo; + return ovl_check_setxattr(ofs, dst, OVL_XATTR_VERITY, + src_digest, 1 + hash_digest_size[verity_algo], -EOPNOTSUPP); +} + /* * ovl_sync_status() - Check fs sync status for volatile mounts *