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