]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/ccp.c
Because of a bug in zlib, restrict deflate parameter to 9..15 for now.
[ppp.git] / pppd / ccp.c
index 7cfd692fd3558409bcf64c3f117db725c56a8437..3a5fc97fd4cda019602d14013cb3c7322e437f41 100644 (file)
@@ -25,7 +25,7 @@
  * OR MODIFICATIONS.
  */
 
-#define RCSID  "$Id: ccp.c,v 1.30 2000/04/15 01:27:11 masputra Exp $"
+#define RCSID  "$Id: ccp.c,v 1.31 2001/02/22 03:10:06 paulus Exp $"
 
 #include <stdlib.h>
 #include <string.h>
 
 static const char rcsid[] = RCSID;
 
+/*
+ * Unfortunately there is a bug in zlib which means that using a
+ * size of 8 (window size = 256) for Deflate compression will cause
+ * buffer overruns and kernel crashes in the deflate module.
+ * Until this is fixed we only accept sizes in the range 9 .. 15.
+ * Thanks to James Carlson for pointing this out.
+ */
+#define DEFLATE_MIN_WORKS      9
+
 /*
  * Command-line options.
  */
@@ -56,7 +65,7 @@ static option_t ccp_option_list[] = {
     { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
       "don't allow BSD-Compress", OPT_A2COPY,
       &ccp_allowoptions[0].bsd_compress },
-    { "deflate", 1, (void *)setdeflate,
+    { "deflate", o_special, (void *)setdeflate,
       "request Deflate compression" },
     { "nodeflate", o_bool, &ccp_wantoptions[0].deflate,
       "don't allow Deflate compression", OPT_A2COPY,
@@ -234,6 +243,14 @@ setdeflate(argv)
                     DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
        return 0;
     }
+    if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) {
+       if (rbits == DEFLATE_MIN_SIZE)
+           rbits = DEFLATE_MIN_WORKS;
+       if (abits == DEFLATE_MIN_SIZE)
+           abits = DEFLATE_MIN_WORKS;
+       warn("deflate option value of %d changed to %d to avoid zlib bug",
+            DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS);
+    }
     if (rbits > 0) {
        ccp_wantoptions[0].deflate = 1;
        ccp_wantoptions[0].deflate_size = rbits;
@@ -440,7 +457,7 @@ ccp_resetci(f)
        if (go->deflate_correct) {
            opt_buf[0] = CI_DEFLATE;
            opt_buf[1] = CILEN_DEFLATE;
-           opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE);
+           opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS);
            opt_buf[3] = DEFLATE_CHK_SEQUENCE;
            if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
                go->deflate_correct = 0;
@@ -448,7 +465,7 @@ ccp_resetci(f)
        if (go->deflate_draft) {
            opt_buf[0] = CI_DEFLATE_DRAFT;
            opt_buf[1] = CILEN_DEFLATE;
-           opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE);
+           opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS);
            opt_buf[3] = DEFLATE_CHK_SEQUENCE;
            if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
                go->deflate_draft = 0;
@@ -514,7 +531,7 @@ ccp_addci(f, p, lenp)
                p += CILEN_DEFLATE;
                break;
            }
-           if (res < 0 || go->deflate_size <= DEFLATE_MIN_SIZE) {
+           if (res < 0 || go->deflate_size <= DEFLATE_MIN_WORKS) {
                go->deflate = 0;
                break;
            }
@@ -675,7 +692,7 @@ ccp_nakci(f, p, len)
         * Stop asking for Deflate if we don't understand his suggestion.
         */
        if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
-           || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_SIZE
+           || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS
            || p[3] != DEFLATE_CHK_SEQUENCE)
            try.deflate = 0;
        else if (DEFLATE_SIZE(p[2]) < go->deflate_size)
@@ -842,7 +859,7 @@ ccp_reqci(f, p, lenp, dont_nak)
                ho->deflate_size = nb = DEFLATE_SIZE(p[2]);
                if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
                    || p[3] != DEFLATE_CHK_SEQUENCE
-                   || nb > ao->deflate_size || nb < DEFLATE_MIN_SIZE) {
+                   || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) {
                    newret = CONFNAK;
                    if (!dont_nak) {
                        p[2] = DEFLATE_MAKE_OPT(ao->deflate_size);
@@ -863,7 +880,7 @@ ccp_reqci(f, p, lenp, dont_nak)
                        res = ccp_test(f->unit, p, CILEN_DEFLATE, 1);
                        if (res > 0)
                            break;              /* it's OK now */
-                       if (res < 0 || nb == DEFLATE_MIN_SIZE || dont_nak) {
+                       if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) {
                            newret = CONFREJ;
                            p[2] = DEFLATE_MAKE_OPT(ho->deflate_size);
                            break;