diff options
author | simokawa <simokawa@FreeBSD.org> | 2003-04-14 14:17:49 +0000 |
---|---|---|
committer | simokawa <simokawa@FreeBSD.org> | 2003-04-14 14:17:49 +0000 |
commit | 1cfbbefd6c0c68b66ef5099fb1967e94e5542fd9 (patch) | |
tree | e571b29ee4e2302f4cdf58ce11f60d8c8931a826 /sys/dev/firewire | |
parent | 74d6d25d1acb1398a77eef0778b76c066259a259 (diff) | |
download | FreeBSD-src-1cfbbefd6c0c68b66ef5099fb1967e94e5542fd9.zip FreeBSD-src-1cfbbefd6c0c68b66ef5099fb1967e94e5542fd9.tar.gz |
Panic if bus_dmamap_load() doesn't respect maxsegsz.
Diffstat (limited to 'sys/dev/firewire')
-rw-r--r-- | sys/dev/firewire/sbp.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c index 0b66531..307b466 100644 --- a/sys/dev/firewire/sbp.c +++ b/sys/dev/firewire/sbp.c @@ -1816,13 +1816,14 @@ END_DEBUG bzero(sbp, sizeof(struct sbp_softc)); sbp->fd.dev = dev; sbp->fd.fc = device_get_ivars(dev); +#define SBP_SEG_MAX 0x8000 error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/0x100000, /*nsegments*/SBP_IND_MAX, - /*maxsegsz*/0x8000, + /*maxsegsz*/SBP_SEG_MAX, /*flags*/BUS_DMA_ALLOCNOW, &sbp->dmat); if (error != 0) { @@ -2356,8 +2357,11 @@ sbp_execute_ocb(void *arg, bus_dma_segment_t *segments, int seg, int error) ocb = (struct sbp_ocb *)arg; if (seg == 1) { /* direct pointer */ - ocb->orb[3] = htonl(segments[0].ds_addr); - ocb->orb[4] |= htonl(segments[0].ds_len); + s = &segments[0]; + if (s->ds_len > SBP_SEG_MAX) + panic("ds_len > SBP_SEG_MAX, fix busdma code"); + ocb->orb[3] = htonl(s->ds_addr); + ocb->orb[4] |= htonl(s->ds_len); } else if(seg > 1) { /* page table */ SBP_DEBUG(1) @@ -2384,6 +2388,8 @@ SBP_DEBUG(0) #endif "(seg=%d/%d)\n", s->ds_len, i+1, seg); END_DEBUG + if (s->ds_len > SBP_SEG_MAX) + panic("ds_len > SBP_SEG_MAX, fix busdma code"); ocb->ind_ptr[i].hi = htonl(s->ds_len << 16); ocb->ind_ptr[i].lo = htonl(s->ds_addr); } |