From patchwork Tue Oct 10 20:28:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416030 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63F88CD8CB4 for ; Tue, 10 Oct 2023 20:28:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234432AbjJJU2g (ORCPT ); Tue, 10 Oct 2023 16:28:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39022 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234416AbjJJU2f (ORCPT ); Tue, 10 Oct 2023 16:28:35 -0400 Received: from mail-yw1-x112a.google.com (mail-yw1-x112a.google.com [IPv6:2607:f8b0:4864:20::112a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4230BB7 for ; Tue, 10 Oct 2023 13:28:34 -0700 (PDT) Received: by mail-yw1-x112a.google.com with SMTP id 00721157ae682-5a7be88e9ccso14417567b3.2 for ; Tue, 10 Oct 2023 13:28:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696969713; x=1697574513; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=3boZB9d4DR1nvDBWFnnLLUoFhwVH07qcVUA45H8uCsg=; b=ThPFwvADrA/fCQJXs2758GmXvl5a9w/TsN/BsymWfhUTCxr8QzjJHxZO3AAZWdaglj LNhhDLm3qzSSLARg3QNRDIdQL7erJZH72Jtx+EBXun/4yEaVGCG5ReeiR3kIVL44JYBa oB9F0lcsQnpQu5JOzlWWLugjk+kyYczI+TiJcyYmflwXeDHOw2Y5/dSXPwwzinhsSNsv UNmu1YaC08TMdU+A4ujtqq93KlpreMPtiBr7BF674xbbHqirrXw6oPfq5yNqhro4ma2D UanEI1mkUMB+77LU/Qx6rZwQjE5FHBv2pPaCPEpwBLIMGXe9CEqYIfZxwPjbbMdG/0Ki PiQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696969713; x=1697574513; 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=3boZB9d4DR1nvDBWFnnLLUoFhwVH07qcVUA45H8uCsg=; b=UtaWwDEJjI2CYknyNRlOg6g8+xxrts8tTcb3kImHjzyk+G+si3wx9IblpS0ep4JC8K u7fJnzOMJKTyzdIL6xUraGVYiR16Mv0P19ZGkZAuqrtL87livdYUgnLAvEErCXPM3U5S JrbXuogCMYX9ladrxmp0vP2RJ9fEn2wuaah3vSlpst3I7wKXBReuRhZsKDaiRIGp1JuB Q4MsSkQy7JkiONdpT2xHyRQ6i8lRP/Qi94aBnvIJuKmwwmuDbWbYxSb6z7RYNl9H6OEt NnbehtbpWs7F1h83ySeBgSgf9AP/EkHnvqHbYKiyv98wkgF/ezodlPAKw0QWT1saOQx6 nlgA== X-Gm-Message-State: AOJu0YybIb0MHYam6n5I1uZrifLBLUe8XWsww7RtNLpOZFVkioa5guBz PjvXQevzCGm6ZJFkfhVc/XNcDlfy1RlxWhEvSyDXYg== X-Google-Smtp-Source: AGHT+IG7jQhqlxU0Q1LAQQ1xorocUwBGC3Sc6EeLZa5qqlAfcZ33gM0Uv+m4vcjPEZIyFJMbgxtabA== X-Received: by 2002:a0d:cbd7:0:b0:5a7:d9e6:8fc6 with SMTP id n206-20020a0dcbd7000000b005a7d9e68fc6mr769596ywd.39.1696969713291; Tue, 10 Oct 2023 13:28:33 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id l21-20020a81ad15000000b005a20ab8a184sm919602ywh.31.2023.10.10.13.28.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:28:32 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org Cc: Sweet Tea Dorminy Subject: [PATCH 3/8] btrfs-progs: start tracking extent encryption context info Date: Tue, 10 Oct 2023 16:28:20 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Sweet Tea Dorminy This recapitulates the kernel change named 'btrfs: start tracking extent encryption context info". Signed-off-by: Sweet Tea Dorminy --- kernel-shared/accessors.h | 48 ++++++++++++++++++++++++ kernel-shared/tree-checker.c | 66 ++++++++++++++++++++++++++++----- kernel-shared/uapi/btrfs_tree.h | 23 +++++++++++- 3 files changed, 127 insertions(+), 10 deletions(-) diff --git a/kernel-shared/accessors.h b/kernel-shared/accessors.h index 539c20d0..04c0093c 100644 --- a/kernel-shared/accessors.h +++ b/kernel-shared/accessors.h @@ -932,6 +932,10 @@ BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block, BTRFS_SETGET_STACK_FUNCS(super_nr_global_roots, struct btrfs_super_block, nr_global_roots, 64); +/* struct btrfs_file_extent_encryption_info */ +BTRFS_SETGET_FUNCS(encryption_info_size, struct btrfs_encryption_info, size, + 32); + /* struct btrfs_file_extent_item */ BTRFS_SETGET_STACK_FUNCS(stack_file_extent_type, struct btrfs_file_extent_item, type, 8); @@ -970,6 +974,50 @@ BTRFS_SETGET_FUNCS(file_extent_encryption, struct btrfs_file_extent_item, BTRFS_SETGET_FUNCS(file_extent_other_encoding, struct btrfs_file_extent_item, other_encoding, 16); +static inline struct btrfs_encryption_info *btrfs_file_extent_encryption_info( + const struct btrfs_file_extent_item *ei) +{ + unsigned long offset = (unsigned long)ei; + + offset += offsetof(struct btrfs_file_extent_item, encryption_info); + return (struct btrfs_encryption_info *)offset; +} + +static inline unsigned long btrfs_file_extent_encryption_ctx_offset( + const struct btrfs_file_extent_item *ei) +{ + unsigned long offset = (unsigned long)ei; + + offset += offsetof(struct btrfs_file_extent_item, encryption_info); + return offset + offsetof(struct btrfs_encryption_info, context); +} + +static inline u32 btrfs_file_extent_encryption_ctx_size( + const struct extent_buffer *eb, + const struct btrfs_file_extent_item *ei) +{ + return btrfs_encryption_info_size(eb, + btrfs_file_extent_encryption_info(ei)); +} + +static inline void btrfs_set_file_extent_encryption_ctx_size( + const struct extent_buffer *eb, + struct btrfs_file_extent_item *ei, + u32 val) +{ + btrfs_set_encryption_info_size(eb, + btrfs_file_extent_encryption_info(ei), + val); +} + +static inline u32 btrfs_file_extent_encryption_info_size( + const struct extent_buffer *eb, + const struct btrfs_file_extent_item *ei) +{ + return btrfs_encryption_info_size(eb, + btrfs_file_extent_encryption_info(ei)); +} + /* btrfs_qgroup_status_item */ BTRFS_SETGET_FUNCS(qgroup_status_generation, struct btrfs_qgroup_status_item, generation, 64); diff --git a/kernel-shared/tree-checker.c b/kernel-shared/tree-checker.c index 10797589..282f9ba6 100644 --- a/kernel-shared/tree-checker.c +++ b/kernel-shared/tree-checker.c @@ -229,6 +229,8 @@ static int check_extent_data_item(struct extent_buffer *leaf, u32 sectorsize = fs_info->sectorsize; u32 item_size = btrfs_item_size(leaf, slot); u64 extent_end; + u8 policy; + u8 fe_type; if (unlikely(!IS_ALIGNED(key->offset, sectorsize))) { file_extent_err(leaf, slot, @@ -259,12 +261,12 @@ static int check_extent_data_item(struct extent_buffer *leaf, SZ_4K); return -EUCLEAN; } - if (unlikely(btrfs_file_extent_type(leaf, fi) >= - BTRFS_NR_FILE_EXTENT_TYPES)) { + + fe_type = btrfs_file_extent_type(leaf, fi); + if (unlikely(fe_type >= BTRFS_NR_FILE_EXTENT_TYPES)) { file_extent_err(leaf, slot, "invalid type for file extent, have %u expect range [0, %u]", - btrfs_file_extent_type(leaf, fi), - BTRFS_NR_FILE_EXTENT_TYPES - 1); + fe_type, BTRFS_NR_FILE_EXTENT_TYPES - 1); return -EUCLEAN; } @@ -286,6 +288,13 @@ static int check_extent_data_item(struct extent_buffer *leaf, btrfs_file_extent_encryption(leaf, fi)); return -EUCLEAN; } + policy = btrfs_file_extent_encryption(leaf, fi); + if (unlikely(policy >= BTRFS_NR_ENCRYPTION_TYPES)) { + file_extent_err(leaf, slot, + "invalid encryption for file extent, have %u expect range [0, %u]", + policy, BTRFS_NR_ENCRYPTION_TYPES - 1); + return -EUCLEAN; + } if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) { /* Inline extent must have 0 as key offset */ if (unlikely(key->offset)) { @@ -312,12 +321,51 @@ static int check_extent_data_item(struct extent_buffer *leaf, return 0; } - /* Regular or preallocated extent has fixed item size */ - if (unlikely(item_size != sizeof(*fi))) { - file_extent_err(leaf, slot, + if (policy == BTRFS_ENCRYPTION_FSCRYPT) { + size_t fe_size = sizeof(*fi) + + sizeof(struct btrfs_encryption_info); + u32 ctxsize; + + if (unlikely(item_size < fe_size)) { + file_extent_err(leaf, slot, + "invalid item size for encrypted file extent, have %u expect = %zu + size of u32", + item_size, sizeof(*fi)); + return -EUCLEAN; + } + + ctxsize = btrfs_file_extent_encryption_info_size(leaf, fi); + if (unlikely(item_size != (fe_size + ctxsize))) { + file_extent_err(leaf, slot, + "invalid item size for encrypted file extent, have %u expect = %zu + context of size %u", + item_size, fe_size, ctxsize); + return -EUCLEAN; + } + + if (unlikely(ctxsize > BTRFS_MAX_EXTENT_CTX_SIZE)) { + file_extent_err(leaf, slot, + "invalid file extent context size, have %u expect a maximum of %u", + ctxsize, BTRFS_MAX_EXTENT_CTX_SIZE); + return -EUCLEAN; + } + + /* + * Only regular and prealloc extents should have an encryption + * context. + */ + if (unlikely(fe_type != BTRFS_FILE_EXTENT_REG && + fe_type != BTRFS_FILE_EXTENT_PREALLOC)) { + file_extent_err(leaf, slot, + "invalid type for encrypted file extent, have %u", + btrfs_file_extent_type(leaf, fi)); + return -EUCLEAN; + } + } else { + if (unlikely(item_size != sizeof(*fi))) { + file_extent_err(leaf, slot, "invalid item size for reg/prealloc file extent, have %u expect %zu", - item_size, sizeof(*fi)); - return -EUCLEAN; + item_size, sizeof(*fi)); + return -EUCLEAN; + } } if (unlikely(CHECK_FE_ALIGNED(leaf, slot, fi, ram_bytes, sectorsize) || CHECK_FE_ALIGNED(leaf, slot, fi, disk_bytenr, sectorsize) || diff --git a/kernel-shared/uapi/btrfs_tree.h b/kernel-shared/uapi/btrfs_tree.h index ad555e70..f49ae534 100644 --- a/kernel-shared/uapi/btrfs_tree.h +++ b/kernel-shared/uapi/btrfs_tree.h @@ -1016,6 +1016,24 @@ enum { BTRFS_NR_FILE_EXTENT_TYPES = 3, }; +/* + * Currently just the FSCRYPT_SET_CONTEXT_MAX_SIZE, which is larger than the + * current extent context size from fscrypt, so this should give us plenty of + * breathing room for expansion later. + */ +#define BTRFS_MAX_EXTENT_CTX_SIZE 40 + +enum { + BTRFS_ENCRYPTION_NONE, + BTRFS_ENCRYPTION_FSCRYPT, + BTRFS_NR_ENCRYPTION_TYPES, +}; + +struct btrfs_encryption_info { + __le32 size; + __u8 context[0]; +}; + struct btrfs_file_extent_item { /* * transaction id that created this extent @@ -1065,7 +1083,10 @@ struct btrfs_file_extent_item { * always reflects the size uncompressed and without encoding. */ __le64 num_bytes; - + /* + * the encryption info, if any + */ + struct btrfs_encryption_info encryption_info[0]; } __attribute__ ((__packed__)); struct btrfs_csum_item {