diff options
author | joerg <joerg@FreeBSD.org> | 1996-12-23 01:53:13 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1996-12-23 01:53:13 +0000 |
commit | 365b171ddfb22a613bc2a8ab5db82d41f02d8537 (patch) | |
tree | ca0b7cc75bf2442a75285be27beeeebc569152c4 /sys/i386/isa/wt.c | |
parent | ba341fe3e82d8de79a6008e6a18c06798a167d2e (diff) | |
download | FreeBSD-src-365b171ddfb22a613bc2a8ab5db82d41f02d8537.zip FreeBSD-src-365b171ddfb22a613bc2a8ab5db82d41f02d8537.tar.gz |
Fix a bug in the wt driver that could cause memory corruption.
Closes PR # kern/1065.
While i was at it, also reject IO requests that are not an integer
multiple of the device blocksize.
Submitted by: vak@crox.net.kiae.su (Serge V.Vakulenko)
Confirmed by: Georg-W. Koltermann (gwk@cray.com)
Diffstat (limited to 'sys/i386/isa/wt.c')
-rw-r--r-- | sys/i386/isa/wt.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/sys/i386/isa/wt.c b/sys/i386/isa/wt.c index 2722bc2..c82a7e0 100644 --- a/sys/i386/isa/wt.c +++ b/sys/i386/isa/wt.c @@ -20,7 +20,7 @@ * the original CMU copyright notice. * * Version 1.3, Thu Nov 11 12:09:13 MSK 1993 - * $Id: wt.c,v 1.34 1996/08/31 14:47:45 bde Exp $ + * $Id: wt.c,v 1.35 1996/09/06 23:08:15 phk Exp $ * */ @@ -523,13 +523,20 @@ wtstrategy (struct buf *bp) int s; bp->b_resid = bp->b_bcount; - if (u >= NWT || t->type == UNKNOWN) - goto errxit; + if (u >= NWT || t->type == UNKNOWN) { + bp->b_error = ENXIO; + goto err2xit; + } /* at file marks and end of tape, we just return '0 bytes available' */ if (t->flags & TPVOL) goto xit; + if (bp->b_bcount % t->bsize != 0) { + bp->b_error = EINVAL; + goto err2xit; + } + if (bp->b_flags & B_READ) { /* Check read access and no previous write to this tape. */ if (! (t->flags & TPREAD) || (t->flags & TPWANY)) @@ -576,8 +583,8 @@ wtstrategy (struct buf *bp) splx (s); if (t->flags & TPEXCEP) { -errxit: bp->b_flags |= B_ERROR; - bp->b_error = EIO; +errxit: bp->b_error = EIO; +err2xit: bp->b_flags |= B_ERROR; } xit: biodone (bp); return; @@ -636,8 +643,6 @@ wtintr (int u) TRACE (("unexpected interrupt\n")); return; } - t->flags &= ~TPACTIVE; - t->dmacount += t->bsize; /* increment counter */ /* * Clean up dma. @@ -650,6 +655,10 @@ wtintr (int u) } else isa_dmadone (t->dmaflags, t->dmavaddr, t->bsize, t->chan); + t->flags &= ~TPACTIVE; + t->dmacount += t->bsize; + t->dmavaddr = (char *)t->dmavaddr + t->bsize; + /* * On exception, check for end of file and end of volume. */ @@ -665,7 +674,6 @@ wtintr (int u) } if (t->dmacount < t->dmatotal) { /* continue i/o */ - t->dmavaddr = (char *)t->dmavaddr + t->bsize; wtdma (t); TRACE (("continue i/o, %d\n", t->dmacount)); return; |