From bf28fc736c33aa8b26b3c3267cf4c3b33e69c4a5 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 25 Jul 2013 18:30:50 +0100 Subject: [PATCH] udp.c: Do not send NAKs in response to NAKs 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 --- udp.c | 31 ++++++++++++++++++++----------- 1 file 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); -- 2.30.2