diff --git a/block/partitions/amiga.c b/block/partitions/amiga.c
index 5609366..6184d83 100644
--- a/block/partitions/amiga.c
+++ b/block/partitions/amiga.c
@@ -11,6 +11,7 @@
 #define pr_fmt(fmt) fmt
 
 #include <linux/types.h>
+#include <linux/log2.h>
 #include <linux/affs_hardblocks.h>
 
 #include "check.h"
@@ -32,7 +33,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, cylblk_res;	/* rdb_CylBlocks = nr_heads*sect_per_track */
+	int blk, part, res = 0, blk_shift = 0, did_warn = 0;
 	int blksize = 1;	/* Multiplier for disk block size */
 	int slot = 1;
 	char b[BDEVNAME_SIZE];
@@ -98,6 +101,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[3]) *
+			 be32_to_cpu(pb->pb_Environment[5]);
+
+		/* check for consistency with RDB defined CylBlocks */
+		if (cylblk > be32_to_cpu(rdb->rdb_CylBlocks)) {
+			pr_err("Dev %s: cylblk 0x%lx > rdb_CylBlocks 0x%x!\n",
+				bdevname(state->bdev, b),
+				(unsigned long) 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 don't care much.
+		 */
+
+		if (cylblk > UINT_MAX) {
+			pr_err("Dev %s: hds*sects 0x%lx > UINT_MAX!\n",
+				bdevname(state->bdev, b),
+				(unsigned long) cylblk);
+
+			/* lop off low 32 bits */
+			cylblk_res = cylblk >> 32;
+
+			/* check for further overflow in end result */
+			if (be32_to_cpu(pb->pb_Environment[9]) *
+				cylblk_res * blksize > UINT_MAX) {
+				pr_err("Dev %s: start_sect overflows u64!\n",
+					bdevname(state->bdev, b));
+				res = -1;
+				goto rdb_done;
+			}
+
+			if (be32_to_cpu(pb->pb_Environment[10]) *
+			   cylblk_res * blksize > UINT_MAX) {
+				pr_err("Dev %s: end_sect overflows u64!\n",
+					bdevname(state->bdev, b));
+				res = -1;
+				goto rdb_done;
+			}
+		}
+
+		/* Condition 2: even if CylBlocks did not overflow, the end
+		 * result must still fit u64!
+		 */
+
+		/* how many bits above 32 in cylblk * blksize ? */
+		if (cylblk*blksize > (u64) UINT_MAX)
+			blk_shift = ilog2(cylblk*blksize) - 32;
+
+		if (be32_to_cpu(pb->pb_Environment[9])
+			> (u64) UINT_MAX>>blk_shift) {
+			pr_err("Dev %s: start_sect overflows u64!\n",
+				bdevname(state->bdev, b));
+			res = -1;
+			goto rdb_done;
+		}
+
+		if (be32_to_cpu(pb->pb_Environment[10])
+			> (u64) UINT_MAX>>blk_shift) {
+			pr_err("Dev %s: end_sect overflows u64!\n",
+				bdevname(state->bdev, b));
+			res = -1;
+			goto rdb_done;
+		}
+
 		/* Tell Kernel about it */
 
 		nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
@@ -111,6 +187,27 @@ int amiga_partition(struct parsed_partitions *state)
 			     be32_to_cpu(pb->pb_Environment[3]) *
 			     be32_to_cpu(pb->pb_Environment[5]) *
 			     blksize;
+
+		/* Warn user if start_sect or nr_sects overflow u32 */
+		if ((nr_sects > UINT_MAX || start_sect > UINT_MAX ||
+		    (start_sect + nr_sects) > UINT_MAX) && !did_warn) {
+			pr_err("Dev %s: partition 32 bit overflow! ",
+				bdevname(state->bdev, b));
+			pr_cont("start_sect 0x%llX, nr_sects 0x%llx\n",
+				 start_sect, nr_sects);
+			pr_err("Dev %s: partition may  need 64 bit ",
+				bdevname(state->bdev, b));
+			pr_cont("device support on native AmigaOS!\n");
+			/* Without LBD support, better bail out */
+			if (!IS_ENABLED(CONFIG_LBDAF)) {
+				pr_err("Dev %s: no LBD support, aborting!",
+					bdevname(state->bdev, b));
+				res = -1;
+				goto rdb_done;
+			}
+			did_warn++;
+		}
+
 		put_partition(state,slot++,start_sect,nr_sects);
 		{
 			/* Be even more informative to aid mounting */
