import of dnsmasq-2.50.tar.gz

This commit is contained in:
Simon Kelley
2009-08-31 17:32:17 +01:00
parent 03a97b6170
commit 77e94da7bb
3 changed files with 34 additions and 19 deletions

View File

@@ -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 version 2.49
Fix regression in 2.48 which disables the lease-change Fix regression in 2.48 which disables the lease-change
script. Thanks to Jose Luis Duran for spotting this. script. Thanks to Jose Luis Duran for spotting this.

View File

@@ -14,7 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define VERSION "2.49" #define VERSION "2.50"
#define FTABSIZ 150 /* max number of outstanding requests (default) */ #define FTABSIZ 150 /* max number of outstanding requests (default) */
#define MAX_PROCS 20 /* max no children for TCP requests */ #define MAX_PROCS 20 /* max no children for TCP requests */

View File

@@ -192,20 +192,21 @@ void tftp_request(struct listener *listen, time_t now)
while ((opt = next(&p, end))) while ((opt = next(&p, end)))
{ {
if (strcasecmp(opt, "blksize") == 0 && if (strcasecmp(opt, "blksize") == 0)
(opt = next(&p, end)) &&
!(daemon->options & OPT_TFTP_NOBLOCK))
{ {
transfer->blocksize = atoi(opt); if ((opt = next(&p, end)) &&
if (transfer->blocksize < 1) !(daemon->options & OPT_TFTP_NOBLOCK))
transfer->blocksize = 1; {
if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4) transfer->blocksize = atoi(opt);
transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4; if (transfer->blocksize < 1)
transfer->opt_blocksize = 1; transfer->blocksize = 1;
transfer->block = 0; if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
transfer->opt_blocksize = 1;
transfer->block = 0;
}
} }
else if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii)
if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii)
{ {
transfer->opt_transize = 1; transfer->opt_transize = 1;
transfer->block = 0; transfer->block = 0;
@@ -217,17 +218,17 @@ void tftp_request(struct listener *listen, time_t now)
{ {
if (daemon->tftp_prefix[0] == '/') if (daemon->tftp_prefix[0] == '/')
daemon->namebuff[0] = 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] != '/') 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) if (daemon->options & OPT_TFTP_APREF)
{ {
size_t oldlen = strlen(daemon->namebuff); size_t oldlen = strlen(daemon->namebuff);
struct stat statbuf; struct stat statbuf;
strncat(daemon->namebuff, inet_ntoa(peer.sin_addr), MAXDNAME); strncat(daemon->namebuff, inet_ntoa(peer.sin_addr), (MAXDNAME-1) - strlen(daemon->namebuff));
strncat(daemon->namebuff, "/", MAXDNAME); strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
/* remove unique-directory if it doesn't exist */ /* remove unique-directory if it doesn't exist */
if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode)) 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] == '/') else if (filename[0] == '/')
daemon->namebuff[0] = 0; daemon->namebuff[0] = 0;
strncat(daemon->namebuff, filename, MAXDNAME); strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
daemon->namebuff[MAXDNAME-1] = 0;
/* check permissions and open file */ /* check permissions and open file */
if ((transfer->file = check_tftp_fileperm(&len))) if ((transfer->file = check_tftp_fileperm(&len)))