tech-toolchain archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
PR toolchain/42357 disklabel endian issues
Hi all,
I have submitted the above PR with a bunch of patches for fixing this problem.
Some review would be nice.
This adds a function called bswap_label() that byte swaps a label. The dkcksum
function has been changed to take the number of partitions in the label as a
parameter because it sometimes needs to checksum a byte swapped label. I could
have changed dkcksum to check the label magic numbers and byte swap the
npartitions field if necessary, but that would have introduced a lot of new
dependencies to dkcksum, so I opted for the extra parameter.
I also replaced a couple of u_short with uint16_t because we are dealing with
data types whose size is fixed externally. (u_short may be defined to have a
fixed size, but there's no harm in saying what you mean.)
The patch defines a macro called BSWAP_LABEL that is overkill for this. I
expect that whoever commits a fix leaves this bit out. I only saw it after I
had filed the PR.
Cheers,
Lloyd
Index: sbin/apmlabel/apmlabel.c
===================================================================
RCS file: /vol/src/rsync-src/src/sbin/apmlabel/apmlabel.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 apmlabel.c
--- sbin/apmlabel/apmlabel.c 5 Mar 2007 23:06:53 -0000 1.1.1.1
+++ sbin/apmlabel/apmlabel.c 16 Jul 2009 22:34:15 -0000
@@ -87,7 +87,7 @@
int one = 1;
label.d_checksum = 0;
- label.d_checksum = dkcksum(&label);
+ label.d_checksum = dkcksum(&label, label.d_npartitions);
if (ioctl(sd, doraw ? DIOCWDINFO : DIOCSDINFO, &label) < 0) {
perror("set label");
exit(1);
Index: sbin/disklabel/Makefile
===================================================================
RCS file: /vol/src/rsync-src/src/sbin/disklabel/Makefile,v
retrieving revision 1.62
diff -u -r1.62 Makefile
--- sbin/disklabel/Makefile 14 Feb 2009 13:52:51 -0000 1.62
+++ sbin/disklabel/Makefile 9 Jul 2009 04:13:49 -0000
@@ -1,9 +1,12 @@
# $NetBSD: Makefile,v 1.62 2009/02/14 13:52:51 abs Exp $
# @(#)Makefile 8.2 (Berkeley) 3/17/94
+.include <bsd.endian.mk>
+
PROG= disklabel
SRCS= main.c dkcksum.c interact.c printlabel.c
MAN= disklabel.5 disklabel.8
+CPPFLAGS+= -DTARGET_ENDIANNESS=${TARGET_ENDIANNESS}
.if (${HOSTPROG:U} == "")
DPADD+= ${LIBUTIL}
LDADD+= -lutil
Index: sbin/disklabel/dkcksum.c
===================================================================
RCS file: /vol/src/rsync-src/src/sbin/disklabel/dkcksum.c,v
retrieving revision 1.11
diff -u -r1.11 dkcksum.c
--- sbin/disklabel/dkcksum.c 12 Jun 2005 19:18:34 -0000 1.11
+++ sbin/disklabel/dkcksum.c 14 Jul 2009 21:42:21 -0000
@@ -50,15 +50,15 @@
#endif /* HAVE_NBTOOL_CONFIG_H */
#include "dkcksum.h"
-u_short
-dkcksum(struct disklabel *lp)
+uint16_t
+dkcksum(struct disklabel *lp, int npartitions)
{
- u_short *start, *end;
- u_short sum;
+ uint16_t *start, *end;
+ uint16_t sum;
sum = 0;
- start = (u_short *)lp;
- end = (u_short *)&lp->d_partitions[lp->d_npartitions];
+ start = (uint16_t *)lp;
+ end = (uint16_t *)&lp->d_partitions[npartitions];
while (start < end)
sum ^= *start++;
return (sum);
Index: sbin/disklabel/dkcksum.h
===================================================================
RCS file: /vol/src/rsync-src/src/sbin/disklabel/dkcksum.h,v
retrieving revision 1.3
diff -u -r1.3 dkcksum.h
--- sbin/disklabel/dkcksum.h 24 Dec 2000 05:59:11 -0000 1.3
+++ sbin/disklabel/dkcksum.h 14 Jul 2009 20:58:42 -0000
@@ -1,3 +1,3 @@
/* $NetBSD: dkcksum.h,v 1.3 2000/12/24 05:59:11 lukem Exp $ */
-u_short dkcksum(struct disklabel *);
+uint16_t dkcksum(struct disklabel *, int);
Index: sbin/disklabel/main.c
===================================================================
RCS file: /vol/src/rsync-src/src/sbin/disklabel/main.c,v
retrieving revision 1.20
diff -u -r1.20 main.c
--- sbin/disklabel/main.c 4 May 2009 18:09:04 -0000 1.20
+++ sbin/disklabel/main.c 17 Jul 2009 00:04:06 -0000
@@ -180,6 +180,13 @@
#define GETNUM16(a, v) getulong(a, '\0', NULL, v, UINT16_MAX)
#define GETNUM8(a, v) getulong(a, '\0', NULL, v, UINT8_MAX)
+static void bswap_label (struct disklabel *);
+#if BYTE_ORDER != TARGET_ENDIANNESS
+#define BSWAP_LABEL(l) do { bswap_label(l); } while (0)
+#else
+#define BSWAP_LABEL(l)
+#endif
+
static int set_writable_fd = -1;
#if HAVE_NBTOOL_CONFIG_H
@@ -486,7 +493,7 @@
lab.d_magic = DISKMAGIC;
lab.d_magic2 = DISKMAGIC;
lab.d_checksum = 0;
- lab.d_checksum = dkcksum(&lab);
+ lab.d_checksum = dkcksum(&lab, lab.d_npartitions);
if (rflag) {
/* Write the label directly to the disk */
@@ -933,15 +940,12 @@
is_deleted = "deleted ";
}
if (lp->d_magic != DISKMAGIC) {
- /* XXX: Do something about byte-swapped labels ? */
if (lp->d_magic == DISKMAGIC_REV &&
lp->d_magic2 == DISKMAGIC_REV)
- warnx("ignoring %sbyteswapped label"
- " at offset %u from sector %u",
- is_deleted, offset, sector);
- continue;
+ bswap_label (lp);
}
- if (lp->d_npartitions > MAXPARTITIONS || dkcksum(lp) != 0) {
+ if (lp->d_npartitions > MAXPARTITIONS ||
+ dkcksum(lp, lp->d_npartitions) != 0) {
if (verbose > 0)
warnx("corrupt label found at offset %u in "
"sector %u", offset, sector);
@@ -1034,6 +1038,7 @@
}
*disk_lp = lab;
+ BSWAP_LABEL (disk_lp);
write_bootarea(f, label_sector);
return 1;
}
@@ -1895,3 +1900,64 @@
return ret;
}
+
+static void
+bswap_label (struct disklabel *l)
+{
+ uint16_t npartitions;
+ int i;
+
+ if (l->d_magic == DISKMAGIC && l->d_magic2 == DISKMAGIC)
+ npartitions = l->d_npartitions;
+ else if (l->d_magic == DISKMAGIC_REV && l->d_magic2 == DISKMAGIC_REV)
+ npartitions = bswap16 (l->d_npartitions);
+ else
+ return;
+
+ /* We need to make sure that we don't replace a bad checksum with a
+ * good one, but we don't need to tell anyone because we are preserving
+ * the bad checksum for others to check.
+ */
+ if (dkcksum(l, npartitions) != 0)
+ return;
+
+ l->d_magic = bswap32 (l->d_magic);
+ l->d_type = bswap16 (l->d_type);
+ l->d_subtype = bswap16 (l->d_subtype);
+
+ l->d_secsize = bswap32 (l->d_secsize);
+ l->d_nsectors = bswap32 (l->d_nsectors);
+ l->d_ntracks = bswap32 (l->d_ntracks);
+ l->d_ncylinders = bswap32 (l->d_ncylinders);
+ l->d_secpercyl = bswap32 (l->d_secpercyl);
+ l->d_secperunit = bswap32 (l->d_secperunit);
+
+ l->d_sparespertrack = bswap16 (l->d_sparespertrack);
+ l->d_sparespercyl = bswap16 (l->d_sparespercyl);
+
+ l->d_acylinders = bswap32 (l->d_acylinders);
+ l->d_rpm = bswap16 (l->d_rpm);
+ l->d_interleave = bswap16 (l->d_interleave);
+ l->d_trackskew = bswap16 (l->d_trackskew);
+ l->d_cylskew = bswap16 (l->d_cylskew);
+ l->d_headswitch = bswap32 (l->d_headswitch);
+ l->d_trkseek = bswap32 (l->d_trkseek);
+ l->d_flags = bswap32 (l->d_flags);
+ for (i = 0; i < NDDATA; i++)
+ l->d_drivedata[i] = bswap32 (l->d_drivedata[i]);
+ l->d_magic2 = bswap32 (l->d_magic2);
+
+ l->d_npartitions = bswap16 (l->d_npartitions);
+ l->d_bbsize = bswap32 (l->d_bbsize);
+ l->d_sbsize = bswap32 (l->d_sbsize);
+ for (i = 0; i < npartitions; i++)
+ {
+ l->d_partitions[i].p_size = bswap32 (l->d_partitions[i].p_size);
+ l->d_partitions[i].p_offset = bswap32
(l->d_partitions[i].p_offset);
+ l->d_partitions[i].p_fsize = bswap32
(l->d_partitions[i].p_fsize);
+ l->d_partitions[i].p_cpg = bswap16 (l->d_partitions[i].p_cpg);
+ }
+
+ l->d_checksum = 0;
+ l->d_checksum = dkcksum (l, npartitions);
+}
Index: sbin/mbrlabel/mbrlabel.c
===================================================================
RCS file: /vol/src/rsync-src/src/sbin/mbrlabel/mbrlabel.c,v
retrieving revision 1.26
diff -u -r1.26 mbrlabel.c
--- sbin/mbrlabel/mbrlabel.c 28 Dec 2005 06:03:15 -0000 1.26
+++ sbin/mbrlabel/mbrlabel.c 17 Jul 2009 00:11:04 -0000
@@ -87,7 +87,7 @@
int one = 1;
label.d_checksum = 0;
- label.d_checksum = dkcksum(&label);
+ label.d_checksum = dkcksum(&label, label.d_npartitions);
if (ioctl(sd, doraw ? DIOCWDINFO : DIOCSDINFO, &label) < 0) {
perror("set label");
exit(1);
Index: sbin/svhlabel/svhlabel.c
===================================================================
RCS file: /vol/src/rsync-src/src/sbin/svhlabel/svhlabel.c,v
retrieving revision 1.5
diff -u -r1.5 svhlabel.c
--- sbin/svhlabel/svhlabel.c 6 Apr 2009 12:33:11 -0000 1.5
+++ sbin/svhlabel/svhlabel.c 17 Jul 2009 00:28:19 -0000
@@ -91,7 +91,7 @@
int one = 1;
label.d_checksum = 0;
- label.d_checksum = dkcksum(&label);
+ label.d_checksum = dkcksum(&label, label.d_npartitions);
if (ioctl(sd, doraw ? DIOCWDINFO : DIOCSDINFO, &label) < 0) {
perror("set label");
exit(1);
Index: usr.sbin/mscdlabel/main.c
===================================================================
RCS file: /vol/src/rsync-src/src/usr.sbin/mscdlabel/main.c,v
retrieving revision 1.4
diff -u -r1.4 main.c
--- usr.sbin/mscdlabel/main.c 25 May 2006 00:42:23 -0000 1.4
+++ usr.sbin/mscdlabel/main.c 17 Jul 2009 00:36:38 -0000
@@ -199,7 +199,7 @@
label.d_npartitions = j;
strncpy(label.d_packname, "mscdlabel's", 16);
label.d_checksum = 0;
- label.d_checksum = dkcksum(&label);
+ label.d_checksum = dkcksum(&label, label.d_npartitions);
res = ioctl(fd, DIOCSDINFO, &label);
if (res < 0)
err(6, "DIOCSDINFO");
Home |
Main Index |
Thread Index |
Old Index