]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 16 Jul 2023 15:22:05 +0000 (17:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 16 Jul 2023 15:22:05 +0000 (17:22 +0200)
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

queue-5.10/block-add-overflow-checks-for-amiga-partition-support.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-add-verifier-test-for-ptr_to_mem-spill.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/tpm-tpm_tis-claim-locality-in-interrupt-handler.patch [new file with mode: 0644]

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 (file)
index 0000000..64a6be8
--- /dev/null
@@ -0,0 +1,202 @@
+From b6f3f28f604ba3de4724ad82bea6adb1300c0b5f Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitzmic@gmail.com>
+Date: Wed, 21 Jun 2023 08:17:25 +1200
+Subject: block: add overflow checks for Amiga partition support
+
+From: Michael Schmitz <schmitzmic@gmail.com>
+
+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 <jdow@earthlink.net>. 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 <Martin@lichtvoll.de>
+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: <stable@vger.kernel.org> # 5.2
+Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Reviewed-by: Christoph Hellwig <hch@infradead.org>
+Link: https://lore.kernel.org/r/20230620201725.7020-4-schmitzmic@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/types.h>
++#include <linux/mm_types.h>
++#include <linux/overflow.h>
+ #include <linux/affs_hardblocks.h>
+ #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, &sect);
+               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, &sect);
+               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 (file)
index 0000000..7465b19
--- /dev/null
@@ -0,0 +1,109 @@
+From 4237e9f4a96228ccc8a7abe5e4b30834323cd353 Mon Sep 17 00:00:00 2001
+From: Gilad Reti <gilad.reti@gmail.com>
+Date: Wed, 13 Jan 2021 07:38:08 +0200
+Subject: selftests/bpf: Add verifier test for PTR_TO_MEM spill
+
+From: Gilad Reti <gilad.reti@gmail.com>
+
+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 <gilad.reti@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Yonghong Song <yhs@fb.com>
+Acked-by: KP Singh <kpsingh@kernel.org>
+Link: https://lore.kernel.org/bpf/20210113053810.13518-2-gilad.reti@gmail.com
+Cc: Lorenz Bauer <lmb@isovalent.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 */
index 42bc36cebbcdf2d3d3a36c7aa81a65102c8d5e1c..9e67e5b10921338ac2b3403b970b76f7c0bbb88c 100644 (file)
@@ -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 (file)
index 0000000..958bfde
--- /dev/null
@@ -0,0 +1,39 @@
+From 0e069265bce5a40c4eee52e2364bbbd4dabee94a Mon Sep 17 00:00:00 2001
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+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 <l.sanfilippo@kunbus.com>
+
+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 <l.sanfilippo@kunbus.com>
+Tested-by: Michael Niewöhner <linux@mniewoehner.de>
+Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;