⬢ DragonFlyBSD Kernel Audit
DF-3495 / probe.diff
← back to finding ↓ download raw
--- a/ng_l2tp.c
+++ b/ng_l2tp.c
@@ -57,6 +57,9 @@
 #include <sys/errno.h>
 #include <sys/libkern.h>
 #include <sys/thread2.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <machine/atomic.h>
 
 #include <netgraph/ng_message.h>
 #include <netgraph/netgraph.h>
@@ -95,6 +98,27 @@
 #define L2TP_MAX_REXMIT_TO	30			/* default rexmit to */
 #define L2TP_DELAYED_ACK	((hz + 19) / 20)	/* delayed ack: 50 ms */
 
+/* ---- DF-3495 diagnostic probes (temporary, diagnostic build only) ---- */
+static u_int df_probe_frees, df_probe_deliv, df_probe_stale_inv;
+static u_int df_probe_stale_realloc, df_probe_hpriv_bad, df_probe_walkn;
+static u_quad_t df_probe_walkns;
+SYSCTL_NODE(_net_graph, OID_AUTO, l2probe, CTLFLAG_RW, 0, "DF3495 probes");
+SYSCTL_UINT(_net_graph_l2probe, OID_AUTO, frees, CTLFLAG_RD,
+    &df_probe_frees, 0, "session hook frees");
+SYSCTL_UINT(_net_graph_l2probe, OID_AUTO, deliv, CTLFLAG_RD,
+    &df_probe_deliv, 0, "data deliveries attempted");
+SYSCTL_UINT(_net_graph_l2probe, OID_AUTO, stale_inv, CTLFLAG_RD,
+    &df_probe_stale_inv, 0, "stale hook with HK_INVALID at delivery");
+SYSCTL_UINT(_net_graph_l2probe, OID_AUTO, stale_realloc, CTLFLAG_RD,
+    &df_probe_stale_realloc, 0, "stale hook REALLOCATED as another hook");
+SYSCTL_UINT(_net_graph_l2probe, OID_AUTO, hpriv_bad, CTLFLAG_RD,
+    &df_probe_hpriv_bad, 0, "stale hpriv mismatch at delivery");
+SYSCTL_UINT(_net_graph_l2probe, OID_AUTO, walkn, CTLFLAG_RD,
+    &df_probe_walkn, 0, "offset-strip walks");
+SYSCTL_QUAD(_net_graph_l2probe, OID_AUTO, walkns, CTLFLAG_RD,
+    &df_probe_walkns, 0, "offset-strip walk total ns");
+/* --------------------------------------------------------------------- */
+
 /* Default data sequence number configuration for new sessions */
 #define L2TP_CONTROL_DSEQ	1			/* we are the lns */
 #define L2TP_ENABLE_DSEQ	1			/* enable data seq # */
@@ -661,6 +685,7 @@
 	else {
 		kfree(NG_HOOK_PRIVATE(hook), M_NETGRAPH_L2TP);
 		NG_HOOK_SET_PRIVATE(hook, NULL);
+		df_probe_frees++;
 	}
 
 	/* Go away if no longer connected to anything */
@@ -800,7 +825,9 @@
 	/* Strip offset padding if present */
 	if ((hdr & L2TP_HDR_OFF) != 0) {
 		u_int16_t offset;
+		struct timespec df_tp0, df_tp1;
 
+		nanouptime(&df_tp0);
 		/* Get length of offset padding */
 		if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) {
 			priv->stats.memoryFailures++;
@@ -817,6 +844,10 @@
 			return (EINVAL);
 		}
 		m_adj(m, offset);
+		nanouptime(&df_tp1);
+		df_probe_walkn++;
+		df_probe_walkns += (df_tp1.tv_sec - df_tp0.tv_sec) * 1000000000ull
+		    + (df_tp1.tv_nsec - df_tp0.tv_nsec);
 	}
 
 	/* Handle control packets */
@@ -878,6 +909,17 @@
 		return (0);
 	}
 
+	/* DF-3495 probes at the delivery point */
+	df_probe_deliv++;
+	if (hook->flags & HK_INVALID)
+		df_probe_stale_inv++;
+	if ((hook->flags & HK_INVALID) == 0 &&
+	    (hook->name == NULL || hook->name[0] != 's' ||
+	     strcmp(hook->name, "session_0001") != 0))
+		df_probe_stale_realloc++;
+	if (hpriv == NULL || hpriv->conf.session_id != ids[1])
+		df_probe_hpriv_bad++;
+
 	/* Deliver data */
 	NG_SEND_DATA(error, hook, m, meta);
 	return (error);