Clean up bounds_check_with_label(). Round request to sector size in label,

and return EINVAL if bcount is less than the sector size or negative.
This commit is contained in:
mycroft 1995-01-13 06:51:38 +00:00
parent 002aa598e1
commit dc63598a7f

View File

@ -1,4 +1,4 @@
/* $NetBSD: disksubr.c,v 1.14 1994/12/14 15:17:22 mycroft Exp $ */ /* $NetBSD: disksubr.c,v 1.15 1995/01/13 06:51:38 mycroft Exp $ */
/* /*
* Copyright (c) 1982, 1986, 1988 Regents of the University of California. * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
@ -352,55 +352,55 @@ done:
* if needed, and signal errors or early completion. * if needed, and signal errors or early completion.
*/ */
int int
bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) bounds_check_with_label(bp, lp, wlabel)
struct buf *bp;
struct disklabel *lp;
int wlabel;
{ {
struct partition *p = lp->d_partitions + DISKPART(bp->b_dev); struct partition *p = lp->d_partitions + DISKPART(bp->b_dev);
int labelsect = lp->d_partitions[0].p_offset; int labelsect = lp->d_partitions[2].p_offset + LABELSECTOR;
int maxsz = p->p_size, int sz;
sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
/* overwriting disk label ? */ if (bp->b_bcount < lp->d_secsize) {
/* XXX should also protect bootstrap in first 8K */ /* No whole sectors requested. */
if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect && bp->b_error = EINVAL;
goto bad;
}
sz = (bp->b_bcount + lp->d_secsize - 1) / lp->d_secsize;
/* Overwriting disk label? */
/* XXX Also protect MBR and boot program? */
if (bp->b_blkno + p->p_offset <= labelsect &&
#if LABELSECTOR != 0 #if LABELSECTOR != 0
bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect && bp->b_blkno + p->p_offset + sz > labelsect &&
#endif #endif
(bp->b_flags & B_READ) == 0 && wlabel == 0) { (bp->b_flags & B_READ) == 0 && wlabel == 0) {
bp->b_error = EROFS; bp->b_error = EROFS;
goto bad; goto bad;
} }
#if defined(DOSBBSECTOR) && defined(notyet) if (bp->b_blkno + sz > p->p_size) {
/* overwriting master boot record? */ sz = p->p_size - bp->b_blkno;
if (bp->b_blkno + p->p_offset <= DOSBBSECTOR && if (sz == 0) {
(bp->b_flags & B_READ) == 0 && wlabel == 0) { /* If exactly at end of disk, return EOF. */
bp->b_error = EROFS; bp->b_resid = bp->b_bcount;
goto bad; return (0);
} if (sz < 0) {
#endif /* If past end of disk, return EINVAL. */
/* beyond partition? */
if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
/* if exactly at end of disk, return an EOF */
if (bp->b_blkno == maxsz) {
bp->b_resid = bp->b_bcount;
return(0);
}
/* or truncate if part of it fits */
sz = maxsz - bp->b_blkno;
if (sz <= 0) {
bp->b_error = EINVAL; bp->b_error = EINVAL;
goto bad; goto bad;
} }
bp->b_bcount = sz << DEV_BSHIFT; /* Otherwise, truncate request. */
} bp->b_bcount = sz << DEV_BSHIFT;
}
/* calculate cylinder for disksort to order transfers with */ /* calculate cylinder for disksort to order transfers with */
bp->b_cylin = (bp->b_blkno + p->p_offset) / lp->d_secpercyl; bp->b_cylin = (bp->b_blkno + p->p_offset) / lp->d_secpercyl;
return(1); return (1);
bad: bad:
bp->b_flags |= B_ERROR; bp->b_flags |= B_ERROR;
return(-1); return (-1);
} }