⬢ DragonFlyBSD Kernel Audit
DF-3366 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/net/route.c b/sys/net/route.c
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -924,6 +924,17 @@
 		else
 			bcopy(dst, ndst, dst->sa_len);
 
+		/*
+		 * Zero the sockaddr alignment padding.  The key is
+		 * allocated RT_ROUNDUP(sa_len) bytes (rt_setgate) but
+		 * only sa_len bytes were initialized; rt_msg_buffer()
+		 * (rtsock.c) copies the full rounded length back to
+		 * userland when replying to -- potentially
+		 * unprivileged -- RTM_GET, disclosing stale heap data.
+		 */
+		bzero((char *)ndst + dst->sa_len,
+		      RT_ROUNDUP(dst->sa_len) - dst->sa_len);
+
 		if (rtinfo->rti_info[RTAX_MPLS1] != NULL)
 			rt_setshims(rt, rtinfo->rti_info);
 
@@ -1224,7 +1235,16 @@
 
 	/* Set the gateway value. */
 	rt->rt_gateway = (struct sockaddr *)(space + dlen);
-	bcopy(gate, rt->rt_gateway, glen);
+	/*
+	 * Copy only the valid bytes and zero the alignment padding:
+	 * glen (RT_ROUNDUP) may exceed gate's valid content -- the
+	 * final sockaddr of a route(4) message need not be padded --
+	 * and the full rounded length is copied back out by
+	 * rt_msg_buffer() on RTM_GET replies.
+	 */
+	bcopy(gate, rt->rt_gateway, gate->sa_len);
+	bzero((char *)rt->rt_gateway + gate->sa_len,
+	      glen - gate->sa_len);
 
 	if (oldspace != NULL) {
 		/*