diff --git a/CHANGELOG b/CHANGELOG index 04ff3f0..0559a6f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,17 @@ +version 2.77 + Calculate the length of TFTP error reply packet + correctly. This fixes a problem when the error + message in a TFTP packet exceeds the arbitrary + limit of 500 characters. The message was correctly + truncated, but not the packet length, so + extra data was appended. This is a possible + security risk, since the extra data comes from + a buffer which is also used for DNS, so that + previous DNS queries or replies may be leaked. + Thanks to Mozilla for funding the security audit + which spotted this bug. + + version 2.76 Include 0.0.0.0/8 in DNS rebind checks. This range translates to hosts on the local network, or, at diff --git a/src/tftp.c b/src/tftp.c index 5e4a32a..3e1b5c5 100644 --- a/src/tftp.c +++ b/src/tftp.c @@ -652,20 +652,23 @@ static void sanitise(char *buf) } +#define MAXMESSAGE 500 /* limit to make packet < 512 bytes and definitely smaller than buffer */ static ssize_t tftp_err(int err, char *packet, char *message, char *file) { struct errmess { unsigned short op, err; char message[]; } *mess = (struct errmess *)packet; - ssize_t ret = 4; + ssize_t len, ret = 4; char *errstr = strerror(errno); sanitise(file); mess->op = htons(OP_ERR); mess->err = htons(err); - ret += (snprintf(mess->message, 500, message, file, errstr) + 1); + len = snprintf(mess->message, MAXMESSAGE, message, file, errstr); + ret += (len < MAXMESSAGE) ? len + 1 : MAXMESSAGE; /* include terminating zero */ + my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message); return ret;