From 269f61d63e9a7c78fc1b3efcd6a636a6271e1c56 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 Jan 2023 17:57:12 +0100 Subject: [PATCH] 5.15-stable patches added patches: btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch efi-random-combine-bootloader-provided-rng-seed-with-rng-protocol-output.patch mbcache-avoid-nesting-of-cache-c_list_lock-under-bit-locks.patch net-hns3-fix-return-value-check-bug-of-rx-copybreak.patch --- ...-block-check-to-also-verify-checksum.patch | 117 ++++++++++++ ...ed-rng-seed-with-rng-protocol-output.patch | 180 ++++++++++++++++++ ...of-cache-c_list_lock-under-bit-locks.patch | 66 +++++++ ...turn-value-check-bug-of-rx-copybreak.patch | 36 ++++ queue-5.15/series | 4 + 5 files changed, 403 insertions(+) create mode 100644 queue-5.15/btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch create mode 100644 queue-5.15/efi-random-combine-bootloader-provided-rng-seed-with-rng-protocol-output.patch create mode 100644 queue-5.15/mbcache-avoid-nesting-of-cache-c_list_lock-under-bit-locks.patch create mode 100644 queue-5.15/net-hns3-fix-return-value-check-bug-of-rx-copybreak.patch diff --git a/queue-5.15/btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch b/queue-5.15/btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch new file mode 100644 index 00000000000..cdb6facbca7 --- /dev/null +++ b/queue-5.15/btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch @@ -0,0 +1,117 @@ +From 3d17adea74a56a4965f7a603d8ed8c66bb9356d9 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Tue, 18 Oct 2022 09:56:38 +0800 +Subject: btrfs: make thaw time super block check to also verify checksum + +From: Qu Wenruo + +commit 3d17adea74a56a4965f7a603d8ed8c66bb9356d9 upstream. + +Previous commit a05d3c915314 ("btrfs: check superblock to ensure the fs +was not modified at thaw time") only checks the content of the super +block, but it doesn't really check if the on-disk super block has a +matching checksum. + +This patch will add the checksum verification to thaw time superblock +verification. + +This involves the following extra changes: + +- Export btrfs_check_super_csum() + As we need to call it in super.c. + +- Change the argument list of btrfs_check_super_csum() + Instead of passing a char *, directly pass struct btrfs_super_block * + pointer. + +- Verify that our checksum type didn't change before checking the + checksum value, like it's done at mount time + +Fixes: a05d3c915314 ("btrfs: check superblock to ensure the fs was not modified at thaw time") +Reviewed-by: Johannes Thumshirn +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/disk-io.c | 10 ++++------ + fs/btrfs/disk-io.h | 2 ++ + fs/btrfs/super.c | 16 ++++++++++++++++ + 3 files changed, 22 insertions(+), 6 deletions(-) + +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -202,11 +202,9 @@ static bool btrfs_supported_super_csum(u + * Return 0 if the superblock checksum type matches the checksum value of that + * algorithm. Pass the raw disk superblock data. + */ +-static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info, +- char *raw_disk_sb) ++int btrfs_check_super_csum(struct btrfs_fs_info *fs_info, ++ const struct btrfs_super_block *disk_sb) + { +- struct btrfs_super_block *disk_sb = +- (struct btrfs_super_block *)raw_disk_sb; + char result[BTRFS_CSUM_SIZE]; + SHASH_DESC_ON_STACK(shash, fs_info->csum_shash); + +@@ -217,7 +215,7 @@ static int btrfs_check_super_csum(struct + * BTRFS_SUPER_INFO_SIZE range, we expect that the unused space is + * filled with zeros and is included in the checksum. + */ +- crypto_shash_digest(shash, raw_disk_sb + BTRFS_CSUM_SIZE, ++ crypto_shash_digest(shash, (const u8 *)disk_sb + BTRFS_CSUM_SIZE, + BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE, result); + + if (memcmp(disk_sb->csum, result, fs_info->csum_size)) +@@ -3210,7 +3208,7 @@ int __cold open_ctree(struct super_block + * We want to check superblock checksum, the type is stored inside. + * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k). + */ +- if (btrfs_check_super_csum(fs_info, (u8 *)disk_super)) { ++ if (btrfs_check_super_csum(fs_info, disk_super)) { + btrfs_err(fs_info, "superblock checksum mismatch"); + err = -EINVAL; + btrfs_release_disk_super(disk_super); +--- a/fs/btrfs/disk-io.h ++++ b/fs/btrfs/disk-io.h +@@ -52,6 +52,8 @@ struct extent_buffer *btrfs_find_create_ + void btrfs_clean_tree_block(struct extent_buffer *buf); + void btrfs_clear_oneshot_options(struct btrfs_fs_info *fs_info); + int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info); ++int btrfs_check_super_csum(struct btrfs_fs_info *fs_info, ++ const struct btrfs_super_block *disk_sb); + int __cold open_ctree(struct super_block *sb, + struct btrfs_fs_devices *fs_devices, + char *options); +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -2501,6 +2501,7 @@ static int check_dev_super(struct btrfs_ + { + struct btrfs_fs_info *fs_info = dev->fs_info; + struct btrfs_super_block *sb; ++ u16 csum_type; + int ret = 0; + + /* This should be called with fs still frozen. */ +@@ -2515,6 +2516,21 @@ static int check_dev_super(struct btrfs_ + if (IS_ERR(sb)) + return PTR_ERR(sb); + ++ /* Verify the checksum. */ ++ csum_type = btrfs_super_csum_type(sb); ++ if (csum_type != btrfs_super_csum_type(fs_info->super_copy)) { ++ btrfs_err(fs_info, "csum type changed, has %u expect %u", ++ csum_type, btrfs_super_csum_type(fs_info->super_copy)); ++ ret = -EUCLEAN; ++ goto out; ++ } ++ ++ if (btrfs_check_super_csum(fs_info, sb)) { ++ btrfs_err(fs_info, "csum for on-disk super block no longer matches"); ++ ret = -EUCLEAN; ++ goto out; ++ } ++ + /* Btrfs_validate_super() includes fsid check against super->fsid. */ + ret = btrfs_validate_super(fs_info, sb, 0); + if (ret < 0) diff --git a/queue-5.15/efi-random-combine-bootloader-provided-rng-seed-with-rng-protocol-output.patch b/queue-5.15/efi-random-combine-bootloader-provided-rng-seed-with-rng-protocol-output.patch new file mode 100644 index 00000000000..3d72b36180b --- /dev/null +++ b/queue-5.15/efi-random-combine-bootloader-provided-rng-seed-with-rng-protocol-output.patch @@ -0,0 +1,180 @@ +From 196dff2712ca5a2e651977bb2fe6b05474111a83 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Thu, 20 Oct 2022 10:39:10 +0200 +Subject: efi: random: combine bootloader provided RNG seed with RNG protocol output + +From: Ard Biesheuvel + +commit 196dff2712ca5a2e651977bb2fe6b05474111a83 upstream. + +Instead of blindly creating the EFI random seed configuration table if +the RNG protocol is implemented and works, check whether such a EFI +configuration table was provided by an earlier boot stage and if so, +concatenate the existing and the new seeds, leaving it up to the core +code to mix it in and credit it the way it sees fit. + +This can be used for, e.g., systemd-boot, to pass an additional seed to +Linux in a way that can be consumed by the kernel very early. In that +case, the following definitions should be used to pass the seed to the +EFI stub: + +struct linux_efi_random_seed { + u32 size; // of the 'seed' array in bytes + u8 seed[]; +}; + +The memory for the struct must be allocated as EFI_ACPI_RECLAIM_MEMORY +pool memory, and the address of the struct in memory should be installed +as a EFI configuration table using the following GUID: + +LINUX_EFI_RANDOM_SEED_TABLE_GUID 1ce1e5bc-7ceb-42f2-81e5-8aadf180f57b + +Note that doing so is safe even on kernels that were built without this +patch applied, but the seed will simply be overwritten with a seed +derived from the EFI RNG protocol, if available. The recommended seed +size is 32 bytes, and seeds larger than 512 bytes are considered +corrupted and ignored entirely. + +In order to preserve forward secrecy, seeds from previous bootloaders +are memzero'd out, and in order to preserve memory, those older seeds +are also freed from memory. Freeing from memory without first memzeroing +is not safe to do, as it's possible that nothing else will ever +overwrite those pages used by EFI. + +Reviewed-by: Jason A. Donenfeld +[ardb: incorporate Jason's followup changes to extend the maximum seed + size on the consumer end, memzero() it and drop a needless printk] +Signed-off-by: Ard Biesheuvel +Signed-off-by: Jason A. Donenfeld +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firmware/efi/efi.c | 4 +-- + drivers/firmware/efi/libstub/efistub.h | 2 + + drivers/firmware/efi/libstub/random.c | 42 ++++++++++++++++++++++++++++----- + include/linux/efi.h | 2 - + 4 files changed, 40 insertions(+), 10 deletions(-) + +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -590,7 +590,7 @@ int __init efi_config_parse_tables(const + + seed = early_memremap(efi_rng_seed, sizeof(*seed)); + if (seed != NULL) { +- size = min(seed->size, EFI_RANDOM_SEED_SIZE); ++ size = min_t(u32, seed->size, SZ_1K); // sanity check + early_memunmap(seed, sizeof(*seed)); + } else { + pr_err("Could not map UEFI random seed!\n"); +@@ -599,8 +599,8 @@ int __init efi_config_parse_tables(const + seed = early_memremap(efi_rng_seed, + sizeof(*seed) + size); + if (seed != NULL) { +- pr_notice("seeding entropy pool\n"); + add_bootloader_randomness(seed->bits, size); ++ memzero_explicit(seed->bits, size); + early_memunmap(seed, sizeof(*seed) + size); + } else { + pr_err("Could not map UEFI random seed!\n"); +--- a/drivers/firmware/efi/libstub/efistub.h ++++ b/drivers/firmware/efi/libstub/efistub.h +@@ -766,6 +766,8 @@ efi_status_t efi_get_random_bytes(unsign + efi_status_t efi_random_alloc(unsigned long size, unsigned long align, + unsigned long *addr, unsigned long random_seed); + ++efi_status_t efi_random_get_seed(void); ++ + efi_status_t check_platform_features(void); + + void *get_efi_config_table(efi_guid_t guid); +--- a/drivers/firmware/efi/libstub/random.c ++++ b/drivers/firmware/efi/libstub/random.c +@@ -67,8 +67,9 @@ efi_status_t efi_random_get_seed(void) + efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID; + efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW; + efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID; ++ struct linux_efi_random_seed *prev_seed, *seed = NULL; ++ int prev_seed_size = 0, seed_size = EFI_RANDOM_SEED_SIZE; + efi_rng_protocol_t *rng = NULL; +- struct linux_efi_random_seed *seed = NULL; + efi_status_t status; + + status = efi_bs_call(locate_protocol, &rng_proto, NULL, (void **)&rng); +@@ -76,18 +77,33 @@ efi_status_t efi_random_get_seed(void) + return status; + + /* ++ * Check whether a seed was provided by a prior boot stage. In that ++ * case, instead of overwriting it, let's create a new buffer that can ++ * hold both, and concatenate the existing and the new seeds. ++ * Note that we should read the seed size with caution, in case the ++ * table got corrupted in memory somehow. ++ */ ++ prev_seed = get_efi_config_table(LINUX_EFI_RANDOM_SEED_TABLE_GUID); ++ if (prev_seed && prev_seed->size <= 512U) { ++ prev_seed_size = prev_seed->size; ++ seed_size += prev_seed_size; ++ } ++ ++ /* + * Use EFI_ACPI_RECLAIM_MEMORY here so that it is guaranteed that the + * allocation will survive a kexec reboot (although we refresh the seed + * beforehand) + */ + status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY, +- sizeof(*seed) + EFI_RANDOM_SEED_SIZE, ++ struct_size(seed, bits, seed_size), + (void **)&seed); +- if (status != EFI_SUCCESS) +- return status; ++ if (status != EFI_SUCCESS) { ++ efi_warn("Failed to allocate memory for RNG seed.\n"); ++ goto err_warn; ++ } + + status = efi_call_proto(rng, get_rng, &rng_algo_raw, +- EFI_RANDOM_SEED_SIZE, seed->bits); ++ EFI_RANDOM_SEED_SIZE, seed->bits); + + if (status == EFI_UNSUPPORTED) + /* +@@ -100,14 +116,28 @@ efi_status_t efi_random_get_seed(void) + if (status != EFI_SUCCESS) + goto err_freepool; + +- seed->size = EFI_RANDOM_SEED_SIZE; ++ seed->size = seed_size; ++ if (prev_seed_size) ++ memcpy(seed->bits + EFI_RANDOM_SEED_SIZE, prev_seed->bits, ++ prev_seed_size); ++ + status = efi_bs_call(install_configuration_table, &rng_table_guid, seed); + if (status != EFI_SUCCESS) + goto err_freepool; + ++ if (prev_seed_size) { ++ /* wipe and free the old seed if we managed to install the new one */ ++ memzero_explicit(prev_seed->bits, prev_seed_size); ++ efi_bs_call(free_pool, prev_seed); ++ } + return EFI_SUCCESS; + + err_freepool: ++ memzero_explicit(seed, struct_size(seed, bits, seed_size)); + efi_bs_call(free_pool, seed); ++ efi_warn("Failed to obtain seed from EFI_RNG_PROTOCOL\n"); ++err_warn: ++ if (prev_seed) ++ efi_warn("Retaining bootloader-supplied seed only"); + return status; + } +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -1114,8 +1114,6 @@ void efi_check_for_embedded_firmwares(vo + static inline void efi_check_for_embedded_firmwares(void) { } + #endif + +-efi_status_t efi_random_get_seed(void); +- + /* + * Arch code can implement the following three template macros, avoiding + * reptition for the void/non-void return cases of {__,}efi_call_virt(): diff --git a/queue-5.15/mbcache-avoid-nesting-of-cache-c_list_lock-under-bit-locks.patch b/queue-5.15/mbcache-avoid-nesting-of-cache-c_list_lock-under-bit-locks.patch new file mode 100644 index 00000000000..f69506fe620 --- /dev/null +++ b/queue-5.15/mbcache-avoid-nesting-of-cache-c_list_lock-under-bit-locks.patch @@ -0,0 +1,66 @@ +From 5fc4cbd9fde5d4630494fd6ffc884148fb618087 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Sep 2022 11:10:32 +0200 +Subject: mbcache: Avoid nesting of cache->c_list_lock under bit locks + +From: Jan Kara + +commit 5fc4cbd9fde5d4630494fd6ffc884148fb618087 upstream. + +Commit 307af6c87937 ("mbcache: automatically delete entries from cache +on freeing") started nesting cache->c_list_lock under the bit locks +protecting hash buckets of the mbcache hash table in +mb_cache_entry_create(). This causes problems for real-time kernels +because there spinlocks are sleeping locks while bitlocks stay atomic. +Luckily the nesting is easy to avoid by holding entry reference until +the entry is added to the LRU list. This makes sure we cannot race with +entry deletion. + +Cc: stable@kernel.org +Fixes: 307af6c87937 ("mbcache: automatically delete entries from cache on freeing") +Reported-by: Mike Galbraith +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20220908091032.10513-1-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/mbcache.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/fs/mbcache.c ++++ b/fs/mbcache.c +@@ -90,8 +90,14 @@ int mb_cache_entry_create(struct mb_cach + return -ENOMEM; + + INIT_LIST_HEAD(&entry->e_list); +- /* Initial hash reference */ +- atomic_set(&entry->e_refcnt, 1); ++ /* ++ * We create entry with two references. One reference is kept by the ++ * hash table, the other reference is used to protect us from ++ * mb_cache_entry_delete_or_get() until the entry is fully setup. This ++ * avoids nesting of cache->c_list_lock into hash table bit locks which ++ * is problematic for RT. ++ */ ++ atomic_set(&entry->e_refcnt, 2); + entry->e_key = key; + entry->e_value = value; + entry->e_flags = 0; +@@ -107,15 +113,12 @@ int mb_cache_entry_create(struct mb_cach + } + } + hlist_bl_add_head(&entry->e_hash_list, head); +- /* +- * Add entry to LRU list before it can be found by +- * mb_cache_entry_delete() to avoid races +- */ ++ hlist_bl_unlock(head); + spin_lock(&cache->c_list_lock); + list_add_tail(&entry->e_list, &cache->c_list); + cache->c_entry_count++; + spin_unlock(&cache->c_list_lock); +- hlist_bl_unlock(head); ++ mb_cache_entry_put(cache, entry); + + return 0; + } diff --git a/queue-5.15/net-hns3-fix-return-value-check-bug-of-rx-copybreak.patch b/queue-5.15/net-hns3-fix-return-value-check-bug-of-rx-copybreak.patch new file mode 100644 index 00000000000..022faa1e7f7 --- /dev/null +++ b/queue-5.15/net-hns3-fix-return-value-check-bug-of-rx-copybreak.patch @@ -0,0 +1,36 @@ +From 29df7c695ed67a8fa32bb7805bad8fe2a76c1f88 Mon Sep 17 00:00:00 2001 +From: Jie Wang +Date: Mon, 14 Nov 2022 16:20:47 +0800 +Subject: net: hns3: fix return value check bug of rx copybreak + +From: Jie Wang + +commit 29df7c695ed67a8fa32bb7805bad8fe2a76c1f88 upstream. + +The refactoring of rx copybreak modifies the original return logic, which +will make this feature unavailable. So this patch fixes the return logic of +rx copybreak. + +Fixes: e74a726da2c4 ("net: hns3: refactor hns3_nic_reuse_page()") +Fixes: 99f6b5fb5f63 ("net: hns3: use bounce buffer when rx page can not be reused") +Signed-off-by: Jie Wang +Signed-off-by: Hao Lan +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -3590,8 +3590,8 @@ static void hns3_nic_reuse_page(struct s + desc_cb->reuse_flag = 1; + } else if (frag_size <= ring->rx_copybreak) { + ret = hns3_handle_rx_copybreak(skb, i, ring, pull_len, desc_cb); +- if (ret) +- goto out; ++ if (!ret) ++ return; + } + + out: diff --git a/queue-5.15/series b/queue-5.15/series index b98927d09bc..3aff7249268 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -282,3 +282,7 @@ mptcp-dedicated-request-sock-for-subflow-in-v6.patch mptcp-use-proper-req-destructor-for-ipv6.patch ext4-don-t-allow-journal-inode-to-have-encrypt-flag.patch selftests-set-the-build-variable-to-absolute-path.patch +btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch +net-hns3-fix-return-value-check-bug-of-rx-copybreak.patch +mbcache-avoid-nesting-of-cache-c_list_lock-under-bit-locks.patch +efi-random-combine-bootloader-provided-rng-seed-with-rng-protocol-output.patch -- 2.47.3