From cc266dcde014fe7b96a4f15314cb2e4a19b2f76b Mon Sep 17 00:00:00 2001 From: Nicolas Thill Date: Wed, 2 Sep 2009 00:15:31 +0000 Subject: [PATCH] dnsmasq: fix 2 DoS vulnerabilities in TFTP handling - CVE-2009-2957 - CVE-2009-2958 SVN-Revision: 17464 --- package/dnsmasq/Makefile | 2 +- .../patches/001-upstream-security.patch | 72 +++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 package/dnsmasq/patches/001-upstream-security.patch diff --git a/package/dnsmasq/Makefile b/package/dnsmasq/Makefile index 1b030d1ad0..eaa4fe2a2f 100644 --- a/package/dnsmasq/Makefile +++ b/package/dnsmasq/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dnsmasq PKG_VERSION:=2.47 -PKG_RELEASE:=3 +PKG_RELEASE:=3.1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq diff --git a/package/dnsmasq/patches/001-upstream-security.patch b/package/dnsmasq/patches/001-upstream-security.patch new file mode 100644 index 0000000000..f12d61fe57 --- /dev/null +++ b/package/dnsmasq/patches/001-upstream-security.patch @@ -0,0 +1,72 @@ +http://www.thekelleys.org.uk/dnsmasq/dnsmasq.security.patch +http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-2957 +http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-2958 + +--- a/src/tftp.c ++++ b/src/tftp.c +@@ -195,20 +195,21 @@ void tftp_request(struct listener *liste + + 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; +@@ -220,17 +221,17 @@ void tftp_request(struct listener *liste + { + 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)) +@@ -248,8 +249,7 @@ void tftp_request(struct listener *liste + } + 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))) -- 2.30.2