DF-2953 / fix.diff
--- 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"); } |