[PATCH 21/41] udp.c: Do not send NAKs in response to NAKs

Ian Jackson ijackson at chiark.greenend.org.uk
Thu Jul 25 18:40:47 BST 2013


If an incoming packet isn't name-addressed and has an invalid
destination site id, udp.c would send a NAK.  This is not a good idea
- if somehow the source site id was wrong too, it will result in a NAK
storm.

This is a security vulnerability as it can be used by an attacker to
trigger an unending NAK storm.

Also, improve the message printed when a NAK is sent by udp.c because
no site wanted to handle it.

Signed-off-by: Ian Jackson <ijackson at chiark.greenend.org.uk>
---
 udp.c |   31 ++++++++++++++++++++-----------
 1 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/udp.c b/udp.c
index 77be5b1..c83e618 100644
--- a/udp.c
+++ b/udp.c
@@ -133,17 +133,26 @@ static void udp_afterpoll(void *state, struct pollfd *fds, int nfds)
 		    }
 		}
 		if (!done) {
-		    uint32_t source,dest;
-		    /* Manufacture and send NAK packet */
-		    source=get_uint32(st->rbuf->start); /* Us */
-		    dest=get_uint32(st->rbuf->start+4); /* Them */
-		    Message(M_INFO,"udp (port %d): sending NAK\n",st->port);
-		    buffer_init(st->rbuf,0);
-		    buf_append_uint32(st->rbuf,dest);
-		    buf_append_uint32(st->rbuf,source);
-		    buf_append_uint32(st->rbuf,LABEL_NAK);
-		    sendto(st->fd, st->rbuf->start, st->rbuf->size, 0,
-			   (struct sockaddr *)&from, sizeof(from));
+		    uint32_t msgtype;
+		    if (st->rbuf->size>12 /* prevents traffic amplification */
+			&& ((msgtype=get_uint32(st->rbuf->start+8))
+			    != LABEL_NAK)) {
+			uint32_t source,dest;
+			/* Manufacture and send NAK packet */
+			source=get_uint32(st->rbuf->start); /* Us */
+			dest=get_uint32(st->rbuf->start+4); /* Them */
+			Message(M_INFO,"udp (port %d, peer %s):"
+				" %08"PRIx32"<-%08"PRIx32": %08"PRIx32":"
+				" unwanted/incorrect, sending NAK\n",
+				st->port, saddr_to_string(&from),
+				dest, source, msgtype);
+			buffer_init(st->rbuf,0);
+			buf_append_uint32(st->rbuf,dest);
+			buf_append_uint32(st->rbuf,source);
+			buf_append_uint32(st->rbuf,LABEL_NAK);
+			sendto(st->fd, st->rbuf->start, st->rbuf->size, 0,
+			       (struct sockaddr *)&from, sizeof(from));
+		    }
 		    BUF_FREE(st->rbuf);
 		}
 		BUF_ASSERT_FREE(st->rbuf);
-- 
1.7.2.5




More information about the sgo-software-discuss mailing list