DragonFlyBSD Kernel Audit
DF-2796 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c
index 1111111..3333333 100644
--- a/sys/kern/sysv_msg.c
+++ b/sys/kern/sysv_msg.c
@@ -1071,8 +1071,24 @@ static int
 sysctl_msqids(SYSCTL_HANDLER_ARGS)
 {
-	return (SYSCTL_OUT(req, msqids,
-		sizeof(struct msqid_ds) * msginfo.msgmni));
+	struct msqid_ds *snap;
+	size_t len = sizeof(struct msqid_ds) * (size_t)msginfo.msgmni;
+	int error, i;
+
+	/*
+	 * Do not export the live array: msg_first/msg_last are kernel
+	 * heap pointers and msg_pad* are never initialized.  Sanitize a
+	 * copy (DF-2796; same treatment IPC_STAT needs for DF-0050).
+	 */
+	snap = kmalloc(len, M_TEMP, M_WAITOK | M_ZERO);
+	if (snap == NULL)
+		return (ENOMEM);
+	lwkt_gettoken(&msg_token);
+	bcopy(msqids, snap, len);
+	lwkt_reltoken(&msg_token);
+	for (i = 0; i < msginfo.msgmni; i++) {
+		snap[i].msg_first = NULL;
+		snap[i].msg_last = NULL;
+	}
+	error = SYSCTL_OUT(req, snap, len);
+	kfree(snap, M_TEMP);
+	return (error);
 }