DragonFlyBSD Kernel Audit
DF-2953 / fix.diff
← back to finding ↓ download raw
--- a/sys/kern/subr_log.c
+++ b/sys/kern/subr_log.c
@@ -79,6 +79,8 @@
 	struct	kqinfo	sc_kqp;		/* processes waiting on I/O */
 	struct  sigio *sc_sigio;	/* information for async I/O */
 	struct	callout sc_callout;	/* callout to wakeup syslog  */
+	struct	lock sc_lock;		/* interlocks sc_sigio; real lock
+					   (holdable across blocking) */
 } logsoftc;
 
 int	log_open;			/* also used in log() */
@@ -99,7 +101,9 @@
 		return (EBUSY);
 	log_open = 1;
 	callout_init_mp(&logsoftc.sc_callout);
+	lockmgr(&logsoftc.sc_lock, LK_EXCLUSIVE);
 	fsetown(p->p_pid, &logsoftc.sc_sigio);	/* signal process only */
+	lockmgr(&logsoftc.sc_lock, LK_RELEASE);
 	callout_reset(&logsoftc.sc_callout, hz / log_wakeups_per_second,
 		      logtimeout, NULL);
 	return (0);
@@ -112,7 +116,9 @@
 	log_open = 0;
 	callout_terminate(&logsoftc.sc_callout);
 	logsoftc.sc_state = 0;
+	lockmgr(&logsoftc.sc_lock, LK_EXCLUSIVE);
 	funsetown(&logsoftc.sc_sigio);
+	lockmgr(&logsoftc.sc_lock, LK_RELEASE);
 	return (0);
 }
 
@@ -244,8 +250,12 @@
 	}
 	msgbuftrigger = 0;
 	KNOTE(&logsoftc.sc_kqp.ki_note, 0);
-	if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL)
-		pgsigio(logsoftc.sc_sigio, SIGIO, 0);
+	if (logsoftc.sc_state & LOG_ASYNC) {
+		lockmgr(&logsoftc.sc_lock, LK_EXCLUSIVE);
+		if (logsoftc.sc_sigio != NULL)
+			pgsigio(logsoftc.sc_sigio, SIGIO, 0);
+		lockmgr(&logsoftc.sc_lock, LK_RELEASE);
+	}
 	if (logsoftc.sc_state & LOG_RDWAIT) {
 		atomic_clear_int(&logsoftc.sc_state, LOG_RDWAIT);
 		wakeup((caddr_t)msgbufp);
@@ -289,16 +299,28 @@
 			atomic_clear_int(&logsoftc.sc_state, LOG_ASYNC);
 		break;
 
-	case FIOSETOWN:
-		return (fsetown(*(int *)ap->a_data, &logsoftc.sc_sigio));
+	case FIOSETOWN: {
+		int error;
+
+		lockmgr(&logsoftc.sc_lock, LK_EXCLUSIVE);
+		error = fsetown(*(int *)ap->a_data, &logsoftc.sc_sigio);
+		lockmgr(&logsoftc.sc_lock, LK_RELEASE);
+		return (error);
+	}
 
 	case FIOGETOWN:
 		*(int *)ap->a_data = fgetown(&logsoftc.sc_sigio);
 		break;
 
 	/* This is deprecated, FIOSETOWN should be used instead. */
-	case TIOCSPGRP:
-		return (fsetown(-(*(int *)ap->a_data), &logsoftc.sc_sigio));
+	case TIOCSPGRP: {
+		int error;
+
+		lockmgr(&logsoftc.sc_lock, LK_EXCLUSIVE);
+		error = fsetown(-(*(int *)ap->a_data), &logsoftc.sc_sigio);
+		lockmgr(&logsoftc.sc_lock, LK_RELEASE);
+		return (error);
+	}
 
 	/* This is deprecated, FIOGETOWN should be used instead */
 	case TIOCGPGRP:
@@ -314,6 +336,7 @@
 static void
 log_drvinit(void *unused)
 {
+	lockinit(&logsoftc.sc_lock, "klogsig", 0, 0);
 	make_dev(&log_ops, 0, UID_ROOT, GID_WHEEL, 0600, "klog");
 }