From 82893c619c3fe3a17b650cbf97a6e00dc0940e37 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 16 Jul 2023 17:22:05 +0200 Subject: [PATCH] 5.10-stable patches added patches: block-add-overflow-checks-for-amiga-partition-support.patch selftests-bpf-add-verifier-test-for-ptr_to_mem-spill.patch tpm-tpm_tis-claim-locality-in-interrupt-handler.patch --- ...w-checks-for-amiga-partition-support.patch | 202 ++++++++++++++++++ ...d-verifier-test-for-ptr_to_mem-spill.patch | 109 ++++++++++ queue-5.10/series | 3 + ...-claim-locality-in-interrupt-handler.patch | 39 ++++ 4 files changed, 353 insertions(+) create mode 100644 queue-5.10/block-add-overflow-checks-for-amiga-partition-support.patch create mode 100644 queue-5.10/selftests-bpf-add-verifier-test-for-ptr_to_mem-spill.patch create mode 100644 queue-5.10/tpm-tpm_tis-claim-locality-in-interrupt-handler.patch diff --git a/queue-5.10/block-add-overflow-checks-for-amiga-partition-support.patch b/queue-5.10/block-add-overflow-checks-for-amiga-partition-support.patch new file mode 100644 index 00000000000..64a6be8ad01 --- /dev/null +++ b/queue-5.10/block-add-overflow-checks-for-amiga-partition-support.patch @@ -0,0 +1,202 @@ +From b6f3f28f604ba3de4724ad82bea6adb1300c0b5f Mon Sep 17 00:00:00 2001 +From: Michael Schmitz +Date: Wed, 21 Jun 2023 08:17:25 +1200 +Subject: block: add overflow checks for Amiga partition support + +From: Michael Schmitz + +commit b6f3f28f604ba3de4724ad82bea6adb1300c0b5f upstream. + +The Amiga partition parser module uses signed int for partition sector +address and count, which will overflow for disks larger than 1 TB. + +Use u64 as type for sector address and size to allow using disks up to +2 TB without LBD support, and disks larger than 2 TB with LBD. The RBD +format allows to specify disk sizes up to 2^128 bytes (though native +OS limitations reduce this somewhat, to max 2^68 bytes), so check for +u64 overflow carefully to protect against overflowing sector_t. + +Bail out if sector addresses overflow 32 bits on kernels without LBD +support. + +This bug was reported originally in 2012, and the fix was created by +the RDB author, Joanne Dow . A patch had been +discussed and reviewed on linux-m68k at that time but never officially +submitted (now resubmitted as patch 1 in this series). +This patch adds additional error checking and warning messages. + +Reported-by: Martin Steigerwald +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=43511 +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Message-ID: <201206192146.09327.Martin@lichtvoll.de> +Cc: # 5.2 +Signed-off-by: Michael Schmitz +Reviewed-by: Geert Uytterhoeven +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20230620201725.7020-4-schmitzmic@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/partitions/amiga.c | 103 ++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 85 insertions(+), 18 deletions(-) + +--- a/block/partitions/amiga.c ++++ b/block/partitions/amiga.c +@@ -11,10 +11,18 @@ + #define pr_fmt(fmt) fmt + + #include ++#include ++#include + #include + + #include "check.h" + ++/* magic offsets in partition DosEnvVec */ ++#define NR_HD 3 ++#define NR_SECT 5 ++#define LO_CYL 9 ++#define HI_CYL 10 ++ + static __inline__ u32 + checksum_block(__be32 *m, int size) + { +@@ -31,9 +39,12 @@ int amiga_partition(struct parsed_partit + unsigned char *data; + struct RigidDiskBlock *rdb; + struct PartitionBlock *pb; +- sector_t start_sect, nr_sects; +- int blk, part, res = 0; +- int blksize = 1; /* Multiplier for disk block size */ ++ u64 start_sect, nr_sects; ++ sector_t blk, end_sect; ++ u32 cylblk; /* rdb_CylBlocks = nr_heads*sect_per_track */ ++ u32 nr_hd, nr_sect, lo_cyl, hi_cyl; ++ int part, res = 0; ++ unsigned int blksize = 1; /* Multiplier for disk block size */ + int slot = 1; + char b[BDEVNAME_SIZE]; + +@@ -42,7 +53,7 @@ int amiga_partition(struct parsed_partit + goto rdb_done; + data = read_part_sector(state, blk, §); + if (!data) { +- pr_err("Dev %s: unable to read RDB block %d\n", ++ pr_err("Dev %s: unable to read RDB block %llu\n", + bdevname(state->bdev, b), blk); + res = -1; + goto rdb_done; +@@ -59,12 +70,12 @@ int amiga_partition(struct parsed_partit + *(__be32 *)(data+0xdc) = 0; + if (checksum_block((__be32 *)data, + be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)==0) { +- pr_err("Trashed word at 0xd0 in block %d ignored in checksum calculation\n", ++ pr_err("Trashed word at 0xd0 in block %llu ignored in checksum calculation\n", + blk); + break; + } + +- pr_err("Dev %s: RDB in block %d has bad checksum\n", ++ pr_err("Dev %s: RDB in block %llu has bad checksum\n", + bdevname(state->bdev, b), blk); + } + +@@ -81,10 +92,15 @@ int amiga_partition(struct parsed_partit + blk = be32_to_cpu(rdb->rdb_PartitionList); + put_dev_sector(sect); + for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) { +- blk *= blksize; /* Read in terms partition table understands */ ++ /* Read in terms partition table understands */ ++ if (check_mul_overflow(blk, (sector_t) blksize, &blk)) { ++ pr_err("Dev %s: overflow calculating partition block %llu! Skipping partitions %u and beyond\n", ++ bdevname(state->bdev, b), blk, part); ++ break; ++ } + data = read_part_sector(state, blk, §); + if (!data) { +- pr_err("Dev %s: unable to read partition block %d\n", ++ pr_err("Dev %s: unable to read partition block %llu\n", + bdevname(state->bdev, b), blk); + res = -1; + goto rdb_done; +@@ -96,19 +112,70 @@ int amiga_partition(struct parsed_partit + if (checksum_block((__be32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 ) + continue; + +- /* Tell Kernel about it */ ++ /* RDB gives us more than enough rope to hang ourselves with, ++ * many times over (2^128 bytes if all fields max out). ++ * Some careful checks are in order, so check for potential ++ * overflows. ++ * We are multiplying four 32 bit numbers to one sector_t! ++ */ ++ ++ nr_hd = be32_to_cpu(pb->pb_Environment[NR_HD]); ++ nr_sect = be32_to_cpu(pb->pb_Environment[NR_SECT]); ++ ++ /* CylBlocks is total number of blocks per cylinder */ ++ if (check_mul_overflow(nr_hd, nr_sect, &cylblk)) { ++ pr_err("Dev %s: heads*sects %u overflows u32, skipping partition!\n", ++ bdevname(state->bdev, b), cylblk); ++ continue; ++ } ++ ++ /* check for consistency with RDB defined CylBlocks */ ++ if (cylblk > be32_to_cpu(rdb->rdb_CylBlocks)) { ++ pr_warn("Dev %s: cylblk %u > rdb_CylBlocks %u!\n", ++ bdevname(state->bdev, b), cylblk, ++ be32_to_cpu(rdb->rdb_CylBlocks)); ++ } ++ ++ /* RDB allows for variable logical block size - ++ * normalize to 512 byte blocks and check result. ++ */ ++ ++ if (check_mul_overflow(cylblk, blksize, &cylblk)) { ++ pr_err("Dev %s: partition %u bytes per cyl. overflows u32, skipping partition!\n", ++ bdevname(state->bdev, b), part); ++ continue; ++ } ++ ++ /* Calculate partition start and end. Limit of 32 bit on cylblk ++ * guarantees no overflow occurs if LBD support is enabled. ++ */ ++ ++ lo_cyl = be32_to_cpu(pb->pb_Environment[LO_CYL]); ++ start_sect = ((u64) lo_cyl * cylblk); ++ ++ hi_cyl = be32_to_cpu(pb->pb_Environment[HI_CYL]); ++ nr_sects = (((u64) hi_cyl - lo_cyl + 1) * cylblk); + +- nr_sects = ((sector_t)be32_to_cpu(pb->pb_Environment[10]) + 1 - +- be32_to_cpu(pb->pb_Environment[9])) * +- be32_to_cpu(pb->pb_Environment[3]) * +- be32_to_cpu(pb->pb_Environment[5]) * +- blksize; + if (!nr_sects) + continue; +- start_sect = (sector_t)be32_to_cpu(pb->pb_Environment[9]) * +- be32_to_cpu(pb->pb_Environment[3]) * +- be32_to_cpu(pb->pb_Environment[5]) * +- blksize; ++ ++ /* Warn user if partition end overflows u32 (AmigaDOS limit) */ ++ ++ if ((start_sect + nr_sects) > UINT_MAX) { ++ pr_warn("Dev %s: partition %u (%llu-%llu) needs 64 bit device support!\n", ++ bdevname(state->bdev, b), part, ++ start_sect, start_sect + nr_sects); ++ } ++ ++ if (check_add_overflow(start_sect, nr_sects, &end_sect)) { ++ pr_err("Dev %s: partition %u (%llu-%llu) needs LBD device support, skipping partition!\n", ++ bdevname(state->bdev, b), part, ++ start_sect, end_sect); ++ continue; ++ } ++ ++ /* Tell Kernel about it */ ++ + put_partition(state,slot++,start_sect,nr_sects); + { + /* Be even more informative to aid mounting */ diff --git a/queue-5.10/selftests-bpf-add-verifier-test-for-ptr_to_mem-spill.patch b/queue-5.10/selftests-bpf-add-verifier-test-for-ptr_to_mem-spill.patch new file mode 100644 index 00000000000..7465b19b384 --- /dev/null +++ b/queue-5.10/selftests-bpf-add-verifier-test-for-ptr_to_mem-spill.patch @@ -0,0 +1,109 @@ +From 4237e9f4a96228ccc8a7abe5e4b30834323cd353 Mon Sep 17 00:00:00 2001 +From: Gilad Reti +Date: Wed, 13 Jan 2021 07:38:08 +0200 +Subject: selftests/bpf: Add verifier test for PTR_TO_MEM spill + +From: Gilad Reti + +commit 4237e9f4a96228ccc8a7abe5e4b30834323cd353 upstream. + +Add a test to check that the verifier is able to recognize spilling of +PTR_TO_MEM registers, by reserving a ringbuf buffer, forcing the spill +of a pointer holding the buffer address to the stack, filling it back +in from the stack and writing to the memory area pointed by it. + +The patch was partially contributed by CyberArk Software, Inc. + +Signed-off-by: Gilad Reti +Signed-off-by: Alexei Starovoitov +Acked-by: Yonghong Song +Acked-by: KP Singh +Link: https://lore.kernel.org/bpf/20210113053810.13518-2-gilad.reti@gmail.com +Cc: Lorenz Bauer +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/test_verifier.c | 12 ++++++++ + tools/testing/selftests/bpf/verifier/spill_fill.c | 30 ++++++++++++++++++++++ + 2 files changed, 41 insertions(+), 1 deletion(-) + +--- a/tools/testing/selftests/bpf/test_verifier.c ++++ b/tools/testing/selftests/bpf/test_verifier.c +@@ -50,7 +50,7 @@ + #define MAX_INSNS BPF_MAXINSNS + #define MAX_TEST_INSNS 1000000 + #define MAX_FIXUPS 8 +-#define MAX_NR_MAPS 20 ++#define MAX_NR_MAPS 21 + #define MAX_TEST_RUNS 8 + #define POINTER_VALUE 0xcafe4all + #define TEST_DATA_LEN 64 +@@ -87,6 +87,7 @@ struct bpf_test { + int fixup_sk_storage_map[MAX_FIXUPS]; + int fixup_map_event_output[MAX_FIXUPS]; + int fixup_map_reuseport_array[MAX_FIXUPS]; ++ int fixup_map_ringbuf[MAX_FIXUPS]; + const char *errstr; + const char *errstr_unpriv; + uint32_t insn_processed; +@@ -640,6 +641,7 @@ static void do_test_fixup(struct bpf_tes + int *fixup_sk_storage_map = test->fixup_sk_storage_map; + int *fixup_map_event_output = test->fixup_map_event_output; + int *fixup_map_reuseport_array = test->fixup_map_reuseport_array; ++ int *fixup_map_ringbuf = test->fixup_map_ringbuf; + + if (test->fill_helper) { + test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct bpf_insn)); +@@ -817,6 +819,14 @@ static void do_test_fixup(struct bpf_tes + fixup_map_reuseport_array++; + } while (*fixup_map_reuseport_array); + } ++ if (*fixup_map_ringbuf) { ++ map_fds[20] = create_map(BPF_MAP_TYPE_RINGBUF, 0, ++ 0, 4096); ++ do { ++ prog[*fixup_map_ringbuf].imm = map_fds[20]; ++ fixup_map_ringbuf++; ++ } while (*fixup_map_ringbuf); ++ } + } + + struct libcap { +--- a/tools/testing/selftests/bpf/verifier/spill_fill.c ++++ b/tools/testing/selftests/bpf/verifier/spill_fill.c +@@ -29,6 +29,36 @@ + .result_unpriv = ACCEPT, + }, + { ++ "check valid spill/fill, ptr to mem", ++ .insns = { ++ /* reserve 8 byte ringbuf memory */ ++ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), ++ BPF_LD_MAP_FD(BPF_REG_1, 0), ++ BPF_MOV64_IMM(BPF_REG_2, 8), ++ BPF_MOV64_IMM(BPF_REG_3, 0), ++ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve), ++ /* store a pointer to the reserved memory in R6 */ ++ BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), ++ /* check whether the reservation was successful */ ++ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), ++ /* spill R6(mem) into the stack */ ++ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8), ++ /* fill it back in R7 */ ++ BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_10, -8), ++ /* should be able to access *(R7) = 0 */ ++ BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 0), ++ /* submit the reserved ringbuf memory */ ++ BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), ++ BPF_MOV64_IMM(BPF_REG_2, 0), ++ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_submit), ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ .fixup_map_ringbuf = { 1 }, ++ .result = ACCEPT, ++ .result_unpriv = ACCEPT, ++}, ++{ + "check corrupted spill/fill", + .insns = { + /* spill R1(ctx) into stack */ diff --git a/queue-5.10/series b/queue-5.10/series index 42bc36cebbc..9e67e5b1092 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -310,3 +310,6 @@ arm-orion5x-fix-d2net-gpio-initialization.patch leds-trigger-netdev-recheck-netdev_led_mode_linkup-on-dev-rename.patch fs-no-need-to-check-source.patch fanotify-disallow-mount-sb-marks-on-kernel-internal-pseudo-fs.patch +tpm-tpm_tis-claim-locality-in-interrupt-handler.patch +selftests-bpf-add-verifier-test-for-ptr_to_mem-spill.patch +block-add-overflow-checks-for-amiga-partition-support.patch diff --git a/queue-5.10/tpm-tpm_tis-claim-locality-in-interrupt-handler.patch b/queue-5.10/tpm-tpm_tis-claim-locality-in-interrupt-handler.patch new file mode 100644 index 00000000000..958bfde0828 --- /dev/null +++ b/queue-5.10/tpm-tpm_tis-claim-locality-in-interrupt-handler.patch @@ -0,0 +1,39 @@ +From 0e069265bce5a40c4eee52e2364bbbd4dabee94a Mon Sep 17 00:00:00 2001 +From: Lino Sanfilippo +Date: Thu, 24 Nov 2022 14:55:35 +0100 +Subject: tpm, tpm_tis: Claim locality in interrupt handler +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lino Sanfilippo + +commit 0e069265bce5a40c4eee52e2364bbbd4dabee94a upstream. + +Writing the TPM_INT_STATUS register in the interrupt handler to clear the +interrupts only has effect if a locality is held. Since this is not +guaranteed at the time the interrupt is fired, claim the locality +explicitly in the handler. + +Signed-off-by: Lino Sanfilippo +Tested-by: Michael Niewöhner +Tested-by: Jarkko Sakkinen +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/tpm/tpm_tis_core.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -731,7 +731,9 @@ static irqreturn_t tis_int_handler(int d + wake_up_interruptible(&priv->int_queue); + + /* Clear interrupts handled with TPM_EOI */ ++ tpm_tis_request_locality(chip, 0); + rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), interrupt); ++ tpm_tis_relinquish_locality(chip, 0); + if (rc < 0) + return IRQ_NONE; + -- 2.47.3