⬢ DragonFlyBSD Kernel Audit
DF-2294 / fix.diff
← back to finding ↓ download raw
--- sys/bus/firewire/fwdev.c	2026-10-18 07:35:04.530601456 +0000
+++ sys/bus/firewire/fwdev.c	2026-10-18 07:35:04.542601304 +0000
@@ -100,6 +100,9 @@
 	if (q->flag & (FWXFERQ_RUNNING | FWXFERQ_EXTBUF))
 		return(EBUSY);
 
+	if (b->psize <= 0 || b->nchunk <= 0 || b->npacket <= 0)
+		return(EINVAL);
+
 	q->bulkxfer = (struct fw_bulkxfer *) kmalloc(
 		sizeof(struct fw_bulkxfer) * b->nchunk,
 		M_FW, M_WAITOK);
@@ -267,6 +270,7 @@
 	int err = 0, slept = 0;
 	int unit = DEV2UNIT(dev);
 	struct fw_pkt *fp;
+	u_int ulen;
 
 	if (DEV_FWMEM(dev))
 		return physread(ap);
@@ -326,8 +330,10 @@
 			err = EIO;
 			return err;
 		}
-		err = uiomove((caddr_t)fp,
-			fp->mode.stream.len + sizeof(u_int32_t), uio);
+		ulen = fp->mode.stream.len + sizeof(u_int32_t);
+		if (ulen > ir->psize)
+			ulen = ir->psize;
+		err = uiomove((caddr_t)fp, ulen, uio);
 		ir->queued ++;
 		if(ir->queued >= ir->bnpacket){
 			crit_enter();
@@ -528,6 +534,10 @@
 
 		if ((tinfo->flag & FWTI_BLOCK_ASY) != 0)
 			pay_len = MAX(0, asyreq->req.len - tinfo->hdr_len);
+		if (pay_len > sizeof(asyreq->data)) {
+			err = EINVAL;
+			break;
+		}
 
 		xfer = fw_xfer_alloc_buf(M_FWXFER, pay_len, PAGE_SIZE/*XXX*/);
 		if (xfer == NULL)
@@ -590,6 +600,10 @@
 		sc->fc->ibr(sc->fc);
 		break;
 	case FW_CBINDADDR:
+		if (ir == NULL) {
+			err = EINVAL;
+			break;
+		}
 		fwb = fw_bindlookup(sc->fc,
 				bindreq->start.hi, bindreq->start.lo);
 		if(fwb == NULL){
@@ -601,6 +615,10 @@
 		kfree(fwb, M_FW);
 		break;
 	case FW_SBINDADDR:
+		if (ir == NULL) {
+			err = EINVAL;
+			break;
+		}
 		if(bindreq->len <= 0 ){
 			err = EINVAL;
 			break;