[PATCH] libblkid: Abort after an incorrect checksum

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Log incorrect checksums and stop the superblock probing loop when
one is encountered.
This is to avoid exposing backend devices that are supposed
to be used through a stacked device (like raid or bcache).

Signed-off-by: Gabriel de Perthuis <g2p.code@xxxxxxxxx>
---
 libblkid/src/blkidP.h                   |  5 ++++-
 libblkid/src/probe.c                    | 26 ++++----------------------
 libblkid/src/superblocks/bcache.c       |  4 ++--
 libblkid/src/superblocks/lvm.c          |  5 ++---
 libblkid/src/superblocks/nilfs.c        |  3 +--
 libblkid/src/superblocks/silicon_raid.c |  5 +++--
 libblkid/src/superblocks/superblocks.c  | 13 +++++++++++++
 libblkid/src/superblocks/via_raid.c     |  4 ++--
 8 files changed, 31 insertions(+), 34 deletions(-)

diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h
index 0bbf310..76a3731 100644
--- a/libblkid/src/blkidP.h
+++ b/libblkid/src/blkidP.h
@@ -213,10 +213,13 @@ struct blkid_struct_probe
 	struct blkid_prval	vals[BLKID_NVALS];	/* results */
 	int			nvals;		/* number of assigned vals */
 
 	struct blkid_struct_probe *parent;	/* for clones */
 	struct blkid_struct_probe *disk_probe;	/* whole-disk probing */
+
+	uint64_t		csum;
+	uint64_t		csum_expected;
 };
 
 /* private flags library flags */
 #define BLKID_FL_PRIVATE_FD	(1 << 1)	/* see blkid_new_probe_from_filename() */
 #define BLKID_FL_TINY_DEV	(1 << 2)	/* <= 1.47MiB (floppy or so) */
@@ -514,11 +517,11 @@ extern int blkid_probe_sprintf_value(blkid_probe pr, const char *name,
 
 extern int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
 				size_t len, unsigned char *magic)
 			__attribute__((nonnull));
 
-extern int blkid_probe_verify_csum(blkid_probe pr, uint64_t csum, uint64_t expected)
+extern int blkid_probe_set_csum(blkid_probe pr, uint64_t csum, uint64_t expected)
 			__attribute__((nonnull));
 
 extern void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len)
 			__attribute__((nonnull));
 extern int blkid_uuid_is_empty(const unsigned char *buf, size_t len);
diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c
index 4b0c997..e0c99a6 100644
--- a/libblkid/src/probe.c
+++ b/libblkid/src/probe.c
@@ -1349,33 +1349,15 @@ int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
 	}
 
 	return rc;
 }
 
