From 77e94da7bb3839872abca8e3b8733cfe649d404f Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Mon, 31 Aug 2009 17:32:17 +0100 Subject: [PATCH] import of dnsmasq-2.50.tar.gz --- CHANGELOG | 15 +++++++++++++++ src/config.h | 2 +- src/tftp.c | 36 ++++++++++++++++++------------------ 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6911953..ad398a7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,18 @@ +version 2.50 + Fix security problem which allowed any host permitted to + do TFTP to possibly compromise dnsmasq by remote buffer + overflow when TFTP enabled. Thanks to Core Security + Technologies and Iván Arce, Pablo Hernán Jorge, Alejandro + Pablo Rodriguez, Martín Coco, Alberto Soliño Testa and + Pablo Annetta. This problem has Bugtraq id: 36121 + and CVE: 2009-2957 + + Fix a problem which allowed a malicious TFTP client to + crash dnsmasq. Thanks to Steve Grubb at Red Hat for + spotting this. This problem has Bugtraq id: 36120 and + CVE: 2009-2958 + + version 2.49 Fix regression in 2.48 which disables the lease-change script. Thanks to Jose Luis Duran for spotting this. diff --git a/src/config.h b/src/config.h index cd689c4..92cbf6b 100644 --- a/src/config.h +++ b/src/config.h @@ -14,7 +14,7 @@ along with this program. If not, see . */ -#define VERSION "2.49" +#define VERSION "2.50" #define FTABSIZ 150 /* max number of outstanding requests (default) */ #define MAX_PROCS 20 /* max no children for TCP requests */ diff --git a/src/tftp.c b/src/tftp.c index a6cc7ea..40d9143 100644 --- a/src/tftp.c +++ b/src/tftp.c @@ -192,20 +192,21 @@ void tftp_request(struct listener *listen, time_t now) while ((opt = next(&p, end))) { - if (strcasecmp(opt, "blksize") == 0 && - (opt = next(&p, end)) && - !(daemon->options & OPT_TFTP_NOBLOCK)) + if (strcasecmp(opt, "blksize") == 0) { - transfer->blocksize = atoi(opt); - if (transfer->blocksize < 1) - transfer->blocksize = 1; - if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4) - transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4; - transfer->opt_blocksize = 1; - transfer->block = 0; + if ((opt = next(&p, end)) && + !(daemon->options & OPT_TFTP_NOBLOCK)) + { + transfer->blocksize = atoi(opt); + if (transfer->blocksize < 1) + transfer->blocksize = 1; + if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4) + transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4; + transfer->opt_blocksize = 1; + transfer->block = 0; + } } - - if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii) + else if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii) { transfer->opt_transize = 1; transfer->block = 0; @@ -217,17 +218,17 @@ void tftp_request(struct listener *listen, time_t now) { if (daemon->tftp_prefix[0] == '/') daemon->namebuff[0] = 0; - strncat(daemon->namebuff, daemon->tftp_prefix, MAXDNAME); + strncat(daemon->namebuff, daemon->tftp_prefix, (MAXDNAME-1) - strlen(daemon->namebuff)); if (daemon->tftp_prefix[strlen(daemon->tftp_prefix)-1] != '/') - strncat(daemon->namebuff, "/", MAXDNAME); + strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff)); if (daemon->options & OPT_TFTP_APREF) { size_t oldlen = strlen(daemon->namebuff); struct stat statbuf; - strncat(daemon->namebuff, inet_ntoa(peer.sin_addr), MAXDNAME); - strncat(daemon->namebuff, "/", MAXDNAME); + strncat(daemon->namebuff, inet_ntoa(peer.sin_addr), (MAXDNAME-1) - strlen(daemon->namebuff)); + strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff)); /* remove unique-directory if it doesn't exist */ if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode)) @@ -245,8 +246,7 @@ void tftp_request(struct listener *listen, time_t now) } else if (filename[0] == '/') daemon->namebuff[0] = 0; - strncat(daemon->namebuff, filename, MAXDNAME); - daemon->namebuff[MAXDNAME-1] = 0; + strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff)); /* check permissions and open file */ if ((transfer->file = check_tftp_fileperm(&len)))