diff options
| author | Ralph Siemsen <ralph.siemsen@linaro.org> | 2022-03-11 15:37:58 -0500 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-03-23 23:16:12 +0000 |
| commit | 0c0b8487c96a6199f8a9bf5f457867167dd12474 (patch) | |
| tree | 331a7430b8efc4b44bc2ba2e29b7f57862ef4c52 | |
| parent | 3ec873af83c7b09468605d8aadd0933aecbdb56d (diff) | |
| download | poky-0c0b8487c96a6199f8a9bf5f457867167dd12474.tar.gz | |
libxml2: backport fix for CVE-2022-23308
Use-after-free of ID and IDREF attributes, which could result in denial
of service.
https://nvd.nist.gov/vuln/detail/CVE-2022-23308
CVE: CVE-2022-23308
(From OE-Core rev: 6c2f91ce93921c9bfe52c62c0347b992df98d62d)
Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
| -rw-r--r-- | meta/recipes-core/libxml/libxml2/CVE-2022-23308.patch | 204 | ||||
| -rw-r--r-- | meta/recipes-core/libxml/libxml2_2.9.10.bb | 1 |
2 files changed, 205 insertions, 0 deletions
diff --git a/meta/recipes-core/libxml/libxml2/CVE-2022-23308.patch b/meta/recipes-core/libxml/libxml2/CVE-2022-23308.patch new file mode 100644 index 0000000000..bf5604e81a --- /dev/null +++ b/meta/recipes-core/libxml/libxml2/CVE-2022-23308.patch | |||
| @@ -0,0 +1,204 @@ | |||
| 1 | From 8b66850de350f0fcd786ae776a65ba15a5999e50 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Nick Wellnhofer <wellnhofer@aevum.de> | ||
| 3 | Date: Tue, 8 Feb 2022 03:29:24 +0100 | ||
| 4 | Subject: [PATCH] Use-after-free of ID and IDREF attributes | ||
| 5 | |||
| 6 | If a document is parsed with XML_PARSE_DTDVALID and without | ||
| 7 | XML_PARSE_NOENT, the value of ID attributes has to be normalized after | ||
| 8 | potentially expanding entities in xmlRemoveID. Otherwise, later calls | ||
| 9 | to xmlGetID can return a pointer to previously freed memory. | ||
| 10 | |||
| 11 | ID attributes which are empty or contain only whitespace after | ||
| 12 | entity expansion are affected in a similar way. This is fixed by | ||
| 13 | not storing such attributes in the ID table. | ||
| 14 | |||
| 15 | The test to detect streaming mode when validating against a DTD was | ||
| 16 | broken. In connection with the defects above, this could result in a | ||
| 17 | use-after-free when using the xmlReader interface with validation. | ||
| 18 | Fix detection of streaming mode to avoid similar issues. (This changes | ||
| 19 | the expected result of a test case. But as far as I can tell, using the | ||
| 20 | XML reader with XIncludes referencing the root document never worked | ||
| 21 | properly, anyway.) | ||
| 22 | |||
| 23 | All of these issues can result in denial of service. Using xmlReader | ||
| 24 | with validation could result in disclosure of memory via the error | ||
| 25 | channel, typically stderr. The security impact of xmlGetID returning | ||
| 26 | a pointer to freed memory depends on the application. The typical use | ||
| 27 | case of calling xmlGetID on an unmodified document is not affected. | ||
| 28 | |||
| 29 | Upstream-Status: Backport | ||
| 30 | [https://gitlab.gnome.org/GNOME/libxml2/-/commit/652dd12a858989b14eed4e84e453059cd3ba340e] | ||
| 31 | |||
| 32 | The upstream patch 652dd12a858989b14eed4e84e453059cd3ba340e has been modified | ||
| 33 | to skip the patch to the testsuite result (result/XInclude/ns1.xml.rdr), as | ||
| 34 | this particular test does not exist in v2.9.10 (it was added later). | ||
| 35 | |||
| 36 | CVE: CVE-2022-23308 | ||
| 37 | Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org> | ||
| 38 | |||
| 39 | --- | ||
| 40 | valid.c | 88 +++++++++++++++++++++++++++++++++++---------------------- | ||
| 41 | 1 file changed, 55 insertions(+), 33 deletions(-) | ||
| 42 | |||
| 43 | diff --git a/valid.c b/valid.c | ||
| 44 | index 07963e7..ee75311 100644 | ||
| 45 | --- a/valid.c | ||
| 46 | +++ b/valid.c | ||
| 47 | @@ -479,6 +479,35 @@ nodeVPop(xmlValidCtxtPtr ctxt) | ||
| 48 | return (ret); | ||
| 49 | } | ||
| 50 | |||
| 51 | +/** | ||
| 52 | + * xmlValidNormalizeString: | ||
| 53 | + * @str: a string | ||
| 54 | + * | ||
| 55 | + * Normalize a string in-place. | ||
| 56 | + */ | ||
| 57 | +static void | ||
| 58 | +xmlValidNormalizeString(xmlChar *str) { | ||
| 59 | + xmlChar *dst; | ||
| 60 | + const xmlChar *src; | ||
| 61 | + | ||
| 62 | + if (str == NULL) | ||
| 63 | + return; | ||
| 64 | + src = str; | ||
| 65 | + dst = str; | ||
| 66 | + | ||
| 67 | + while (*src == 0x20) src++; | ||
| 68 | + while (*src != 0) { | ||
| 69 | + if (*src == 0x20) { | ||
| 70 | + while (*src == 0x20) src++; | ||
| 71 | + if (*src != 0) | ||
| 72 | + *dst++ = 0x20; | ||
| 73 | + } else { | ||
| 74 | + *dst++ = *src++; | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + *dst = 0; | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | #ifdef DEBUG_VALID_ALGO | ||
| 81 | static void | ||
| 82 | xmlValidPrintNode(xmlNodePtr cur) { | ||
| 83 | @@ -2607,6 +2636,24 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) { | ||
| 84 | (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \ | ||
| 85 | xmlFree((char *)(str)); | ||
| 86 | |||
| 87 | +static int | ||
| 88 | +xmlIsStreaming(xmlValidCtxtPtr ctxt) { | ||
| 89 | + xmlParserCtxtPtr pctxt; | ||
| 90 | + | ||
| 91 | + if (ctxt == NULL) | ||
| 92 | + return(0); | ||
| 93 | + /* | ||
| 94 | + * These magic values are also abused to detect whether we're validating | ||
| 95 | + * while parsing a document. In this case, userData points to the parser | ||
| 96 | + * context. | ||
| 97 | + */ | ||
| 98 | + if ((ctxt->finishDtd != XML_CTXT_FINISH_DTD_0) && | ||
| 99 | + (ctxt->finishDtd != XML_CTXT_FINISH_DTD_1)) | ||
| 100 | + return(0); | ||
| 101 | + pctxt = ctxt->userData; | ||
| 102 | + return(pctxt->parseMode == XML_PARSE_READER); | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | /** | ||
| 106 | * xmlFreeID: | ||
| 107 | * @not: A id | ||
| 108 | @@ -2650,7 +2697,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value, | ||
| 109 | if (doc == NULL) { | ||
| 110 | return(NULL); | ||
| 111 | } | ||
| 112 | - if (value == NULL) { | ||
| 113 | + if ((value == NULL) || (value[0] == 0)) { | ||
| 114 | return(NULL); | ||
| 115 | } | ||
| 116 | if (attr == NULL) { | ||
| 117 | @@ -2681,7 +2728,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value, | ||
| 118 | */ | ||
| 119 | ret->value = xmlStrdup(value); | ||
| 120 | ret->doc = doc; | ||
| 121 | - if ((ctxt != NULL) && (ctxt->vstateNr != 0)) { | ||
| 122 | + if (xmlIsStreaming(ctxt)) { | ||
| 123 | /* | ||
| 124 | * Operating in streaming mode, attr is gonna disappear | ||
| 125 | */ | ||
| 126 | @@ -2820,6 +2867,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) { | ||
| 127 | ID = xmlNodeListGetString(doc, attr->children, 1); | ||
| 128 | if (ID == NULL) | ||
| 129 | return(-1); | ||
| 130 | + xmlValidNormalizeString(ID); | ||
| 131 | |||
| 132 | id = xmlHashLookup(table, ID); | ||
| 133 | if (id == NULL || id->attr != attr) { | ||
| 134 | @@ -3009,7 +3057,7 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value, | ||
| 135 | * fill the structure. | ||
| 136 | */ | ||
| 137 | ret->value = xmlStrdup(value); | ||
| 138 | - if ((ctxt != NULL) && (ctxt->vstateNr != 0)) { | ||
| 139 | + if (xmlIsStreaming(ctxt)) { | ||
| 140 | /* | ||
| 141 | * Operating in streaming mode, attr is gonna disappear | ||
| 142 | */ | ||
| 143 | @@ -4028,8 +4076,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc, | ||
| 144 | xmlChar * | ||
| 145 | xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc, | ||
| 146 | xmlNodePtr elem, const xmlChar *name, const xmlChar *value) { | ||
| 147 | - xmlChar *ret, *dst; | ||
| 148 | - const xmlChar *src; | ||
| 149 | + xmlChar *ret; | ||
| 150 | xmlAttributePtr attrDecl = NULL; | ||
| 151 | int extsubset = 0; | ||
| 152 | |||
| 153 | @@ -4070,19 +4117,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc, | ||
| 154 | ret = xmlStrdup(value); | ||
| 155 | if (ret == NULL) | ||
| 156 | return(NULL); | ||
| 157 | - src = value; | ||
| 158 | - dst = ret; | ||
| 159 | - while (*src == 0x20) src++; | ||
| 160 | - while (*src != 0) { | ||
| 161 | - if (*src == 0x20) { | ||
| 162 | - while (*src == 0x20) src++; | ||
| 163 | - if (*src != 0) | ||
| 164 | - *dst++ = 0x20; | ||
| 165 | - } else { | ||
| 166 | - *dst++ = *src++; | ||
| 167 | - } | ||
| 168 | - } | ||
| 169 | - *dst = 0; | ||
| 170 | + xmlValidNormalizeString(ret); | ||
| 171 | if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) { | ||
| 172 | xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE, | ||
| 173 | "standalone: %s on %s value had to be normalized based on external subset declaration\n", | ||
| 174 | @@ -4114,8 +4149,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc, | ||
| 175 | xmlChar * | ||
| 176 | xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem, | ||
| 177 | const xmlChar *name, const xmlChar *value) { | ||
| 178 | - xmlChar *ret, *dst; | ||
| 179 | - const xmlChar *src; | ||
| 180 | + xmlChar *ret; | ||
| 181 | xmlAttributePtr attrDecl = NULL; | ||
| 182 | |||
| 183 | if (doc == NULL) return(NULL); | ||
| 184 | @@ -4145,19 +4179,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem, | ||
| 185 | ret = xmlStrdup(value); | ||
| 186 | if (ret == NULL) | ||
| 187 | return(NULL); | ||
| 188 | - src = value; | ||
| 189 | - dst = ret; | ||
| 190 | - while (*src == 0x20) src++; | ||
| 191 | - while (*src != 0) { | ||
| 192 | - if (*src == 0x20) { | ||
| 193 | - while (*src == 0x20) src++; | ||
| 194 | - if (*src != 0) | ||
| 195 | - *dst++ = 0x20; | ||
| 196 | - } else { | ||
| 197 | - *dst++ = *src++; | ||
| 198 | - } | ||
| 199 | - } | ||
| 200 | - *dst = 0; | ||
| 201 | + xmlValidNormalizeString(ret); | ||
| 202 | return(ret); | ||
| 203 | } | ||
| 204 | |||
diff --git a/meta/recipes-core/libxml/libxml2_2.9.10.bb b/meta/recipes-core/libxml/libxml2_2.9.10.bb index ebb996c8dd..1b22e5672c 100644 --- a/meta/recipes-core/libxml/libxml2_2.9.10.bb +++ b/meta/recipes-core/libxml/libxml2_2.9.10.bb | |||
| @@ -27,6 +27,7 @@ SRC_URI = "http://www.xmlsoft.org/sources/libxml2-${PV}.tar.gz;name=libtar \ | |||
| 27 | file://CVE-2021-3537.patch \ | 27 | file://CVE-2021-3537.patch \ |
| 28 | file://CVE-2021-3518.patch \ | 28 | file://CVE-2021-3518.patch \ |
| 29 | file://CVE-2021-3541.patch \ | 29 | file://CVE-2021-3541.patch \ |
| 30 | file://CVE-2022-23308.patch \ | ||
| 30 | " | 31 | " |
| 31 | 32 | ||
| 32 | SRC_URI[libtar.md5sum] = "10942a1dc23137a8aa07f0639cbfece5" | 33 | SRC_URI[libtar.md5sum] = "10942a1dc23137a8aa07f0639cbfece5" |
