Blame SOURCES/0083-Detect-too-small-device-error-rather-than-underflow-.patch

e95a18
From 2cf0433063203fca10d26629c9e090b51fb1d806 Mon Sep 17 00:00:00 2001
e95a18
From: David Favro <dfavro@meta-dynamic.com>
e95a18
Date: Sat, 23 May 2020 08:24:59 -0400
e95a18
Subject: [PATCH 083/108] Detect too-small device: error rather than
e95a18
 underflow/crash
e95a18
e95a18
For 1.x metadata, when the user requested creation of an array on
e95a18
component devices that were too small even to hold the superblock,
e95a18
an undetected integer wraparound (underflow) resulted in an enormous
e95a18
computed size which resulted in various follow-on errors such as
e95a18
floating-point exception.
e95a18
e95a18
This patch detects this condition, prints a reasonable diagnostic
e95a18
message, and refuses to continue.
e95a18
e95a18
Signed-off-by: David Favro <dfavro@meta-dynamic.com>
e95a18
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
e95a18
---
e95a18
 super1.c | 19 ++++++++++++++-----
e95a18
 1 file changed, 14 insertions(+), 5 deletions(-)
e95a18
e95a18
diff --git a/super1.c b/super1.c
e95a18
index e0d80be..7664883 100644
e95a18
--- a/super1.c
e95a18
+++ b/super1.c
e95a18
@@ -2753,6 +2753,7 @@ static int validate_geometry1(struct supertype *st, int level,
e95a18
 	unsigned long long ldsize, devsize;
e95a18
 	int bmspace;
e95a18
 	unsigned long long headroom;
e95a18
+	unsigned long long overhead;
e95a18
 	int fd;
e95a18
 
e95a18
 	if (level == LEVEL_CONTAINER) {
e95a18
@@ -2785,10 +2786,6 @@ static int validate_geometry1(struct supertype *st, int level,
e95a18
 	close(fd);
e95a18
 
e95a18
 	devsize = ldsize >> 9;
e95a18
-	if (devsize < 24) {
e95a18
-		*freesize = 0;
e95a18
-		return 0;
e95a18
-	}
e95a18
 
e95a18
 	/* creating:  allow suitable space for bitmap or PPL */
e95a18
 	if (consistency_policy == CONSISTENCY_POLICY_PPL)
e95a18
@@ -2829,15 +2826,27 @@ static int validate_geometry1(struct supertype *st, int level,
e95a18
 	case 0: /* metadata at end.  Round down and subtract space to reserve */
e95a18
 		devsize = (devsize & ~(4ULL*2-1));
e95a18
 		/* space for metadata, bblog, bitmap/ppl */
e95a18
-		devsize -= 8*2 + 8 + bmspace;
e95a18
+		overhead = 8*2 + 8 + bmspace;
e95a18
+		if (devsize < overhead) /* detect underflow */
e95a18
+			goto dev_too_small_err;
e95a18
+		devsize -= overhead;
e95a18
 		break;
e95a18
 	case 1:
e95a18
 	case 2:
e95a18
+		if (devsize < data_offset) /* detect underflow */
e95a18
+			goto dev_too_small_err;
e95a18
 		devsize -= data_offset;
e95a18
 		break;
e95a18
 	}
e95a18
 	*freesize = devsize;
e95a18
 	return 1;
e95a18
+
e95a18
+/* Error condition, device cannot even hold the overhead. */
e95a18
+dev_too_small_err:
e95a18
+	fprintf(stderr, "device %s is too small (%lluK) for "
e95a18
+			"required metadata!\n", subdev, devsize>>1);
e95a18
+	*freesize = 0;
e95a18
+	return 0;
e95a18
 }
e95a18
 
e95a18
 void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0)
e95a18
-- 
e95a18
2.7.5
e95a18