DragonFlyBSD Kernel Audit
DF-2145 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/linux_tasklet.c b/sys/dev/drm/linux_tasklet.c
--- a/sys/dev/drm/linux_tasklet.c
+++ b/sys/dev/drm/linux_tasklet.c
@@ -169,9 +169,31 @@
 void
 tasklet_kill(struct tasklet_struct *t)
 {
+	struct tasklet_entry *te;
+
 	set_bit(TASKLET_IS_DYING, &t->state);
 	wakeup(&tasklet_runner);
 	tasklet_unlock_wait(t);
+
+	/* Ensure no dangling tasklet_entry remains on any queue */
+	lockmgr(&tasklet_lock, LK_EXCLUSIVE);
+	STAILQ_FOREACH(te, &tlist, tasklet_entries) {
+		if (te->ts == t) {
+			STAILQ_REMOVE(&tlist, te, tasklet_entry,
+			    tasklet_entries);
+			kfree(te);
+			break;
+		}
+	}
+	STAILQ_FOREACH(te, &tlist_hi, tasklet_entries) {
+		if (te->ts == t) {
+			STAILQ_REMOVE(&tlist_hi, te, tasklet_entry,
+			    tasklet_entries);
+			kfree(te);
+			break;
+		}
+	}
+	lockmgr(&tasklet_lock, LK_RELEASE);
 }
 
 int