-int blkid_probe_verify_csum(blkid_probe pr, uint64_t csum, uint64_t expected)
+int blkid_probe_set_csum(blkid_probe pr, uint64_t csum, uint64_t expected)
 {
-	if (csum != expected) {
-		struct blkid_chain *chn = blkid_probe_get_chain(pr);
-
-		DBG(LOWPROBE, blkid_debug(
-				"incorrect checksum for type %s,"
-				" got %jX, expected %jX",
-				blkid_probe_get_probername(pr),
-				csum, expected));
-		/*
-		 * Accept bad checksum if BLKID_SUBLKS_BADCSUM flags is set
-		 */
-		if (chn->driver->id == BLKID_CHAIN_SUBLKS
-		    && (chn->flags & BLKID_SUBLKS_BADCSUM)) {
-			blkid_probe_set_value(pr, "SBBADCSUM", (unsigned char *) "1", 2);
-			goto accept;
-		}
-		return 0;	/* bad checksum */
-	}
-
-accept:
-	return 1;
+	pr->csum = csum;
+	pr->csum_expected = expected;
+	return 0;
 }
 
 /**
  * blkid_probe_get_devno:
  * @pr: probe
diff --git a/libblkid/src/superblocks/bcache.c b/libblkid/src/superblocks/bcache.c
index 303f7ee..99d886d 100644
--- a/libblkid/src/superblocks/bcache.c
+++ b/libblkid/src/superblocks/bcache.c
@@ -106,12 +106,12 @@ static int probe_bcache (blkid_probe pr, const struct blkid_idmag *mag)
 	if (!bcs)
 		return -1;
 
 	if (le64_to_cpu(bcs->offset) != BCACHE_SB_OFF / 512)
 		return 1;
-	if (!blkid_probe_verify_csum(pr, bcache_crc64(bcs), le64_to_cpu(bcs->csum)))
-		return 1;
+	if (blkid_probe_set_csum(pr, bcache_crc64(bcs), le64_to_cpu(bcs->csum)))
+		return -1;
 
 	if (blkid_probe_set_uuid(pr, bcs->uuid) < 0)
 		return -1;
 
 	return 0;
diff --git a/libblkid/src/superblocks/lvm.c b/libblkid/src/superblocks/lvm.c
index 65c7c35..de419bd 100644
--- a/libblkid/src/superblocks/lvm.c
+++ b/libblkid/src/superblocks/lvm.c
@@ -95,16 +95,15 @@ static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag)
 	}
 
 	if (le64_to_cpu(label->sector_xl) != (unsigned) sector)
 		return 1;
 
-	if (!blkid_probe_verify_csum(
+	blkid_probe_set_csum(
 		pr, lvm2_calc_crc(
 			&label->offset_xl, LVM2_LABEL_SIZE -
 			((char *) &label->offset_xl - (char *) label)),
-			le32_to_cpu(label->crc_xl)))
-		return 1;
+			le32_to_cpu(label->crc_xl));
 
 	format_lvm_uuid(uuid, (char *) label->pv_uuid);
 	blkid_probe_sprintf_uuid(pr, label->pv_uuid, sizeof(label->pv_uuid),
 			"%s", uuid);
 
diff --git a/libblkid/src/superblocks/nilfs.c b/libblkid/src/superblocks/nilfs.c
index 9207677..bf5f109 100644
--- a/libblkid/src/superblocks/nilfs.c
+++ b/libblkid/src/superblocks/nilfs.c
@@ -87,12 +87,11 @@ static int probe_nilfs2(blkid_probe pr, const struct blkid_idmag *mag)
 	bytes = le16_to_cpu(sb->s_bytes);
 	crc = crc32(le32_to_cpu(sb->s_crc_seed), (unsigned char *)sb, sumoff);
 	crc = crc32(crc, sum, 4);
 	crc = crc32(crc, (unsigned char *)sb + sumoff + 4, bytes - sumoff - 4);
 
-	if (!blkid_probe_verify_csum(pr, crc, le32_to_cpu(sb->s_sum)))
-		return 1;
+	blkid_probe_set_csum(pr, crc, le32_to_cpu(sb->s_sum));
 
 	if (strlen(sb->s_volume_name))
 		blkid_probe_set_label(pr, (unsigned char *) sb->s_volume_name,
 				      sizeof(sb->s_volume_name));
 
diff --git a/libblkid/src/superblocks/silicon_raid.c b/libblkid/src/superblocks/silicon_raid.c
index 10a3023..0202eea 100644
--- a/libblkid/src/superblocks/silicon_raid.c
+++ b/libblkid/src/superblocks/silicon_raid.c
@@ -102,12 +102,13 @@ static int probe_silraid(blkid_probe pr,
 
 	if (le32_to_cpu(sil->magic) != SILICON_MAGIC)
 		return 1;
 	if (sil->disk_number >= 8)
 		return 1;
-	if (!blkid_probe_verify_csum(pr, silraid_checksum(sil), le16_to_cpu(sil->checksum1)))
-		return 1;
+
+	if (blkid_probe_set_csum(pr, silraid_checksum(sil), le16_to_cpu(sil->checksum1)))
+		return -1;
 
 	if (blkid_probe_sprintf_version(pr, "%u.%u",
 				le16_to_cpu(sil->major_ver),
 				le16_to_cpu(sil->minor_ver)) != 0)
 		return -1;
diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c
index c6394c4..dcba46d 100644
--- a/libblkid/src/superblocks/superblocks.c
+++ b/libblkid/src/superblocks/superblocks.c
@@ -389,10 +389,23 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
 				blkid_probe_chain_reset_vals(pr, chn);
 				continue;
 			}
 		}
 
+		if (pr->csum != pr->csum_expected) {
+			DBG(LOWPROBE, blkid_debug(
+					"incorrect checksum for type %s,"
+					" got %jX, expected %jX",
+					id->name, pr->csum, pr->csum_expected));
+			if (chn->flags & BLKID_SUBLKS_BADCSUM)
+				/* flag a bad checksum but continue probing */
+				blkid_probe_set_value(pr, "SBBADCSUM", (unsigned char *) "1", 2);
+			else
+				/* stop probing */
+				goto nothing;
+		}
+
 		/* all cheks passed */
 		if (chn->flags & BLKID_SUBLKS_TYPE)
 			rc = blkid_probe_set_value(pr, "TYPE",
 				(unsigned char *) id->name,
 				strlen(id->name) + 1);
diff --git a/libblkid/src/superblocks/via_raid.c b/libblkid/src/superblocks/via_raid.c
index 5c15167..4630e8e 100644
--- a/libblkid/src/superblocks/via_raid.c
+++ b/libblkid/src/superblocks/via_raid.c
@@ -67,13 +67,13 @@ static int probe_viaraid(blkid_probe pr,
 
 	if (le16_to_cpu(v->signature) != VIA_SIGNATURE)
 		return 1;
 	if (v->version_number > 2)
 		return 1;
-	if (!blkid_probe_verify_csum(pr, via_checksum(v), v->checksum))
-		return 1;
 
+	if (blkid_probe_set_csum(pr, via_checksum(v), v->checksum))
+		return -1;
 	if (blkid_probe_sprintf_version(pr, "%u", v->version_number) != 0)
 		return -1;
 	if (blkid_probe_set_magic(pr, off,
 				sizeof(v->signature),
 				(unsigned char *) &v->signature))
-- 
1.8.4.25.g05e4ae6

--
To unsubscribe from this list: send the line "unsubscribe util-linux" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux