summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_bsd_enc.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-05-02 22:46:13 +0000
committerphk <phk@FreeBSD.org>2003-05-02 22:46:13 +0000
commit2a47b08091621c84d2d45229dcdb6753d5a56366 (patch)
tree167b9bb293bf61d98bdeb7e2f55bda158e7dc864 /sys/geom/geom_bsd_enc.c
parent6c2bb0c0915b99851b219ab760eecfc5067d2afc (diff)
downloadFreeBSD-src-2a47b08091621c84d2d45229dcdb6753d5a56366.zip
FreeBSD-src-2a47b08091621c84d2d45229dcdb6753d5a56366.tar.gz
Make bsd_disklabel_le_enc calculate the checksum and fill it in.
(If there is a legitimate need to correctly encode and pack a disklabel with an invalid checksum custom tools can be built for that.) Make bsd_disklabel_le_dec() validate the magics, number of partitions (against a new parameter) and the checksum. Vastly simplify the logic of the GEOM::BSD class implementation: Let g_bsd_modify() always take a byte-stream label. This simplifies all users, except the ioctl's which now have to convert to a byte-stream first. Their loss. g_bsd_modify() is called with topology held now, and it returns with it held. Always update the md5sum in g_bsd_modify(), otherwise the check is no use after the first modification of the label. Make the MD5 over the bytestream version of the label. Move the rawoffset hack to g_bsd_modify() and remove all the inram/ondisk conversions. Don't configure hotspots in g_bsd_modify(), do it in taste instead, we do not support moving the label to a different location on the fly anyway. This passes all current regression tests.
Diffstat (limited to 'sys/geom/geom_bsd_enc.c')
-rw-r--r--sys/geom/geom_bsd_enc.c45
1 files changed, 40 insertions, 5 deletions
diff --git a/sys/geom/geom_bsd_enc.c b/sys/geom/geom_bsd_enc.c
index 8292497..a3a7fd9 100644
--- a/sys/geom/geom_bsd_enc.c
+++ b/sys/geom/geom_bsd_enc.c
@@ -44,10 +44,12 @@
#include <sys/types.h>
#include <sys/endian.h>
#include <sys/disklabel.h>
+#include <sys/errno.h>
#ifdef _KERNEL
#include <sys/systm.h>
#else
#include <string.h>
+#include <stdio.h>
#endif
void
@@ -61,12 +63,38 @@ bsd_partition_le_dec(u_char *ptr, struct partition *d)
d->p_cpg = le16dec(ptr + 14);
}
-void
-bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d)
+int
+bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d, int maxpart)
{
int i;
+ u_char *p, *pe;
+ uint16_t sum;
d->d_magic = le32dec(ptr + 0);
+ if (d->d_magic != DISKMAGIC)
+ return(EINVAL);
+
+ d->d_magic2 = le32dec(ptr + 132);
+ if (d->d_magic2 != DISKMAGIC) {
+printf("HERE %s %d\n", __FILE__, __LINE__);
+ return(EINVAL);
+ }
+
+ d->d_npartitions = le16dec(ptr + 138);
+ if (d->d_npartitions > maxpart) {
+printf("HERE %s %d\n", __FILE__, __LINE__);
+ return(EINVAL);
+ }
+
+ pe = ptr + 148 + 16 * d->d_npartitions;
+ sum = 0;
+ for (p = ptr; p < pe; p += 2)
+ sum ^= le16dec(p);
+ if (sum != 0) {
+printf("HERE %s %d\n", __FILE__, __LINE__);
+ return(EINVAL);
+ }
+
d->d_type = le16dec(ptr + 4);
d->d_subtype = le16dec(ptr + 6);
bcopy(ptr + 8, d->d_typename, 16);
@@ -97,13 +125,13 @@ bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d)
d->d_spare[2] = le32dec(ptr + 120);
d->d_spare[3] = le32dec(ptr + 124);
d->d_spare[4] = le32dec(ptr + 128);
- d->d_magic2 = le32dec(ptr + 132);
d->d_checksum = le16dec(ptr + 136);
d->d_npartitions = le16dec(ptr + 138);
d->d_bbsize = le32dec(ptr + 140);
d->d_sbsize = le32dec(ptr + 144);
for (i = 0; i < MAXPARTITIONS; i++)
bsd_partition_le_dec(ptr + 148 + 16 * i, &d->d_partitions[i]);
+ return(0);
}
void
@@ -121,6 +149,8 @@ void
bsd_disklabel_le_enc(u_char *ptr, struct disklabel *d)
{
int i;
+ u_char *p, *pe;
+ uint16_t sum;
le32enc(ptr + 0, d->d_magic);
le16enc(ptr + 4, d->d_type);
@@ -154,10 +184,15 @@ bsd_disklabel_le_enc(u_char *ptr, struct disklabel *d)
le32enc(ptr + 124, d->d_spare[3]);
le32enc(ptr + 128, d->d_spare[4]);
le32enc(ptr + 132, d->d_magic2);
- le16enc(ptr + 136, d->d_checksum);
+ le16enc(ptr + 136, 0);
le16enc(ptr + 138, d->d_npartitions);
le32enc(ptr + 140, d->d_bbsize);
le32enc(ptr + 144, d->d_sbsize);
- for (i = 0; i < MAXPARTITIONS; i++)
+ for (i = 0; i < d->d_npartitions; i++)
bsd_partition_le_enc(ptr + 148 + 16 * i, &d->d_partitions[i]);
+ pe = ptr + 148 + 16 * d->d_npartitions;
+ sum = 0;
+ for (p = ptr; p < pe; p += 2)
+ sum ^= le16dec(p);
+ le16enc(ptr + 136, sum);
}
OpenPOWER on IntegriCloud