]> git.ipfire.org Git - people/ms/dnsmasq.git/commitdiff
import of dnsmasq-2.50.tar.gz
authorSimon Kelley <simon@thekelleys.org.uk>
Mon, 31 Aug 2009 16:32:17 +0000 (17:32 +0100)
committerSimon Kelley <simon@thekelleys.org.uk>
Thu, 5 Jan 2012 17:31:14 +0000 (17:31 +0000)
CHANGELOG
src/config.h
src/tftp.c

index 6911953d18c0b02619b71196cc7f8ebc982c5882..ad398a7d1d705b1d14a75834b965cd0d2b323b30 100644 (file)
--- 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.
index cd689c4c04935f93c54639fa8b9108798809f15a..92cbf6bf444586743cba29a1524b3c7484a8f73f 100644 (file)
@@ -14,7 +14,7 @@
    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 MAX_PROCS 20 /* max no children for TCP requests */
index a6cc7ea8a604766ec0fbc8d75cae197747bd2603..40d9143028f0ff9e09caea0de61c1aa0ae6436e9 100644 (file)
@@ -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)))