From dd8b45ebc6848b7521095c87a3303f93356bb43a Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 1 Mar 2007 21:30:50 +0000 Subject: [PATCH] Split the disklabel checksum function into two, so we can pass the length separately. Use this for foreign-endianess labels in wedge autodiscovery, and calculate the checksum of those before we swap various fields in the label. --- sys/dev/dkwedge/dkwedge_bsdlabel.c | 10 +++++++--- sys/kern/subr_disk.c | 12 +++++++++--- sys/sys/disklabel.h | 3 ++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/sys/dev/dkwedge/dkwedge_bsdlabel.c b/sys/dev/dkwedge/dkwedge_bsdlabel.c index c05e9a8040fe..aef19cac24a8 100644 --- a/sys/dev/dkwedge/dkwedge_bsdlabel.c +++ b/sys/dev/dkwedge/dkwedge_bsdlabel.c @@ -1,4 +1,4 @@ -/* $NetBSD: dkwedge_bsdlabel.c,v 1.9 2006/11/16 01:32:50 christos Exp $ */ +/* $NetBSD: dkwedge_bsdlabel.c,v 1.10 2007/03/01 21:30:50 martin Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -86,7 +86,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: dkwedge_bsdlabel.c,v 1.9 2006/11/16 01:32:50 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dkwedge_bsdlabel.c,v 1.10 2007/03/01 21:30:50 martin Exp $"); #include #include @@ -226,6 +226,7 @@ validate_label(mbr_args_t *a, daddr_t label_sector, size_t label_offset) struct disklabel *lp; caddr_t lp_lim; int i, error; + u_int checksum; error = dkwedge_read(a->pdk, a->vp, label_sector, a->buf, DEV_BSIZE); if (error) { @@ -264,6 +265,8 @@ validate_label(mbr_args_t *a, daddr_t label_sector, size_t label_offset) bswap16(lp->d_npartitions)); continue; } + checksum = dkcksum_sized(lp, + bswap16(lp->d_npartitions)); swap_disklabel(lp); } else continue; @@ -279,13 +282,14 @@ validate_label(mbr_args_t *a, daddr_t label_sector, size_t label_offset) label_offset, lp->d_npartitions); continue; } + checksum = dkcksum(lp); } /* * Disklabel is now in the right order and we have validated * the partition count, checksum it as the final check. */ - if (dkcksum(lp) != 0) { + if (checksum != 0) { aprint_error("%s: BSD disklabel @ %" PRId64 "+%zd has bad checksum\n", a->pdk->dk_name, label_sector, label_offset); diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index 71b2a233bda5..3aeeb5a4d4bc 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -1,4 +1,4 @@ -/* $NetBSD: subr_disk.c,v 1.83 2006/11/25 11:59:58 scw Exp $ */ +/* $NetBSD: subr_disk.c,v 1.84 2007/03/01 21:30:50 martin Exp $ */ /*- * Copyright (c) 1996, 1997, 1999, 2000 The NetBSD Foundation, Inc. @@ -74,7 +74,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.83 2006/11/25 11:59:58 scw Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.84 2007/03/01 21:30:50 martin Exp $"); #include #include @@ -91,12 +91,18 @@ __KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.83 2006/11/25 11:59:58 scw Exp $"); */ u_int dkcksum(struct disklabel *lp) +{ + return dkcksum_sized(lp, lp->d_npartitions); +} + +u_int +dkcksum_sized(struct disklabel *lp, size_t npartitions) { u_short *start, *end; u_short sum = 0; start = (u_short *)lp; - end = (u_short *)&lp->d_partitions[lp->d_npartitions]; + end = (u_short *)&lp->d_partitions[npartitions]; while (start < end) sum ^= *start++; return (sum); diff --git a/sys/sys/disklabel.h b/sys/sys/disklabel.h index e87e3e4a8f50..ba4ef48b8fd4 100644 --- a/sys/sys/disklabel.h +++ b/sys/sys/disklabel.h @@ -1,4 +1,4 @@ -/* $NetBSD: disklabel.h,v 1.97 2005/12/29 14:53:47 tsutsui Exp $ */ +/* $NetBSD: disklabel.h,v 1.98 2007/03/01 21:30:50 martin Exp $ */ /* * Copyright (c) 1987, 1988, 1993 @@ -436,6 +436,7 @@ struct disk; void diskerr(const struct buf *, const char *, const char *, int, int, const struct disklabel *); u_int dkcksum(struct disklabel *); +u_int dkcksum_sized(struct disklabel *, size_t); int setdisklabel(struct disklabel *, struct disklabel *, u_long, struct cpu_disklabel *); const char *readdisklabel(dev_t, void (*)(struct buf *),