From patchwork Wed Oct 16 08:41:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Thumshirn X-Patchwork-Id: 11192663 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C33C91390 for ; Wed, 16 Oct 2019 08:42:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A540121925 for ; Wed, 16 Oct 2019 08:42:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727453AbfJPImG (ORCPT ); Wed, 16 Oct 2019 04:42:06 -0400 Received: from mx2.suse.de ([195.135.220.15]:48260 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2404143AbfJPImD (ORCPT ); Wed, 16 Oct 2019 04:42:03 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 2FA7DAD73 for ; Wed, 16 Oct 2019 08:42:01 +0000 (UTC) From: Johannes Thumshirn To: Linux BTRFS Mailinglist Cc: Johannes Thumshirn Subject: [RFC PATCH 1/4] btrfs-progs: pass in fs_info to btrfs_csum_data Date: Wed, 16 Oct 2019 10:41:55 +0200 Message-Id: <20191016084158.7573-1-jthumshirn@suse.de> X-Mailer: git-send-email 2.16.4 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org For passing authentication keys to the checksumming functions we need a container for the key. Pass in a btrfs_fs_info to btrfs_csum_data() so we can use the fs_info as a container for the authentication key. Note this is not always possible for all callers of btrfs_csum_data() so we're just passing in NULL if it is not directly possible. Functions calling btrfs_csum_data() with a NULL fs_info argument are currently not supported in the context of an authenticated file-system. Signed-off-by: Johannes Thumshirn --- btrfs-sb-mod.c | 4 ++-- check/main.c | 2 +- cmds/inspect-dump-super.c | 2 +- cmds/rescue-chunk-recover.c | 2 +- convert/common.c | 2 +- disk-io.c | 16 +++++++++------- disk-io.h | 3 ++- file-item.c | 2 +- 8 files changed, 18 insertions(+), 15 deletions(-) diff --git a/btrfs-sb-mod.c b/btrfs-sb-mod.c index ad143ca05aa6..537002687da6 100644 --- a/btrfs-sb-mod.c +++ b/btrfs-sb-mod.c @@ -36,7 +36,7 @@ static int check_csum_superblock(void *sb) u8 result[BTRFS_CSUM_SIZE]; u16 csum_type = btrfs_super_csum_type(sb); - btrfs_csum_data(csum_type, (unsigned char *)sb + BTRFS_CSUM_SIZE, + btrfs_csum_data(NULL, csum_type, (unsigned char *)sb + BTRFS_CSUM_SIZE, result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); return !memcmp(sb, result, csum_size); @@ -48,7 +48,7 @@ static void update_block_csum(void *block) struct btrfs_header *hdr; u16 csum_type = btrfs_super_csum_type(block); - btrfs_csum_data(csum_type, (unsigned char *)block + BTRFS_CSUM_SIZE, + btrfs_csum_data(NULL, csum_type, (unsigned char *)block + BTRFS_CSUM_SIZE, result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); memset(block, 0, BTRFS_CSUM_SIZE); diff --git a/check/main.c b/check/main.c index fd05430c1f51..d009f33e9657 100644 --- a/check/main.c +++ b/check/main.c @@ -5659,7 +5659,7 @@ static int check_extent_csums(struct btrfs_root *root, u64 bytenr, while (data_checked < read_len) { tmp = offset + data_checked; - btrfs_csum_data(csum_type, data + tmp, + btrfs_csum_data(fs_info, csum_type, data + tmp, result, fs_info->sectorsize); csum_offset = leaf_offset + diff --git a/cmds/inspect-dump-super.c b/cmds/inspect-dump-super.c index fc06488dde32..1a2ef4d4822c 100644 --- a/cmds/inspect-dump-super.c +++ b/cmds/inspect-dump-super.c @@ -39,7 +39,7 @@ static int check_csum_sblock(void *sb, int csum_size, u16 csum_type) { u8 result[BTRFS_CSUM_SIZE]; - btrfs_csum_data(csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, + btrfs_csum_data(NULL, csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); return !memcmp(sb, result, csum_size); diff --git a/cmds/rescue-chunk-recover.c b/cmds/rescue-chunk-recover.c index bf35693ddbfa..0896cea674ab 100644 --- a/cmds/rescue-chunk-recover.c +++ b/cmds/rescue-chunk-recover.c @@ -1908,7 +1908,7 @@ static int check_one_csum(int fd, u64 start, u32 len, u32 tree_csum, } ret = 0; put_unaligned_le32(tree_csum, expected_csum); - btrfs_csum_data(csum_type, (u8 *)data, result, len); + btrfs_csum_data(NULL, csum_type, (u8 *)data, result, len); if (memcmp(result, expected_csum, csum_size) != 0) ret = 1; out: diff --git a/convert/common.c b/convert/common.c index 3cb2d9d44881..54ed52b592e6 100644 --- a/convert/common.c +++ b/convert/common.c @@ -66,7 +66,7 @@ static inline int write_temp_super(int fd, struct btrfs_super_block *sb, u16 csum_type = btrfs_super_csum_type(sb); int ret; - btrfs_csum_data(csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, + btrfs_csum_data(NULL, csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); memcpy(&sb->csum[0], result, BTRFS_CSUM_SIZE); ret = pwrite(fd, sb, BTRFS_SUPER_INFO_SIZE, sb_bytenr); diff --git a/disk-io.c b/disk-io.c index a9744af90a43..e68f28e72077 100644 --- a/disk-io.c +++ b/disk-io.c @@ -139,7 +139,8 @@ static void print_tree_block_error(struct btrfs_fs_info *fs_info, } } -int btrfs_csum_data(u16 csum_type, const u8 *data, u8 *out, size_t len) +int btrfs_csum_data(struct btrfs_fs_info *fs_info, u16 csum_type, + const u8 *data, u8 *out, size_t len) { memset(out, 0, BTRFS_CSUM_SIZE); @@ -167,7 +168,8 @@ static int __csum_tree_block_size(struct extent_buffer *buf, u16 csum_size, u32 len; len = buf->len - BTRFS_CSUM_SIZE; - btrfs_csum_data(csum_type, (u8 *)buf->data + BTRFS_CSUM_SIZE, + btrfs_csum_data(buf->fs_info, csum_type, + (u8 *)buf->data + BTRFS_CSUM_SIZE, result, len); if (verify) { @@ -1386,7 +1388,7 @@ int btrfs_check_super(struct btrfs_super_block *sb, unsigned sbflags) } csum_size = btrfs_super_csum_size(sb); - btrfs_csum_data(csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, + btrfs_csum_data(NULL, csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); if (memcmp(result, sb->csum, csum_size)) { @@ -1640,8 +1642,8 @@ static int write_dev_supers(struct btrfs_fs_info *fs_info, } if (fs_info->super_bytenr != BTRFS_SUPER_INFO_OFFSET) { btrfs_set_super_bytenr(sb, fs_info->super_bytenr); - btrfs_csum_data(csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, result, - BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); + btrfs_csum_data(fs_info, csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, + result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); memcpy(&sb->csum[0], result, BTRFS_CSUM_SIZE); /* @@ -1675,8 +1677,8 @@ static int write_dev_supers(struct btrfs_fs_info *fs_info, btrfs_set_super_bytenr(sb, bytenr); - btrfs_csum_data(csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, result, - BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); + btrfs_csum_data(fs_info, csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, + result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); memcpy(&sb->csum[0], result, BTRFS_CSUM_SIZE); /* diff --git a/disk-io.h b/disk-io.h index 545cacda9a79..bb093ae69d57 100644 --- a/disk-io.h +++ b/disk-io.h @@ -186,7 +186,8 @@ int btrfs_free_fs_root(struct btrfs_root *root); void btrfs_mark_buffer_dirty(struct extent_buffer *buf); int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid); int btrfs_set_buffer_uptodate(struct extent_buffer *buf); -int btrfs_csum_data(u16 csum_type, const u8 *data, u8 *out, size_t len); +int btrfs_csum_data(struct btrfs_fs_info *fs_info, u16 csum_type, + const u8 *data, u8 *out, size_t len); int btrfs_open_device(struct btrfs_device *dev); int csum_tree_block_size(struct extent_buffer *buf, u16 csum_sectorsize, diff --git a/file-item.c b/file-item.c index 64af57693baf..fb84fbd6d54f 100644 --- a/file-item.c +++ b/file-item.c @@ -315,7 +315,7 @@ csum: item = (struct btrfs_csum_item *)((unsigned char *)item + csum_offset * csum_size); found: - btrfs_csum_data(csum_type, (u8 *)data, csum_result, len); + btrfs_csum_data(root->fs_info, csum_type, (u8 *)data, csum_result, len); /* FIXME: does not make sense for non-crc32c */ if (csum_result == 0) { printk("csum result is 0 for block %llu\n", From patchwork Wed Oct 16 08:41:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Thumshirn X-Patchwork-Id: 11192665 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E14A417E6 for ; Wed, 16 Oct 2019 08:42:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CCE5921A49 for ; Wed, 16 Oct 2019 08:42:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391810AbfJPImG (ORCPT ); Wed, 16 Oct 2019 04:42:06 -0400 Received: from mx2.suse.de ([195.135.220.15]:48262 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2404144AbfJPImE (ORCPT ); Wed, 16 Oct 2019 04:42:04 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 3E718AD7B for ; Wed, 16 Oct 2019 08:42:01 +0000 (UTC) From: Johannes Thumshirn To: Linux BTRFS Mailinglist Cc: Johannes Thumshirn Subject: [RFC PATCH 2/4] btrfs-progs: add auth_key argument to open_ctree_fs_info Date: Wed, 16 Oct 2019 10:41:56 +0200 Message-Id: <20191016084158.7573-2-jthumshirn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20191016084158.7573-1-jthumshirn@suse.de> References: <20191016084158.7573-1-jthumshirn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Add auth_key argument to open_ctree_fs_info() so we have the key once we create a new fs_info. XXX: Remove as much auth_key = NULL callers as possible. Signed-off-by: Johannes Thumshirn --- btrfs-find-root.c | 2 +- check/main.c | 2 +- cmds/filesystem.c | 2 +- cmds/inspect-dump-tree.c | 2 +- cmds/rescue-chunk-recover.c | 2 +- cmds/rescue.c | 2 +- cmds/restore.c | 2 +- disk-io.c | 16 +++++++++------- disk-io.h | 5 +++-- image/main.c | 5 +++-- mkfs/main.c | 3 ++- 11 files changed, 24 insertions(+), 19 deletions(-) diff --git a/btrfs-find-root.c b/btrfs-find-root.c index 741eb9a95ac5..4cde76d82bde 100644 --- a/btrfs-find-root.c +++ b/btrfs-find-root.c @@ -202,7 +202,7 @@ int main(int argc, char **argv) fs_info = open_ctree_fs_info(argv[optind], 0, 0, 0, OPEN_CTREE_CHUNK_ROOT_ONLY | - OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR); + OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR, NULL); if (!fs_info) { error("open ctree failed"); return 1; diff --git a/check/main.c b/check/main.c index d009f33e9657..65af60cac7f2 100644 --- a/check/main.c +++ b/check/main.c @@ -10021,7 +10021,7 @@ static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv) ctree_flags |= OPEN_CTREE_PARTIAL; info = open_ctree_fs_info(argv[optind], bytenr, tree_root_bytenr, - chunk_root_bytenr, ctree_flags); + chunk_root_bytenr, ctree_flags, NULL); if (!info) { error("cannot open file system"); ret = -EIO; diff --git a/cmds/filesystem.c b/cmds/filesystem.c index 4f22089abeaa..e9b7a287424f 100644 --- a/cmds/filesystem.c +++ b/cmds/filesystem.c @@ -585,7 +585,7 @@ static int map_seed_devices(struct list_head *all_uuids) * open_ctree_* detects seed/sprout mapping */ fs_info = open_ctree_fs_info(device->name, 0, 0, 0, - OPEN_CTREE_PARTIAL); + OPEN_CTREE_PARTIAL, NULL); if (!fs_info) continue; diff --git a/cmds/inspect-dump-tree.c b/cmds/inspect-dump-tree.c index e5efe2470111..56a85625e2c1 100644 --- a/cmds/inspect-dump-tree.c +++ b/cmds/inspect-dump-tree.c @@ -454,7 +454,7 @@ static int cmd_inspect_dump_tree(const struct cmd_struct *cmd, printf("%s\n", PACKAGE_STRING); - info = open_ctree_fs_info(argv[optind], 0, 0, 0, open_ctree_flags); + info = open_ctree_fs_info(argv[optind], 0, 0, 0, open_ctree_flags, NULL); if (!info) { error("unable to open %s", argv[optind]); goto out; diff --git a/cmds/rescue-chunk-recover.c b/cmds/rescue-chunk-recover.c index 0896cea674ab..720881d9b93a 100644 --- a/cmds/rescue-chunk-recover.c +++ b/cmds/rescue-chunk-recover.c @@ -1439,7 +1439,7 @@ open_ctree_with_broken_chunk(struct recover_control *rc) u64 features; int ret; - fs_info = btrfs_new_fs_info(1, BTRFS_SUPER_INFO_OFFSET); + fs_info = btrfs_new_fs_info(1, BTRFS_SUPER_INFO_OFFSET, NULL); if (!fs_info) { fprintf(stderr, "Failed to allocate memory for fs_info\n"); return ERR_PTR(-ENOMEM); diff --git a/cmds/rescue.c b/cmds/rescue.c index e8eab6808bc3..90a7efa4f196 100644 --- a/cmds/rescue.c +++ b/cmds/rescue.c @@ -241,7 +241,7 @@ static int cmd_rescue_fix_device_size(const struct cmd_struct *cmd, } fs_info = open_ctree_fs_info(devname, 0, 0, 0, OPEN_CTREE_WRITES | - OPEN_CTREE_PARTIAL); + OPEN_CTREE_PARTIAL, NULL); if (!fs_info) { error("could not open btrfs"); ret = -EIO; diff --git a/cmds/restore.c b/cmds/restore.c index c104b01aef69..d7f011c6d352 100644 --- a/cmds/restore.c +++ b/cmds/restore.c @@ -1290,7 +1290,7 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, */ fs_info = open_ctree_fs_info(dev, bytenr, root_location, 0, OPEN_CTREE_PARTIAL | - OPEN_CTREE_NO_BLOCK_GROUPS); + OPEN_CTREE_NO_BLOCK_GROUPS, NULL); if (fs_info) break; fprintf(stderr, "Could not open root, trying backup super\n"); diff --git a/disk-io.c b/disk-io.c index e68f28e72077..5de6daf1563a 100644 --- a/disk-io.c +++ b/disk-io.c @@ -769,7 +769,8 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info) free(fs_info); } -struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr) +struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr, + char *auth_key) { struct btrfs_fs_info *fs_info; @@ -1165,7 +1166,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr, u64 root_tree_bytenr, u64 chunk_root_bytenr, - unsigned flags) + unsigned flags, char *auth_key) { struct btrfs_fs_info *fs_info; struct btrfs_super_block *disk_super; @@ -1182,7 +1183,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, if (posix_fadvise(fp, 0, 0, POSIX_FADV_DONTNEED)) fprintf(stderr, "Warning, could not drop caches\n"); - fs_info = btrfs_new_fs_info(flags & OPEN_CTREE_WRITES, sb_bytenr); + fs_info = btrfs_new_fs_info(flags & OPEN_CTREE_WRITES, sb_bytenr, + auth_key); if (!fs_info) { fprintf(stderr, "Failed to allocate memory for fs_info\n"); return NULL; @@ -1292,7 +1294,7 @@ out: struct btrfs_fs_info *open_ctree_fs_info(const char *filename, u64 sb_bytenr, u64 root_tree_bytenr, u64 chunk_root_bytenr, - unsigned flags) + unsigned flags, char *auth_key) { int fp; int ret; @@ -1319,7 +1321,7 @@ struct btrfs_fs_info *open_ctree_fs_info(const char *filename, return NULL; } info = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, - chunk_root_bytenr, flags); + chunk_root_bytenr, flags, auth_key); close(fp); return info; } @@ -1331,7 +1333,7 @@ struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, /* This flags may not return fs_info with any valid root */ BUG_ON(flags & OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR); - info = open_ctree_fs_info(filename, sb_bytenr, 0, 0, flags); + info = open_ctree_fs_info(filename, sb_bytenr, 0, 0, flags, NULL); if (!info) return NULL; if (flags & __OPEN_CTREE_RETURN_CHUNK_ROOT) @@ -1350,7 +1352,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, (unsigned long long)flags); return NULL; } - info = __open_ctree_fd(fp, path, sb_bytenr, 0, 0, flags); + info = __open_ctree_fd(fp, path, sb_bytenr, 0, 0, flags, NULL); if (!info) return NULL; if (flags & __OPEN_CTREE_RETURN_CHUNK_ROOT) diff --git a/disk-io.h b/disk-io.h index bb093ae69d57..237b8df28d47 100644 --- a/disk-io.h +++ b/disk-io.h @@ -140,7 +140,8 @@ void btrfs_setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info, int clean_tree_block(struct extent_buffer *buf); void btrfs_free_fs_info(struct btrfs_fs_info *fs_info); -struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr); +struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr, + char *auth_key); int btrfs_check_fs_compatibility(struct btrfs_super_block *sb, unsigned int flags); int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr, @@ -160,7 +161,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, struct btrfs_fs_info *open_ctree_fs_info(const char *filename, u64 sb_bytenr, u64 root_tree_bytenr, u64 chunk_root_bytenr, - unsigned flags); + unsigned flags, char *auth_key); int close_ctree_fs_info(struct btrfs_fs_info *fs_info); static inline int close_ctree(struct btrfs_root *root) { diff --git a/image/main.c b/image/main.c index b87525412543..5663fe83ff0b 100644 --- a/image/main.c +++ b/image/main.c @@ -2383,7 +2383,8 @@ static int restore_metadump(const char *input, FILE *out, int old_restore, info = open_ctree_fs_info(target, 0, 0, 0, OPEN_CTREE_WRITES | OPEN_CTREE_RESTORE | - OPEN_CTREE_PARTIAL); + OPEN_CTREE_PARTIAL, + NULL); if (!info) { error("open ctree failed"); ret = -EIO; @@ -2745,7 +2746,7 @@ int BOX_MAIN(image)(int argc, char *argv[]) info = open_ctree_fs_info(target, 0, 0, 0, OPEN_CTREE_PARTIAL | - OPEN_CTREE_RESTORE); + OPEN_CTREE_RESTORE, NULL); if (!info) { error("open ctree failed at %s", target); return 1; diff --git a/mkfs/main.c b/mkfs/main.c index 1a4578412b41..aca104a4bd57 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -1217,7 +1217,8 @@ int BOX_MAIN(mkfs)(int argc, char **argv) } fs_info = open_ctree_fs_info(file, 0, 0, 0, - OPEN_CTREE_WRITES | OPEN_CTREE_TEMPORARY_SUPER); + OPEN_CTREE_WRITES | OPEN_CTREE_TEMPORARY_SUPER, + auth_key); if (!fs_info) { error("open ctree failed"); goto error; From patchwork Wed Oct 16 08:41:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Thumshirn X-Patchwork-Id: 11192661 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 13C4B15AB for ; Wed, 16 Oct 2019 08:42:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EA6F521925 for ; Wed, 16 Oct 2019 08:42:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391794AbfJPImF (ORCPT ); Wed, 16 Oct 2019 04:42:05 -0400 Received: from mx2.suse.de ([195.135.220.15]:48268 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2404145AbfJPImE (ORCPT ); Wed, 16 Oct 2019 04:42:04 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 47222ADAB for ; Wed, 16 Oct 2019 08:42:01 +0000 (UTC) From: Johannes Thumshirn To: Linux BTRFS Mailinglist Cc: Johannes Thumshirn Subject: [RFC PATCH 3/4] btrfs-progs: Add HMAC(SHA256) support Date: Wed, 16 Oct 2019 10:41:57 +0200 Message-Id: <20191016084158.7573-3-jthumshirn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20191016084158.7573-1-jthumshirn@suse.de> References: <20191016084158.7573-1-jthumshirn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Add support for authenticated file systems using HMAC(SHA256) as checksumming algorithm. Example: mkfs.btrfs --csum hmac-sha256 --auth-key 0123456789 -f test.img Not-yet-signed-off-by: Johannes Thumshirn --- Makefile.inc.in | 2 +- cmds/inspect-dump-super.c | 5 ++++- configure.ac | 7 +++++++ crypto/hash.c | 16 ++++++++++++++++ crypto/hash.h | 2 ++ ctree.c | 1 + ctree.h | 3 +++ disk-io.c | 9 ++++++++- mkfs/common.c | 10 ++++++++++ mkfs/common.h | 3 +++ mkfs/main.c | 25 ++++++++++++++++++++++++- 11 files changed, 79 insertions(+), 4 deletions(-) diff --git a/Makefile.inc.in b/Makefile.inc.in index a86c528ed0a5..34191fa0a381 100644 --- a/Makefile.inc.in +++ b/Makefile.inc.in @@ -25,7 +25,7 @@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ SUBST_CFLAGS = @CFLAGS@ SUBST_LDFLAGS = @LDFLAGS@ -LIBS_BASE = @UUID_LIBS@ @BLKID_LIBS@ -L. -pthread +LIBS_BASE = @UUID_LIBS@ @BLKID_LIBS@ @LIBGCRYPT_LIBS@ -L. -pthread LIBS_COMP = @ZLIB_LIBS@ @LZO2_LIBS@ @ZSTD_LIBS@ LIBS_PYTHON = @PYTHON_LIBS@ STATIC_LIBS_BASE = @UUID_LIBS_STATIC@ @BLKID_LIBS_STATIC@ -L. -pthread diff --git a/cmds/inspect-dump-super.c b/cmds/inspect-dump-super.c index 1a2ef4d4822c..5bf5a6bc6f27 100644 --- a/cmds/inspect-dump-super.c +++ b/cmds/inspect-dump-super.c @@ -318,6 +318,7 @@ static bool is_valid_csum_type(u16 csum_type) case BTRFS_CSUM_TYPE_XXHASH: case BTRFS_CSUM_TYPE_SHA256: case BTRFS_CSUM_TYPE_BLAKE2: + case BTRFS_CSUM_TYPE_HMAC_SHA256: return true; default: return false; @@ -351,7 +352,9 @@ static void dump_superblock(struct btrfs_super_block *sb, int full) printf("csum\t\t\t0x"); for (i = 0, p = sb->csum; i < csum_size; i++) printf("%02x", p[i]); - if (!is_valid_csum_type(csum_type)) + if (csum_type == BTRFS_CSUM_TYPE_HMAC_SHA256) + printf(" [NO KEY FOR HMAC]"); + else if (!is_valid_csum_type(csum_type)) printf(" [UNKNOWN CSUM TYPE OR SIZE]"); else if (check_csum_sblock(sb, csum_size, csum_type)) printf(" [match]"); diff --git a/configure.ac b/configure.ac index cf792eb5488b..32b3f41e70d9 100644 --- a/configure.ac +++ b/configure.ac @@ -267,6 +267,13 @@ AC_SUBST([LZO2_LIBS]) AC_SUBST([LZO2_LIBS_STATIC]) AC_SUBST([LZO2_CFLAGS]) +dnl gcrypt library for HMAC(SHA256) +AM_PATH_LIBGCRYPT([1.0.0], [ + AC_SUBST(LIBGCRYPT_LIBS) + AC_SUBST(LIBGCRYPT_CFLAGS) + ], [ + AC_MSG_ERROR([cannot find gcrypt library]) +]) dnl library stuff AC_SUBST([LIBBTRFS_MAJOR]) diff --git a/crypto/hash.c b/crypto/hash.c index 48623c798739..c507a007d4d6 100644 --- a/crypto/hash.c +++ b/crypto/hash.c @@ -1,3 +1,7 @@ +#include + +#include "ctree.h" + #include "crypto/hash.h" #include "crypto/crc32c.h" #include "crypto/xxhash.h" @@ -49,3 +53,15 @@ int hash_blake2b(const u8 *buf, size_t len, u8 *out) return 0; } + +int hash_hmac_sha256(struct btrfs_fs_info *fs_info, const u8 *buf, + size_t length, u8 *out) +{ + gcry_mac_hd_t mac; + gcry_mac_open(&mac, GCRY_MAC_HMAC_SHA256, 0, NULL); + gcry_mac_setkey(mac, fs_info->auth_key, strlen(fs_info->auth_key)); + gcry_mac_write(mac, buf, length); + gcry_mac_read(mac, out, &length); + + return 0; +} diff --git a/crypto/hash.h b/crypto/hash.h index fefccbd59a09..252ce9f94f72 100644 --- a/crypto/hash.h +++ b/crypto/hash.h @@ -9,5 +9,7 @@ int hash_crc32c(const u8 *buf, size_t length, u8 *out); int hash_xxhash(const u8 *buf, size_t length, u8 *out); int hash_sha256(const u8 *buf, size_t length, u8 *out); int hash_blake2b(const u8 *buf, size_t length, u8 *out); +int hash_hmac_sha256(struct btrfs_fs_info *fs_info, const u8 *buf, + size_t length, u8 *out); #endif diff --git a/ctree.c b/ctree.c index 97b44d48dc85..a22ad0bfe3fd 100644 --- a/ctree.c +++ b/ctree.c @@ -46,6 +46,7 @@ static const struct btrfs_csum { [BTRFS_CSUM_TYPE_XXHASH] = { 8, "xxhash64" }, [BTRFS_CSUM_TYPE_SHA256] = { 32, "sha256" }, [BTRFS_CSUM_TYPE_BLAKE2] = { 32, "blake2" }, + [BTRFS_CSUM_TYPE_HMAC_SHA256] = { 32, "hmac-sha256" }, }; u16 btrfs_super_csum_size(const struct btrfs_super_block *sb) diff --git a/ctree.h b/ctree.h index b99ba11279ad..bb64d54c5894 100644 --- a/ctree.h +++ b/ctree.h @@ -170,6 +170,7 @@ enum btrfs_csum_type { BTRFS_CSUM_TYPE_XXHASH = 1, BTRFS_CSUM_TYPE_SHA256 = 2, BTRFS_CSUM_TYPE_BLAKE2 = 3, + BTRFS_CSUM_TYPE_HMAC_SHA256 = 32, // XXX dummy value for now }; #define BTRFS_EMPTY_DIR_SIZE 0 @@ -1190,6 +1191,8 @@ struct btrfs_fs_info { u32 nodesize; u32 sectorsize; u32 stripesize; + + char *auth_key; }; /* diff --git a/disk-io.c b/disk-io.c index 5de6daf1563a..ef43521d0dcf 100644 --- a/disk-io.c +++ b/disk-io.c @@ -153,6 +153,12 @@ int btrfs_csum_data(struct btrfs_fs_info *fs_info, u16 csum_type, return hash_sha256(data, len, out); case BTRFS_CSUM_TYPE_BLAKE2: return hash_blake2b(data, len, out); + case BTRFS_CSUM_TYPE_HMAC_SHA256: + if (!fs_info || !fs_info->auth_key) { + fprintf(stderr, "ERROR: no key for HMAC(SHA256)\n"); + return 0; + } + return hash_hmac_sha256(fs_info, data, len, out); default: fprintf(stderr, "ERROR: unknown csum type: %d\n", csum_type); ASSERT(0); @@ -817,6 +823,7 @@ struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr, fs_info->data_alloc_profile = (u64)-1; fs_info->metadata_alloc_profile = (u64)-1; fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; + fs_info->auth_key = auth_key; return fs_info; free_all: btrfs_free_fs_info(fs_info); @@ -1393,7 +1400,7 @@ int btrfs_check_super(struct btrfs_super_block *sb, unsigned sbflags) btrfs_csum_data(NULL, csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); - if (memcmp(result, sb->csum, csum_size)) { + if (memcmp(result, sb->csum, csum_size) && csum_type != BTRFS_CSUM_TYPE_HMAC_SHA256) { error("superblock checksum mismatch"); return -EIO; } diff --git a/mkfs/common.c b/mkfs/common.c index 469b88d6a8d3..81d0b5c12a52 100644 --- a/mkfs/common.c +++ b/mkfs/common.c @@ -160,6 +160,13 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg) if (!buf) return -ENOMEM; + buf->fs_info = calloc(1, sizeof(struct btrfs_fs_info)); + if (!buf->fs_info) { + free(buf); + return -ENOMEM; + } + + first_free = BTRFS_SUPER_INFO_OFFSET + cfg->sectorsize * 2 - 1; first_free &= ~((u64)cfg->sectorsize - 1); @@ -224,6 +231,8 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg) btrfs_header_chunk_tree_uuid(buf), BTRFS_UUID_SIZE); + buf->fs_info->auth_key = cfg->auth_key; + ret = btrfs_create_tree_root(fd, cfg, buf); if (ret < 0) goto out; @@ -474,6 +483,7 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg) ret = 0; out: + free(buf->fs_info); free(buf); return ret; } diff --git a/mkfs/common.h b/mkfs/common.h index 1ca71a4fcce5..161221d849ec 100644 --- a/mkfs/common.h +++ b/mkfs/common.h @@ -65,6 +65,9 @@ struct btrfs_mkfs_config { /* Superblock offset after make_btrfs */ u64 super_bytenr; + + /* authentication key */ + char *auth_key; }; int make_btrfs(int fd, struct btrfs_mkfs_config *cfg); diff --git a/mkfs/main.c b/mkfs/main.c index aca104a4bd57..5ba57c923359 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -343,6 +343,7 @@ static void print_usage(int ret) printf(" features:\n"); printf("\t--csum TYPE\n"); printf("\t--checksum TYPE checksum algorithm to use (default: crc32c)\n"); + printf("\t--auth-key KEY authentication key to use for authenticated file-systems\n"); printf("\t-n|--nodesize SIZE size of btree nodes\n"); printf("\t-s|--sectorsize SIZE data block size (may not be mountable by current kernel)\n"); printf("\t-O|--features LIST comma separated list of filesystem features (use '-O list-all' to list features)\n"); @@ -400,6 +401,9 @@ static enum btrfs_csum_type parse_csum_type(const char *s) } else if (strcasecmp(s, "blake2b") == 0 || strcasecmp(s, "blake2") == 0) { return BTRFS_CSUM_TYPE_BLAKE2; + } else if (strcasecmp(s, "hmac-sha256") == 0 || + strcasecmp(s, "hmac(sha256)") == 0) { + return BTRFS_CSUM_TYPE_HMAC_SHA256; } else { error("unknown csum type %s", s); exit(1); @@ -855,14 +859,21 @@ int BOX_MAIN(mkfs)(int argc, char **argv) struct mkfs_allocation allocation = { 0 }; struct btrfs_mkfs_config mkfs_cfg; enum btrfs_csum_type csum_type = BTRFS_CSUM_TYPE_CRC32; + char *auth_key = NULL; crc32c_optimization_init(); while(1) { int c; - enum { GETOPT_VAL_SHRINK = 257, GETOPT_VAL_CHECKSUM }; + enum { + GETOPT_VAL_SHRINK = 257, + GETOPT_VAL_CHECKSUM, + GETOPT_VAL_AUTHKEY, + }; static const struct option long_options[] = { { "alloc-start", required_argument, NULL, 'A'}, + { "auth-key", required_argument, NULL, + GETOPT_VAL_AUTHKEY }, { "byte-count", required_argument, NULL, 'b' }, { "csum", required_argument, NULL, GETOPT_VAL_CHECKSUM }, @@ -968,6 +979,9 @@ int BOX_MAIN(mkfs)(int argc, char **argv) case GETOPT_VAL_CHECKSUM: csum_type = parse_csum_type(optarg); break; + case GETOPT_VAL_AUTHKEY: + auth_key = strdup(optarg); + break; case GETOPT_VAL_HELP: default: print_usage(c != GETOPT_VAL_HELP); @@ -995,6 +1009,12 @@ int BOX_MAIN(mkfs)(int argc, char **argv) goto error; } + if ((auth_key && csum_type != BTRFS_CSUM_TYPE_HMAC_SHA256) || + (csum_type == BTRFS_CSUM_TYPE_HMAC_SHA256 && !auth_key)) { + error("the option --auth-key must be used with --csum hmac(sha256)"); + goto error; + } + if (*fs_uuid) { uuid_t dummy_uuid; @@ -1208,6 +1228,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv) mkfs_cfg.stripesize = stripesize; mkfs_cfg.features = features; mkfs_cfg.csum_type = csum_type; + mkfs_cfg.auth_key = auth_key; ret = make_btrfs(fd, &mkfs_cfg); if (ret) { @@ -1424,6 +1445,7 @@ out: btrfs_close_all_devices(); free(label); + free(auth_key); return !!ret; error: @@ -1431,6 +1453,7 @@ error: close(fd); free(label); + free(auth_key); exit(1); success: exit(0); From patchwork Wed Oct 16 08:41:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Thumshirn X-Patchwork-Id: 11192659 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3604D15AB for ; Wed, 16 Oct 2019 08:42:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1FB1621925 for ; Wed, 16 Oct 2019 08:42:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391741AbfJPImE (ORCPT ); Wed, 16 Oct 2019 04:42:04 -0400 Received: from mx2.suse.de ([195.135.220.15]:48272 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2404146AbfJPImD (ORCPT ); Wed, 16 Oct 2019 04:42:03 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 569D1AD7F for ; Wed, 16 Oct 2019 08:42:01 +0000 (UTC) From: Johannes Thumshirn To: Linux BTRFS Mailinglist Cc: Johannes Thumshirn Subject: [RFC PATCH 4/4] btrfs-progs: add --auth-key to dump-super Date: Wed, 16 Oct 2019 10:41:58 +0200 Message-Id: <20191016084158.7573-4-jthumshirn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20191016084158.7573-1-jthumshirn@suse.de> References: <20191016084158.7573-1-jthumshirn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Add auth-key option for btrfs inspect-internal dump-super so we can dump an authenticated super-block and check for it's integrity. Signed-off-by: Johannes Thumshirn --- cmds/inspect-dump-super.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/cmds/inspect-dump-super.c b/cmds/inspect-dump-super.c index 5bf5a6bc6f27..ad81ba9f9ea2 100644 --- a/cmds/inspect-dump-super.c +++ b/cmds/inspect-dump-super.c @@ -35,11 +35,13 @@ #include "crypto/crc32c.h" #include "common/help.h" -static int check_csum_sblock(void *sb, int csum_size, u16 csum_type) +static int check_csum_sblock(void *sb, int csum_size, u16 csum_type, + char *auth_key) { + struct btrfs_fs_info dummy_fs_info = { .auth_key = auth_key }; u8 result[BTRFS_CSUM_SIZE]; - btrfs_csum_data(NULL, csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, + btrfs_csum_data(&dummy_fs_info, csum_type, (u8 *)sb + BTRFS_CSUM_SIZE, result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); return !memcmp(sb, result, csum_size); @@ -325,7 +327,8 @@ static bool is_valid_csum_type(u16 csum_type) } } -static void dump_superblock(struct btrfs_super_block *sb, int full) +static void dump_superblock(struct btrfs_super_block *sb, int full, + char *auth_key) { int i; char *s, buf[BTRFS_UUID_UNPARSED_SIZE]; @@ -352,11 +355,11 @@ static void dump_superblock(struct btrfs_super_block *sb, int full) printf("csum\t\t\t0x"); for (i = 0, p = sb->csum; i < csum_size; i++) printf("%02x", p[i]); - if (csum_type == BTRFS_CSUM_TYPE_HMAC_SHA256) + if (csum_type == BTRFS_CSUM_TYPE_HMAC_SHA256 && !auth_key) printf(" [NO KEY FOR HMAC]"); else if (!is_valid_csum_type(csum_type)) printf(" [UNKNOWN CSUM TYPE OR SIZE]"); - else if (check_csum_sblock(sb, csum_size, csum_type)) + else if (check_csum_sblock(sb, csum_size, csum_type, auth_key)) printf(" [match]"); else printf(" [DON'T MATCH]"); @@ -484,7 +487,7 @@ static void dump_superblock(struct btrfs_super_block *sb, int full) } static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full, - int force) + int force, char *auth_key) { u8 super_block_data[BTRFS_SUPER_INFO_SIZE]; struct btrfs_super_block *sb; @@ -509,7 +512,7 @@ static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full, error("bad magic on superblock on %s at %llu", filename, (unsigned long long)sb_bytenr); } else { - dump_superblock(sb, full); + dump_superblock(sb, full, auth_key); } return 0; } @@ -523,6 +526,7 @@ static const char * const cmd_inspect_dump_super_usage[] = { "-s|--super specify which copy to print out (values: 0, 1, 2)", "-F|--force attempt to dump superblocks with bad magic", "--bytenr specify alternate superblock offset", + "--auth-key specify authentication key for authenticated file-system", "", "Deprecated syntax:", "-s specify alternate superblock offset, values other than 0, 1, 2", @@ -545,16 +549,19 @@ static int cmd_inspect_dump_super(const struct cmd_struct *cmd, int ret = 0; u64 arg; u64 sb_bytenr = btrfs_sb_offset(0); + char *auth_key = NULL; while (1) { int c; - enum { GETOPT_VAL_BYTENR = 257 }; + enum { GETOPT_VAL_BYTENR = 257, GETOPT_VAL_AUTHKEY, }; static const struct option long_options[] = { {"all", no_argument, NULL, 'a'}, {"bytenr", required_argument, NULL, GETOPT_VAL_BYTENR }, {"full", no_argument, NULL, 'f'}, {"force", no_argument, NULL, 'F'}, {"super", required_argument, NULL, 's' }, + {"auth-key", required_argument, NULL, + GETOPT_VAL_AUTHKEY }, {NULL, 0, NULL, 0} }; @@ -601,13 +608,16 @@ static int cmd_inspect_dump_super(const struct cmd_struct *cmd, sb_bytenr = arg; all = 0; break; + case GETOPT_VAL_AUTHKEY: + auth_key = strdup(optarg); + break; default: usage_unknown_option(cmd, argv); } } if (check_argc_min(argc - optind, 1)) - return 1; + goto out; for (i = optind; i < argc; i++) { filename = argv[i]; @@ -624,7 +634,8 @@ static int cmd_inspect_dump_super(const struct cmd_struct *cmd, for (idx = 0; idx < BTRFS_SUPER_MIRROR_MAX; idx++) { sb_bytenr = btrfs_sb_offset(idx); if (load_and_dump_sb(filename, fd, - sb_bytenr, full, force)) { + sb_bytenr, full, force, + auth_key)) { close(fd); ret = 1; goto out; @@ -633,13 +644,15 @@ static int cmd_inspect_dump_super(const struct cmd_struct *cmd, putchar('\n'); } } else { - load_and_dump_sb(filename, fd, sb_bytenr, full, force); + load_and_dump_sb(filename, fd, sb_bytenr, full, force, + auth_key); putchar('\n'); } close(fd); } out: + free(auth_key); return ret; } DEFINE_SIMPLE_COMMAND(inspect_dump_super, "dump-super");