git: 0620c99d278b - main - audit: Add poll / select support

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Fri, 05 Jun 2026 21:50:57 UTC
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=0620c99d278b6a2fd6fe995f5bb365158e04ad7c

commit 0620c99d278b6a2fd6fe995f5bb365158e04ad7c
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-06-05 21:50:38 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-06-05 21:50:38 +0000

    audit: Add poll / select support
    
    It was previously not possible to poll() or select() on the trigger
    device, which made implementing proper signal handling in auditd
    difficult.
    
    MFC after:      1 week
    Sponsored by:   Klara, Inc.
    Reviewed by:    kevans, markj
    Differential Revision:  https://reviews.freebsd.org/D57457
---
 sys/security/audit/audit_trigger.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/sys/security/audit/audit_trigger.c b/sys/security/audit/audit_trigger.c
index 482f7c56a2ef..e2520292cc5d 100644
--- a/sys/security/audit/audit_trigger.c
+++ b/sys/security/audit/audit_trigger.c
@@ -32,8 +32,10 @@
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
+#include <sys/poll.h>
 #include <sys/proc.h>
 #include <sys/queue.h>
+#include <sys/selinfo.h>
 #include <sys/systm.h>
 #include <sys/uio.h>
 
@@ -45,8 +47,6 @@
  * used to communicate with userland.  /dev/audit reliably delivers one-byte
  * messages to a listening application (or discards them if there is no
  * listening application).
- *
- * Currently, select/poll are not supported on the trigger device.
  */
 struct trigger_info {
 	unsigned int			trigger;
@@ -58,6 +58,7 @@ static struct cdev *audit_dev;
 static int audit_isopen = 0;
 static TAILQ_HEAD(, trigger_info) trigger_list;
 static struct mtx audit_trigger_mtx;
+static struct selinfo audit_trigger_rsel;
 
 static int
 audit_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
@@ -127,6 +128,22 @@ audit_write(struct cdev *dev, struct uio *uio, int ioflag)
 	return (EOPNOTSUPP);
 }
 
+static int
+audit_poll(struct cdev *dev, int events, struct thread *td)
+{
+	int revents = 0;
+
+	if (events & (POLLIN | POLLRDNORM)) {
+		mtx_lock(&audit_trigger_mtx);
+		if (!TAILQ_EMPTY(&trigger_list))
+			revents = events & (POLLIN | POLLRDNORM);
+		else
+			selrecord(td, &audit_trigger_rsel);
+		mtx_unlock(&audit_trigger_mtx);
+	}
+	return (revents);
+}
+
 int
 audit_send_trigger(unsigned int trigger)
 {
@@ -142,6 +159,7 @@ audit_send_trigger(unsigned int trigger)
 	}
 	ti->trigger = trigger;
 	TAILQ_INSERT_TAIL(&trigger_list, ti, list);
+	selwakeup(&audit_trigger_rsel);
 	wakeup(&trigger_list);
 	mtx_unlock(&audit_trigger_mtx);
 	return (0);
@@ -153,6 +171,7 @@ static struct cdevsw audit_cdevsw = {
 	.d_close =	audit_close,
 	.d_read =	audit_read,
 	.d_write =	audit_write,
+	.d_poll =	audit_poll,
 	.d_name =	"audit"
 };