Module Name:src
Committed By: bouyer
Date: Fri May 20 19:32:44 UTC 2011
Modified Files:
src/sys/arch/x68k/x68k [netbsd-5]: disksubr.c
Log Message:
Pull up following revision(s) (requested by tsutsui in ticket #1621):
sys/arch/x68k/x68k/disksubr.c: revision 1.34
Fix buffer overrun in readdisklabel(9) (and writedisklabel(9))
that causes unexpected panic during installation and
DIAGNOSTIC pool assertions.
Also fix bp-b_flags in writedisklabel(9) error path.
The problem was reported from Y.Sugahara during XM6i development,
and this fix is confirmed on both X68030 (by me) and XM6i (by Sugahara).
XXX: broken dkbad support (which makes struct cpu_disklabel larger
XXX: than 512 bytes) should be removed...
To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.33.20.1 src/sys/arch/x68k/x68k/disksubr.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/x68k/x68k/disksubr.c
diff -u src/sys/arch/x68k/x68k/disksubr.c:1.33 src/sys/arch/x68k/x68k/disksubr.c:1.33.20.1
--- src/sys/arch/x68k/x68k/disksubr.c:1.33 Wed Jan 2 11:48:32 2008
+++ src/sys/arch/x68k/x68k/disksubr.c Fri May 20 19:32:44 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: disksubr.c,v 1.33 2008/01/02 11:48:32 ad Exp $ */
+/* $NetBSD: disksubr.c,v 1.33.20.1 2011/05/20 19:32:44 bouyer Exp $ */
/*
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
@@ -32,7 +32,7 @@
*/
#include sys/cdefs.h
-__KERNEL_RCSID(0, $NetBSD: disksubr.c,v 1.33 2008/01/02 11:48:32 ad Exp $);
+__KERNEL_RCSID(0, $NetBSD: disksubr.c,v 1.33.20.1 2011/05/20 19:32:44 bouyer Exp $);
#include opt_compat_netbsd.h
@@ -69,7 +69,7 @@
struct buf *bp;
struct disklabel *dlp;
const char *msg = NULL;
- int i, labelsz;
+ int i, bsdlabelsz, humanlabelsz;
if (osdep)
dp = osdep-dosparts;
@@ -90,15 +90,19 @@
lp-d_partitions[0].p_offset = 0;
/* get a buffer and initialize it */
- bp = geteblk((int)lp-d_secsize);
+ bsdlabelsz =
+ howmany(LABELOFFSET + sizeof(struct disklabel), lp-d_secsize)
+ * lp-d_secsize;
+ humanlabelsz =
+ howmany(sizeof(struct cpu_disklabel), lp-d_secsize)
+ * lp-d_secsize;
+ bp = geteblk(MAX(bsdlabelsz, humanlabelsz));
bp-b_dev = dev;
/* read BSD disklabel first */
bp-b_blkno = LABELSECTOR;
bp-b_cylinder = LABELSECTOR/lp-d_secpercyl;
- labelsz = howmany(LABELOFFSET+sizeof(struct disklabel), lp-d_secsize)
- * lp-d_secsize;
- bp-b_bcount = labelsz; /* to support 512B/sector disks */
+ bp-b_bcount = bsdlabelsz; /* to support 512B/sector disks */
bp-b_flags |= B_READ;
(*strat)(bp);
@@ -109,7 +113,7 @@
}
for (dlp = (struct disklabel *)bp-b_data;
dlp = (struct disklabel *)
- ((char *)bp-b_data + labelsz - sizeof(*dlp));
+ ((char *)bp-b_data + bsdlabelsz - sizeof(*dlp));
dlp = (struct disklabel *)((uint8_t *)dlp + sizeof(long))) {
if (dlp-d_magic != DISKMAGIC || dlp-d_magic2 != DISKMAGIC) {
if (msg == NULL)
@@ -135,9 +139,7 @@
bp-b_blkno = DOSPARTOFF * DEF_BSIZE / lp-d_secsize;
/* DOSPARTOFF in DEV_BSIZE unit */
bp-b_cylinder = DOSBBSECTOR / lp-d_secpercyl;
- labelsz = howmany(sizeof(struct cpu_disklabel),
- lp-d_secsize) * lp-d_secsize;
- bp-b_bcount = labelsz; /* to support 512B/sector disks */
+ bp-b_bcount = humanlabelsz; /* to support 512B/sector disks */
bp-b_oflags = ~(BO_DONE);
(*strat)(bp);
@@ -313,7 +315,7 @@
struct dos_partition *dp = 0;
struct buf *bp;
struct disklabel *dlp;
- int error, labelsz, i;
+ int error, bsdlabelsz, humanlabelsz, i;
const char *np;
if (osdep)
@@ -326,15 +328,19 @@
parttbl_consistency_check(lp, dp);
/* get a buffer and initialize it */
- bp = geteblk((int)lp-d_secsize);
+ bsdlabelsz =
+ howmany(LABELOFFSET + sizeof(struct disklabel), lp-d_secsize)
+ * lp-d_secsize;
+ humanlabelsz =
+ howmany(sizeof(struct cpu_disklabel), lp-d_secsize)
+ * lp-d_secsize;
+ bp = geteblk(MAX(bsdlabelsz, humanlabelsz));
bp-b_dev = dev;
/* attempt to write BSD disklabel first */
bp-b_blkno = LABELSECTOR;
bp-b_cylinder = LABELSECTOR / lp-d_secpercyl;
- labelsz = howmany(LABELOFFSET+sizeof(struct disklabel), lp-d_secsize)
- * lp-d_secsize;
- bp-b_bcount = labelsz; /* to support 512B/sector disks */
+ bp-b_bcount = bsdlabelsz; /* to support 512B/sector disks */
bp-b_flags |= B_READ;
(*strat)(bp);
@@ -344,7 +350,7 @@
error = ESRCH;
for (dlp = (struct disklabel *)bp-b_data;
dlp = (struct disklabel *)
- ((char *)bp-b_data + labelsz - sizeof(*dlp));
+ ((char *)bp-b_data + bsdlabelsz - sizeof(*dlp));
dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
if (dlp-d_magic == DISKMAGIC dlp-d_magic2 == DISKMAGIC
dkcksum(dlp) == 0) {
@@ -370,6 +376,7 @@
bp-b_blkno = DOSBBSECTOR;
bp-b_bcount = lp-d_secsize;
bp-b_oflags = ~(BO_DONE);
+ bp-b_flags = ~(B_WRITE);
bp-b_flags |= B_READ;
bp-b_cylinder = DOSBBSECTOR / lp-d_secpercyl;