~ubuntu-branches/ubuntu/trusty/libxml2/trusty-updates

« back to all changes in this revision

Viewing changes to debian/patches/CVE-2014-3660.patch

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-10-16 15:30:49 UTC
  • Revision ID: package-import@ubuntu.com-20141016153049-vzdgn4o9sfee23pb
Tags: 2.9.1+dfsg1-3ubuntu4.4
* SECURITY UPDATE: denial of service via entity expansion
  - debian/patches/CVE-2014-3660.patch: added additional tests to
    parser.c.
  - CVE-2014-3660

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From be2a7edaf289c5da74a4f9ed3a0b6c733e775230 Mon Sep 17 00:00:00 2001
 
2
From: Daniel Veillard <veillard@redhat.com>
 
3
Date: Thu, 16 Oct 2014 13:59:47 +0800
 
4
Subject: Fix for CVE-2014-3660
 
5
 
 
6
Issues related to the billion laugh entity expansion which happened to
 
7
escape the initial set of fixes
 
8
 
 
9
Index: libxml2-2.9.1+dfsg1/parser.c
 
10
===================================================================
 
11
--- libxml2-2.9.1+dfsg1.orig/parser.c   2014-10-16 15:30:40.885274343 -0400
 
12
+++ libxml2-2.9.1+dfsg1/parser.c        2014-10-16 15:30:40.881274311 -0400
 
13
@@ -130,6 +130,29 @@
 
14
         return (0);
 
15
     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
 
16
         return (1);
 
17
+
 
18
+    /*
 
19
+     * This may look absurd but is needed to detect
 
20
+     * entities problems
 
21
+     */
 
22
+    if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
 
23
+       (ent->content != NULL) && (ent->checked == 0)) {
 
24
+       unsigned long oldnbent = ctxt->nbentities;
 
25
+       xmlChar *rep;
 
26
+
 
27
+       ent->checked = 1;
 
28
+
 
29
+       rep = xmlStringDecodeEntities(ctxt, ent->content,
 
30
+                                 XML_SUBSTITUTE_REF, 0, 0, 0);
 
31
+
 
32
+       ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
 
33
+       if (rep != NULL) {
 
34
+           if (xmlStrchr(rep, '<'))
 
35
+               ent->checked |= 1;
 
36
+           xmlFree(rep);
 
37
+           rep = NULL;
 
38
+       }
 
39
+    }
 
40
     if (replacement != 0) {
 
41
        if (replacement < XML_MAX_TEXT_LENGTH)
 
42
            return(0);
 
43
@@ -189,9 +212,12 @@
 
44
             return (0);
 
45
     } else {
 
46
         /*
 
47
-         * strange we got no data for checking just return
 
48
+         * strange we got no data for checking
 
49
          */
 
50
-        return (0);
 
51
+       if (((ctxt->lastError.code != XML_ERR_UNDECLARED_ENTITY) &&
 
52
+            (ctxt->lastError.code != XML_WAR_UNDECLARED_ENTITY)) ||
 
53
+           (ctxt->nbentities <= 10000))
 
54
+           return (0);
 
55
     }
 
56
     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
 
57
     return (1);
 
58
@@ -2584,6 +2610,7 @@
 
59
                                      name, NULL);
 
60
                    ctxt->valid = 0;
 
61
                }
 
62
+               xmlParserEntityCheck(ctxt, 0, NULL, 0);
 
63
            } else if (ctxt->input->free != deallocblankswrapper) {
 
64
                    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
 
65
                    if (xmlPushInput(ctxt, input) < 0)
 
66
@@ -2754,6 +2781,7 @@
 
67
            if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
 
68
                (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
 
69
                goto int_error;
 
70
+           xmlParserEntityCheck(ctxt, 0, ent, 0);
 
71
            if (ent != NULL)
 
72
                ctxt->nbentities += ent->checked / 2;
 
73
            if ((ent != NULL) &&
 
74
@@ -2805,6 +2833,7 @@
 
75
            ent = xmlParseStringPEReference(ctxt, &str);
 
76
            if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
 
77
                goto int_error;
 
78
+           xmlParserEntityCheck(ctxt, 0, ent, 0);
 
79
            if (ent != NULL)
 
80
                ctxt->nbentities += ent->checked / 2;
 
81
            if (ent != NULL) {
 
82
@@ -7307,6 +7336,7 @@
 
83
                   (ret != XML_WAR_UNDECLARED_ENTITY)) {
 
84
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
 
85
                     "Entity '%s' failed to parse\n", ent->name);
 
86
+           xmlParserEntityCheck(ctxt, 0, ent, 0);
 
87
        } else if (list != NULL) {
 
88
            xmlFreeNodeList(list);
 
89
            list = NULL;
 
90
@@ -7413,7 +7443,7 @@
 
91
                /*
 
92
                 * We are copying here, make sure there is no abuse
 
93
                 */
 
94
-               ctxt->sizeentcopy += ent->length;
 
95
+               ctxt->sizeentcopy += ent->length + 5;
 
96
                if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
 
97
                    return;
 
98
 
 
99
@@ -7461,7 +7491,7 @@
 
100
                /*
 
101
                 * We are copying here, make sure there is no abuse
 
102
                 */
 
103
-               ctxt->sizeentcopy += ent->length;
 
104
+               ctxt->sizeentcopy += ent->length + 5;
 
105
                if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
 
106
                    return;
 
107
 
 
108
@@ -7647,6 +7677,7 @@
 
109
                ctxt->sax->reference(ctxt->userData, name);
 
110
            }
 
111
        }
 
112
+       xmlParserEntityCheck(ctxt, 0, ent, 0);
 
113
        ctxt->valid = 0;
 
114
     }
 
115
 
 
116
@@ -7840,6 +7871,7 @@
 
117
                          "Entity '%s' not defined\n",
 
118
                          name);
 
119
        }
 
120
+       xmlParserEntityCheck(ctxt, 0, ent, 0);
 
121
        /* TODO ? check regressions ctxt->valid = 0; */
 
122
     }
 
123
 
 
124
@@ -7999,6 +8031,7 @@
 
125
                          name, NULL);
 
126
            ctxt->valid = 0;
 
127
        }
 
128
+       xmlParserEntityCheck(ctxt, 0, NULL, 0);
 
129
     } else {
 
130
        /*
 
131
         * Internal checking in case the entity quest barfed
 
132
@@ -8238,6 +8271,7 @@
 
133
                          name, NULL);
 
134
            ctxt->valid = 0;
 
135
        }
 
136
+       xmlParserEntityCheck(ctxt, 0, NULL, 0);
 
137
     } else {
 
138
        /*
 
139
         * Internal checking in case the entity quest barfed