⬢ DragonFlyBSD Kernel Audit
DF-3044 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/nfs/bootp_subr.c
+++ b/sys/vfs/nfs/bootp_subr.c
@@ -588,6 +588,7 @@
 	int retry;
 	const char *s;
 	char hexstr[64];
+	struct sockaddr *fromp = NULL;
 	
 	/*
 	 * Create socket and set its recieve timeout.
@@ -804,7 +805,11 @@
 			auio.uio_td = td;
 			
 			rcvflg = 0;
-			error = soreceive(so, NULL, &auio,
+			if (fromp != NULL) {
+				kfree(fromp, M_SONAME);
+				fromp = NULL;
+			}
+			error = soreceive(so, &fromp, &auio,
 					  NULL, NULL, &rcvflg);
 			gctx->secs = time_uptime - gctx->starttime;
 			for (ifctx = gctx->interfaces;
@@ -820,6 +825,13 @@
 				continue;
 			if (error != 0)
 				goto out;
+			if (fromp == NULL ||
+				((struct sockaddr_in *)fromp)->sin_port !=
+				htons(IPPORT_BOOTPS)) {
+				kprintf("bootpc: reply not from server port %d, ignored\n",
+					IPPORT_BOOTPS);
+				continue;
+			}
 			len = sizeof(gctx->reply) - auio.uio_resid;
 			
 			/* Do we have the required number of bytes ? */
@@ -1535,7 +1547,7 @@
 
 	gctx = kmalloc(sizeof(*gctx), M_TEMP, M_WAITOK | M_ZERO);
 	
-	gctx->xid = ~0xFFFF;
+	gctx->xid = karc4random();
 	gctx->starttime = time_uptime;
 	
 	ifctx = allocifctx(gctx);