⬢ DragonFlyBSD Kernel Audit
DF-3356 / fix.diff
← back to finding ↓ download raw
--- a/sys/net/dummynet3/ip_dummynet3.c
+++ b/sys/net/dummynet3/ip_dummynet3.c
@@ -637,9 +637,14 @@
 	if (p->numbytes < 0) { /* This implies bandwidth>0 */
 		dn_key t = 0; /* Number of ticks i have to wait */
 
-		if (p->bandwidth > 0)
+		if (p->bandwidth > 0) {
+			struct dn_pkt *last;
+
 			t = (p->bandwidth - 1 - p->numbytes) / p->bandwidth;
-		TAILQ_LAST(&p->p_queue, dn_pkt_queue)->output_time += t;
+			last = TAILQ_LAST(&p->p_queue, dn_pkt_queue);
+			if (last != NULL)
+				last->output_time += t;
+		}
 		p->sched_time = curr_time;
 
 		/*
@@ -1372,6 +1377,8 @@
 
 	/* Fill the lookup table with (1 - w_q)^x */
 	x->lookup_step = ioc_fs->lookup_step;
+	if (x->lookup_step < 1)
+		x->lookup_step = 1;
 	x->lookup_weight = ioc_fs->lookup_weight;
 
 	x->w_q_lookup[0] = SCALE(1) - x->w_q;
@@ -1440,10 +1447,10 @@
 	x->plr = ioc_fs->plr;
 	set_flowid_parms(&x->flow_mask, &ioc_fs->flow_mask);
 	if (x->flags_fs & DN_QSIZE_IS_BYTES) {
-		if (x->qsize > 1024 * 1024)
+		if (x->qsize > 1024 * 1024 || x->qsize < 0)
 			x->qsize = 1024 * 1024;
 	} else {
-		if (x->qsize == 0 || x->qsize > 100)
+		if (x->qsize <= 0 || x->qsize > 100)
 			x->qsize = 50;
 	}
 
@@ -1483,6 +1490,8 @@
 	 */
 	if (ioc_pipe->pipe_nr > DN_PIPE_NR_MAX || ioc_pipe->pipe_nr < 0)
 		return EINVAL;
+	if (ioc_pipe->bandwidth < 0)
+		return EINVAL;
 
 	error = EINVAL;
 	if (ioc_pipe->pipe_nr != 0) {	/* This is a pipe */
@@ -1545,7 +1554,7 @@
 			x->fs_nr = ioc_fs->fs_nr;
 			x->parent_nr = ioc_fs->parent_nr;
 			x->weight = ioc_fs->weight;
-			if (x->weight == 0)
+			if (x->weight <= 0)
 				x->weight = 1;
 			else if (x->weight > 100)
 				x->weight = 100;
@@ -1624,6 +1633,7 @@
 		kprintf("++ ref to pipe %d from fs %d\n",
 				pipe->pipe_nr, fs->fs_nr);
 		fs->pipe = NULL;
+		fs->backlogged = 0;
 		purge_flow_set(fs, 0);
 	}
 }