diff --git a/block/partitions/amiga.c b/block/partitions/amiga.c
index 5609366..7277ebb 100644
--- a/block/partitions/amiga.c
+++ b/block/partitions/amiga.c
@@ -11,11 +11,20 @@
 #define pr_fmt(fmt) fmt
 
 #include <linux/types.h>
+#include <linux/types.h>
+#include <linux/mm_types.h>
+#include <linux/overflow.h>
 #include <linux/affs_hardblocks.h>
 
 #include "check.h"
 #include "amiga.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)
 {
@@ -32,7 +41,9 @@ int amiga_partition(struct parsed_partitions *state)
 	unsigned char *data;
 	struct RigidDiskBlock *rdb;
 	struct PartitionBlock *pb;
-	int start_sect, nr_sects, blk, part, res = 0;
+	u64 start_sect, nr_sects;
+	u64 cylblk;		/* rdb_CylBlocks = nr_heads*sect_per_track */
+	int blk, part, res = 0;
 	int blksize = 1;	/* Multiplier for disk block size */
 	int slot = 1;
 	char b[BDEVNAME_SIZE];
@@ -98,19 +109,79 @@ int amiga_partition(struct parsed_partitions *state)
 		if (checksum_block((__be32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 )
 			continue;
 
+		/* 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.
+		 */
+
+		/* CylBlocks is total number of blocks per cylinder */
+		cylblk = be32_to_cpu(pb->pb_Environment[NR_HD]) *
+			 be32_to_cpu(pb->pb_Environment[NR_SECT]);
+
+		/* check for consistency with RDB defined CylBlocks */
+		if (cylblk > be32_to_cpu(rdb->rdb_CylBlocks)) {
+			pr_warn("Dev %s: cylblk %llu > rdb_CylBlocks 0x%x!\n",
+				bdevname(state->bdev, b), cylblk,
+				be32_to_cpu(rdb->rdb_CylBlocks));
+		}
+
+		/* check for potential overflows - we are going to multiply
+		 * three 32 bit numbers to one 64 bit result later!
+		 * Condition 1: nr_heads * sects_per_track must fit u32!
+		 * NB: This is a HARD limit for AmigaDOS. We just warn.
+		 */
+
+		if (cylblk > UINT_MAX) {
+			pr_warn("Dev %s: heads*sects %llu > UINT_MAX!\n",
+				bdevname(state->bdev, b), cylblk);
+		}
+
+		/* Condition 2: even if CylBlocks did not overflow, the end
+		 * result must still fit u64!
+		 */
+
+		if (array3_size(be32_to_cpu(pb->pb_Environment[LO_CYL]),
+			cylblk, blksize) == SIZE_MAX) {
+			pr_err("Dev %s: partition %u start overflows u64, skipping partition!\n",
+				bdevname(state->bdev, b), part);
+			continue;
+		}
+
+		if (array3_size(be32_to_cpu(pb->pb_Environment[HI_CYL]),
+			cylblk, blksize) == SIZE_MAX) {
+			pr_err("Dev %s: partition %u end overflows u64, skipping partition!\n",
+				bdevname(state->bdev, b), part);
+			continue;
+		}
+
 		/* Tell Kernel about it */
 
-		nr_sects = (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;
+		nr_sects = (u64)((be32_to_cpu(pb->pb_Environment[HI_CYL]) + 1 -
+			    be32_to_cpu(pb->pb_Environment[LO_CYL])) *
+			   be32_to_cpu(pb->pb_Environment[NR_HD]) *
+			   be32_to_cpu(pb->pb_Environment[NR_SECT]) *
+			   blksize);
 		if (!nr_sects)
 			continue;
-		start_sect = be32_to_cpu(pb->pb_Environment[9]) *
-			     be32_to_cpu(pb->pb_Environment[3]) *
-			     be32_to_cpu(pb->pb_Environment[5]) *
-			     blksize;
+		start_sect = (u64)(be32_to_cpu(pb->pb_Environment[LO_CYL]) *
+			     be32_to_cpu(pb->pb_Environment[NR_HD]) *
+			     be32_to_cpu(pb->pb_Environment[NR_SECT]) *
+			     blksize);
+
+		/* Warn user if start_sect or nr_sects overflow u32 */
+		if (start_sect > UINT_MAX ||
+		    (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, nr_sects);
+			/* Without LBD support, better bail out */
+			if (!IS_ENABLED(CONFIG_LBDAF)) {
+				pr_err("Dev %s: no LBD support, skipping partition %u!",
+					bdevname(state->bdev, b), part);
+				continue;
+			}
+		}
+
 		put_partition(state,slot++,start_sect,nr_sects);
 		{
 			/* Be even more informative to aid mounting */
