diff options
| author | Hitendra Prajapati <hprajapati@mvista.com> | 2025-08-11 12:33:33 +0530 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2025-08-18 13:18:01 -0700 |
| commit | 423e0ff3fbdff2504931731f6e18e8cb3a9486b2 (patch) | |
| tree | ce5538427f97a6ce824f04a41356c537346fd7a2 | |
| parent | 8f356f507e2863e7ffd13294a4bd82e88af6f469 (diff) | |
| download | poky-423e0ff3fbdff2504931731f6e18e8cb3a9486b2.tar.gz | |
libxslt: fix CVE-2023-40403
Upstream-Status: Backport from https://gitlab.gnome.org/GNOME/libxslt/-/commit/adebe45f6ef9f9d036acacd8aec7411d4ea84e25 && https://gitlab.gnome.org/GNOME/libxslt/-/commit/1d9820635c271b35f88431f33ea78dc8be349e5b && https://gitlab.gnome.org/GNOME/libxslt/-/commit/ccec6fa31d11ab0a5299f15ea184c7a457e92940 && https://gitlab.gnome.org/GNOME/libxslt/-/commit/82f6cbf8ca61b1f9e00dc04aa3b15d563e7bbc6d && https://gitlab.gnome.org/GNOME/libxslt/-/commit/452fb4ca9b9803448826008b9573987c615912a1
(From OE-Core rev: b77845d6fed5385de5789f8864fc399f82209ea1)
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
6 files changed, 1044 insertions, 0 deletions
diff --git a/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-001.patch b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-001.patch new file mode 100644 index 0000000000..044e100373 --- /dev/null +++ b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-001.patch | |||
| @@ -0,0 +1,257 @@ | |||
| 1 | From 4f26166f9e253aa62f8c121a6a25c76df5aa8142 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Nick Wellnhofer <wellnhofer@aevum.de> | ||
| 3 | Date: Wed, 31 Aug 2022 15:29:57 +0200 | ||
| 4 | Subject: [PATCH] Infrastructure to store extra data in source nodes | ||
| 5 | |||
| 6 | Provide a mechanism to store bit flags in nodes from the source | ||
| 7 | document. This will later be used to store key and id status. | ||
| 8 | |||
| 9 | Provide a function to find the psvi member of a node. | ||
| 10 | |||
| 11 | Revert any changes to the source document after the transformation. | ||
| 12 | |||
| 13 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/commit/adebe45f6ef9f9d036acacd8aec7411d4ea84e25] | ||
| 14 | CVE: CVE-2023-40403 | ||
| 15 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
| 16 | |||
| 17 | --- | ||
| 18 | libxslt/transform.c | 34 ++++++++++ | ||
| 19 | libxslt/xsltInternals.h | 1 + | ||
| 20 | libxslt/xsltutils.c | 135 ++++++++++++++++++++++++++++++++++++++++ | ||
| 21 | libxslt/xsltutils.h | 13 ++++ | ||
| 22 | 4 files changed, 183 insertions(+) | ||
| 23 | |||
| 24 | diff --git a/libxslt/transform.c b/libxslt/transform.c | ||
| 25 | index 57f05bf..40ab810 100644 | ||
| 26 | --- a/libxslt/transform.c | ||
| 27 | +++ b/libxslt/transform.c | ||
| 28 | @@ -5747,6 +5747,37 @@ xsltCountKeys(xsltTransformContextPtr ctxt) | ||
| 29 | return(ctxt->nbKeys); | ||
| 30 | } | ||
| 31 | |||
| 32 | +/** | ||
| 33 | + * xsltCleanupSourceDoc: | ||
| 34 | + * @doc: Document | ||
| 35 | + * | ||
| 36 | + * Resets source node flags and ids stored in 'psvi' member. | ||
| 37 | + */ | ||
| 38 | +static void | ||
| 39 | +xsltCleanupSourceDoc(xmlDocPtr doc) { | ||
| 40 | + xmlNodePtr cur = (xmlNodePtr) doc; | ||
| 41 | + void **psviPtr; | ||
| 42 | + | ||
| 43 | + while (1) { | ||
| 44 | + xsltClearSourceNodeFlags(cur, XSLT_SOURCE_NODE_MASK); | ||
| 45 | + psviPtr = xsltGetPSVIPtr(cur); | ||
| 46 | + if (psviPtr) | ||
| 47 | + *psviPtr = NULL; | ||
| 48 | + | ||
| 49 | + if (cur->children != NULL && cur->type != XML_ENTITY_REF_NODE) { | ||
| 50 | + cur = cur->children; | ||
| 51 | + } else { | ||
| 52 | + while (cur->next == NULL) { | ||
| 53 | + cur = cur->parent; | ||
| 54 | + if (cur == (xmlNodePtr) doc) | ||
| 55 | + return; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + cur = cur->next; | ||
| 59 | + } | ||
| 60 | + } | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | /** | ||
| 64 | * xsltApplyStylesheetInternal: | ||
| 65 | * @style: a parsed XSLT stylesheet | ||
| 66 | @@ -6145,6 +6176,9 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc, | ||
| 67 | printf("# Reused variables : %d\n", ctxt->cache->dbgReusedVars); | ||
| 68 | #endif | ||
| 69 | |||
| 70 | + if (ctxt->sourceDocDirty) | ||
| 71 | + xsltCleanupSourceDoc(doc); | ||
| 72 | + | ||
| 73 | if ((ctxt != NULL) && (userCtxt == NULL)) | ||
| 74 | xsltFreeTransformContext(ctxt); | ||
| 75 | |||
| 76 | diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h | ||
| 77 | index 14343d2..b0125c2 100644 | ||
| 78 | --- a/libxslt/xsltInternals.h | ||
| 79 | +++ b/libxslt/xsltInternals.h | ||
| 80 | @@ -1786,6 +1786,7 @@ struct _xsltTransformContext { | ||
| 81 | int maxTemplateVars; | ||
| 82 | unsigned long opLimit; | ||
| 83 | unsigned long opCount; | ||
| 84 | + int sourceDocDirty; | ||
| 85 | }; | ||
| 86 | |||
| 87 | /** | ||
| 88 | diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c | ||
| 89 | index 9faa6b2..a879aa8 100644 | ||
| 90 | --- a/libxslt/xsltutils.c | ||
| 91 | +++ b/libxslt/xsltutils.c | ||
| 92 | @@ -1835,6 +1835,141 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len, | ||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | +/** | ||
| 97 | + * xsltGetSourceNodeFlags: | ||
| 98 | + * @node: Node from source document | ||
| 99 | + * | ||
| 100 | + * Returns the flags for a source node. | ||
| 101 | + */ | ||
| 102 | +int | ||
| 103 | +xsltGetSourceNodeFlags(xmlNodePtr node) { | ||
| 104 | + /* | ||
| 105 | + * Squeeze the bit flags into the upper bits of | ||
| 106 | + * | ||
| 107 | + * - 'int properties' member in struct _xmlDoc | ||
| 108 | + * - 'xmlAttributeType atype' member in struct _xmlAttr | ||
| 109 | + * - 'unsigned short extra' member in struct _xmlNode | ||
| 110 | + */ | ||
| 111 | + switch (node->type) { | ||
| 112 | + case XML_DOCUMENT_NODE: | ||
| 113 | + case XML_HTML_DOCUMENT_NODE: | ||
| 114 | + return ((xmlDocPtr) node)->properties >> 27; | ||
| 115 | + | ||
| 116 | + case XML_ATTRIBUTE_NODE: | ||
| 117 | + return ((xmlAttrPtr) node)->atype >> 27; | ||
| 118 | + | ||
| 119 | + case XML_ELEMENT_NODE: | ||
| 120 | + case XML_TEXT_NODE: | ||
| 121 | + case XML_CDATA_SECTION_NODE: | ||
| 122 | + case XML_PI_NODE: | ||
| 123 | + case XML_COMMENT_NODE: | ||
| 124 | + return node->extra >> 12; | ||
| 125 | + | ||
| 126 | + default: | ||
| 127 | + return 0; | ||
| 128 | + } | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +/** | ||
| 132 | + * xsltSetSourceNodeFlags: | ||
| 133 | + * @node: Node from source document | ||
| 134 | + * @flags: Flags | ||
| 135 | + * | ||
| 136 | + * Sets the specified flags to 1. | ||
| 137 | + * | ||
| 138 | + * Returns 0 on success, -1 on error. | ||
| 139 | + */ | ||
| 140 | +int | ||
| 141 | +xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, | ||
| 142 | + int flags) { | ||
| 143 | + if (node->doc == ctxt->initialContextDoc) | ||
| 144 | + ctxt->sourceDocDirty = 1; | ||
| 145 | + | ||
| 146 | + switch (node->type) { | ||
| 147 | + case XML_DOCUMENT_NODE: | ||
| 148 | + case XML_HTML_DOCUMENT_NODE: | ||
| 149 | + ((xmlDocPtr) node)->properties |= flags << 27; | ||
| 150 | + return 0; | ||
| 151 | + | ||
| 152 | + case XML_ATTRIBUTE_NODE: | ||
| 153 | + ((xmlAttrPtr) node)->atype |= flags << 27; | ||
| 154 | + return 0; | ||
| 155 | + | ||
| 156 | + case XML_ELEMENT_NODE: | ||
| 157 | + case XML_TEXT_NODE: | ||
| 158 | + case XML_CDATA_SECTION_NODE: | ||
| 159 | + case XML_PI_NODE: | ||
| 160 | + case XML_COMMENT_NODE: | ||
| 161 | + node->extra |= flags << 12; | ||
| 162 | + return 0; | ||
| 163 | + | ||
| 164 | + default: | ||
| 165 | + return -1; | ||
| 166 | + } | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +/** | ||
| 170 | + * xsltClearSourceNodeFlags: | ||
| 171 | + * @node: Node from source document | ||
| 172 | + * @flags: Flags | ||
| 173 | + * | ||
| 174 | + * Sets the specified flags to 0. | ||
| 175 | + * | ||
| 176 | + * Returns 0 on success, -1 on error. | ||
| 177 | + */ | ||
| 178 | +int | ||
| 179 | +xsltClearSourceNodeFlags(xmlNodePtr node, int flags) { | ||
| 180 | + switch (node->type) { | ||
| 181 | + case XML_DOCUMENT_NODE: | ||
| 182 | + case XML_HTML_DOCUMENT_NODE: | ||
| 183 | + ((xmlDocPtr) node)->properties &= ~(flags << 27); | ||
| 184 | + return 0; | ||
| 185 | + | ||
| 186 | + case XML_ATTRIBUTE_NODE: | ||
| 187 | + ((xmlAttrPtr) node)->atype &= ~(flags << 27); | ||
| 188 | + return 0; | ||
| 189 | + | ||
| 190 | + case XML_ELEMENT_NODE: | ||
| 191 | + case XML_TEXT_NODE: | ||
| 192 | + case XML_CDATA_SECTION_NODE: | ||
| 193 | + case XML_PI_NODE: | ||
| 194 | + case XML_COMMENT_NODE: | ||
| 195 | + node->extra &= ~(flags << 12); | ||
| 196 | + return 0; | ||
| 197 | + | ||
| 198 | + default: | ||
| 199 | + return -1; | ||
| 200 | + } | ||
| 201 | +} | ||
| 202 | + | ||
| 203 | +/** | ||
| 204 | + * xsltGetPSVIPtr: | ||
| 205 | + * @cur: Node | ||
| 206 | + * | ||
| 207 | + * Returns a pointer to the psvi member of a node or NULL on error. | ||
| 208 | + */ | ||
| 209 | +void ** | ||
| 210 | +xsltGetPSVIPtr(xmlNodePtr cur) { | ||
| 211 | + switch (cur->type) { | ||
| 212 | + case XML_DOCUMENT_NODE: | ||
| 213 | + case XML_HTML_DOCUMENT_NODE: | ||
| 214 | + return &((xmlDocPtr) cur)->psvi; | ||
| 215 | + | ||
| 216 | + case XML_ATTRIBUTE_NODE: | ||
| 217 | + return &((xmlAttrPtr) cur)->psvi; | ||
| 218 | + | ||
| 219 | + case XML_ELEMENT_NODE: | ||
| 220 | + case XML_TEXT_NODE: | ||
| 221 | + case XML_CDATA_SECTION_NODE: | ||
| 222 | + case XML_PI_NODE: | ||
| 223 | + case XML_COMMENT_NODE: | ||
| 224 | + return &cur->psvi; | ||
| 225 | + | ||
| 226 | + default: | ||
| 227 | + return NULL; | ||
| 228 | + } | ||
| 229 | +} | ||
| 230 | + | ||
| 231 | #ifdef WITH_PROFILER | ||
| 232 | |||
| 233 | /************************************************************************ | ||
| 234 | diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h | ||
| 235 | index ea6c374..202694f 100644 | ||
| 236 | --- a/libxslt/xsltutils.h | ||
| 237 | +++ b/libxslt/xsltutils.h | ||
| 238 | @@ -247,6 +247,19 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL | ||
| 239 | const xmlChar *str, | ||
| 240 | int flags); | ||
| 241 | |||
| 242 | +#ifdef IN_LIBXSLT | ||
| 243 | +#define XSLT_SOURCE_NODE_MASK 15 | ||
| 244 | +int | ||
| 245 | +xsltGetSourceNodeFlags(xmlNodePtr node); | ||
| 246 | +int | ||
| 247 | +xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, | ||
| 248 | + int flags); | ||
| 249 | +int | ||
| 250 | +xsltClearSourceNodeFlags(xmlNodePtr node, int flags); | ||
| 251 | +void ** | ||
| 252 | +xsltGetPSVIPtr(xmlNodePtr cur); | ||
| 253 | +#endif | ||
| 254 | + | ||
| 255 | /* | ||
| 256 | * Profiling. | ||
| 257 | */ | ||
diff --git a/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-002.patch b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-002.patch new file mode 100644 index 0000000000..0d815c1090 --- /dev/null +++ b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-002.patch | |||
| @@ -0,0 +1,147 @@ | |||
| 1 | From b392a3d0265f190d86cc122d86769a23ddb1fe66 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Nick Wellnhofer <wellnhofer@aevum.de> | ||
| 3 | Date: Wed, 31 Aug 2022 15:34:47 +0200 | ||
| 4 | Subject: [PATCH] Store key status of source nodes as bit flag | ||
| 5 | |||
| 6 | This frees up the psvi member. | ||
| 7 | |||
| 8 | CVE: CVE-2023-40403 | ||
| 9 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/commit/1d9820635c271b35f88431f33ea78dc8be349e5b] | ||
| 10 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
| 11 | |||
| 12 | --- | ||
| 13 | libxslt/keys.c | 19 +------------------ | ||
| 14 | libxslt/pattern.c | 37 ++----------------------------------- | ||
| 15 | libxslt/xsltutils.h | 1 + | ||
| 16 | 3 files changed, 4 insertions(+), 53 deletions(-) | ||
| 17 | |||
| 18 | diff --git a/libxslt/keys.c b/libxslt/keys.c | ||
| 19 | index ecef538..3a134ab 100644 | ||
| 20 | --- a/libxslt/keys.c | ||
| 21 | +++ b/libxslt/keys.c | ||
| 22 | @@ -834,24 +834,7 @@ fprintf(stderr, "xsltInitCtxtKey %s : %d\n", keyDef->name, ctxt->keyInitLevel); | ||
| 23 | */ | ||
| 24 | xmlXPathNodeSetAdd(keylist, cur); | ||
| 25 | } | ||
| 26 | - switch (cur->type) { | ||
| 27 | - case XML_ELEMENT_NODE: | ||
| 28 | - case XML_TEXT_NODE: | ||
| 29 | - case XML_CDATA_SECTION_NODE: | ||
| 30 | - case XML_PI_NODE: | ||
| 31 | - case XML_COMMENT_NODE: | ||
| 32 | - cur->psvi = keyDef; | ||
| 33 | - break; | ||
| 34 | - case XML_ATTRIBUTE_NODE: | ||
| 35 | - ((xmlAttrPtr) cur)->psvi = keyDef; | ||
| 36 | - break; | ||
| 37 | - case XML_DOCUMENT_NODE: | ||
| 38 | - case XML_HTML_DOCUMENT_NODE: | ||
| 39 | - ((xmlDocPtr) cur)->psvi = keyDef; | ||
| 40 | - break; | ||
| 41 | - default: | ||
| 42 | - break; | ||
| 43 | - } | ||
| 44 | + xsltSetSourceNodeFlags(ctxt, cur, XSLT_SOURCE_NODE_HAS_KEY); | ||
| 45 | xmlFree(str); | ||
| 46 | str = NULL; | ||
| 47 | |||
| 48 | diff --git a/libxslt/pattern.c b/libxslt/pattern.c | ||
| 49 | index 1944661..9372bc3 100644 | ||
| 50 | --- a/libxslt/pattern.c | ||
| 51 | +++ b/libxslt/pattern.c | ||
| 52 | @@ -2283,7 +2283,6 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, | ||
| 53 | const xmlChar *name = NULL; | ||
| 54 | xsltCompMatchPtr list = NULL; | ||
| 55 | float priority; | ||
| 56 | - int keyed = 0; | ||
| 57 | |||
| 58 | if ((ctxt == NULL) || (node == NULL)) | ||
| 59 | return(NULL); | ||
| 60 | @@ -2361,37 +2360,25 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, | ||
| 61 | list = curstyle->rootMatch; | ||
| 62 | else | ||
| 63 | list = curstyle->elemMatch; | ||
| 64 | - if (node->psvi != NULL) keyed = 1; | ||
| 65 | break; | ||
| 66 | case XML_ATTRIBUTE_NODE: { | ||
| 67 | - xmlAttrPtr attr; | ||
| 68 | - | ||
| 69 | list = curstyle->attrMatch; | ||
| 70 | - attr = (xmlAttrPtr) node; | ||
| 71 | - if (attr->psvi != NULL) keyed = 1; | ||
| 72 | break; | ||
| 73 | } | ||
| 74 | case XML_PI_NODE: | ||
| 75 | list = curstyle->piMatch; | ||
| 76 | - if (node->psvi != NULL) keyed = 1; | ||
| 77 | break; | ||
| 78 | case XML_DOCUMENT_NODE: | ||
| 79 | case XML_HTML_DOCUMENT_NODE: { | ||
| 80 | - xmlDocPtr doc; | ||
| 81 | - | ||
| 82 | list = curstyle->rootMatch; | ||
| 83 | - doc = (xmlDocPtr) node; | ||
| 84 | - if (doc->psvi != NULL) keyed = 1; | ||
| 85 | break; | ||
| 86 | } | ||
| 87 | case XML_TEXT_NODE: | ||
| 88 | case XML_CDATA_SECTION_NODE: | ||
| 89 | list = curstyle->textMatch; | ||
| 90 | - if (node->psvi != NULL) keyed = 1; | ||
| 91 | break; | ||
| 92 | case XML_COMMENT_NODE: | ||
| 93 | list = curstyle->commentMatch; | ||
| 94 | - if (node->psvi != NULL) keyed = 1; | ||
| 95 | break; | ||
| 96 | case XML_ENTITY_REF_NODE: | ||
| 97 | case XML_ENTITY_NODE: | ||
| 98 | @@ -2461,7 +2448,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, | ||
| 99 | } | ||
| 100 | |||
| 101 | keyed_match: | ||
| 102 | - if (keyed) { | ||
| 103 | + if (xsltGetSourceNodeFlags(node) & XSLT_SOURCE_NODE_HAS_KEY) { | ||
| 104 | list = curstyle->keyMatch; | ||
| 105 | while ((list != NULL) && | ||
| 106 | ((ret == NULL) || | ||
| 107 | @@ -2489,27 +2476,7 @@ keyed_match: | ||
| 108 | if (xsltComputeAllKeys(ctxt, node) == -1) | ||
| 109 | goto error; | ||
| 110 | |||
| 111 | - switch (node->type) { | ||
| 112 | - case XML_ELEMENT_NODE: | ||
| 113 | - if (node->psvi != NULL) keyed = 1; | ||
| 114 | - break; | ||
| 115 | - case XML_ATTRIBUTE_NODE: | ||
| 116 | - if (((xmlAttrPtr) node)->psvi != NULL) keyed = 1; | ||
| 117 | - break; | ||
| 118 | - case XML_TEXT_NODE: | ||
| 119 | - case XML_CDATA_SECTION_NODE: | ||
| 120 | - case XML_COMMENT_NODE: | ||
| 121 | - case XML_PI_NODE: | ||
| 122 | - if (node->psvi != NULL) keyed = 1; | ||
| 123 | - break; | ||
| 124 | - case XML_DOCUMENT_NODE: | ||
| 125 | - case XML_HTML_DOCUMENT_NODE: | ||
| 126 | - if (((xmlDocPtr) node)->psvi != NULL) keyed = 1; | ||
| 127 | - break; | ||
| 128 | - default: | ||
| 129 | - break; | ||
| 130 | - } | ||
| 131 | - if (keyed) | ||
| 132 | + if (xsltGetSourceNodeFlags(node) & XSLT_SOURCE_NODE_HAS_KEY) | ||
| 133 | goto keyed_match; | ||
| 134 | } | ||
| 135 | if (ret != NULL) | ||
| 136 | diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h | ||
| 137 | index 202694f..dcfd139 100644 | ||
| 138 | --- a/libxslt/xsltutils.h | ||
| 139 | +++ b/libxslt/xsltutils.h | ||
| 140 | @@ -249,6 +249,7 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL | ||
| 141 | |||
| 142 | #ifdef IN_LIBXSLT | ||
| 143 | #define XSLT_SOURCE_NODE_MASK 15 | ||
| 144 | +#define XSLT_SOURCE_NODE_HAS_KEY 1 | ||
| 145 | int | ||
| 146 | xsltGetSourceNodeFlags(xmlNodePtr node); | ||
| 147 | int | ||
diff --git a/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-003.patch b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-003.patch new file mode 100644 index 0000000000..0b9ab5829e --- /dev/null +++ b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-003.patch | |||
| @@ -0,0 +1,231 @@ | |||
| 1 | From 8986995b07126852762e8a59eaee83be0b8de9a3 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Nick Wellnhofer <wellnhofer@aevum.de> | ||
| 3 | Date: Wed, 31 Aug 2022 15:35:37 +0200 | ||
| 4 | Subject: [PATCH] Store RVT ownership in 'compression' member | ||
| 5 | |||
| 6 | 'compression' is another unused member in struct _xmlDoc which is even | ||
| 7 | better suited to store ownership status. More importantly, this frees up | ||
| 8 | the 'psvi' member. | ||
| 9 | |||
| 10 | This changes the public API but this feature is only required to | ||
| 11 | implement EXSLT functions. | ||
| 12 | |||
| 13 | CVE: CVE-2023-40403 | ||
| 14 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/commit/ccec6fa31d11ab0a5299f15ea184c7a457e92940] | ||
| 15 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
| 16 | |||
| 17 | --- | ||
| 18 | libexslt/functions.c | 2 +- | ||
| 19 | libxslt/transform.c | 8 ++++---- | ||
| 20 | libxslt/variables.c | 44 ++++++++++++++++++++--------------------- | ||
| 21 | libxslt/variables.h | 6 +++--- | ||
| 22 | libxslt/xsltInternals.h | 2 +- | ||
| 23 | 5 files changed, 31 insertions(+), 31 deletions(-) | ||
| 24 | |||
| 25 | diff --git a/libexslt/functions.c b/libexslt/functions.c | ||
| 26 | index 958bf60..859a992 100644 | ||
| 27 | --- a/libexslt/functions.c | ||
| 28 | +++ b/libexslt/functions.c | ||
| 29 | @@ -775,7 +775,7 @@ exsltFuncResultElem (xsltTransformContextPtr ctxt, | ||
| 30 | } | ||
| 31 | /* Mark as function result. */ | ||
| 32 | xsltRegisterLocalRVT(ctxt, container); | ||
| 33 | - container->psvi = XSLT_RVT_FUNC_RESULT; | ||
| 34 | + container->compression = XSLT_RVT_FUNC_RESULT; | ||
| 35 | |||
| 36 | oldInsert = ctxt->insert; | ||
| 37 | ctxt->insert = (xmlNodePtr) container; | ||
| 38 | diff --git a/libxslt/transform.c b/libxslt/transform.c | ||
| 39 | index 40ab810..19d7326 100644 | ||
| 40 | --- a/libxslt/transform.c | ||
| 41 | +++ b/libxslt/transform.c | ||
| 42 | @@ -2276,17 +2276,17 @@ xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base) | ||
| 43 | do { | ||
| 44 | tmp = cur; | ||
| 45 | cur = (xmlDocPtr) cur->next; | ||
| 46 | - if (tmp->psvi == XSLT_RVT_LOCAL) { | ||
| 47 | + if (tmp->compression == XSLT_RVT_LOCAL) { | ||
| 48 | xsltReleaseRVT(ctxt, tmp); | ||
| 49 | - } else if (tmp->psvi == XSLT_RVT_GLOBAL) { | ||
| 50 | + } else if (tmp->compression == XSLT_RVT_GLOBAL) { | ||
| 51 | xsltRegisterPersistRVT(ctxt, tmp); | ||
| 52 | - } else if (tmp->psvi == XSLT_RVT_FUNC_RESULT) { | ||
| 53 | + } else if (tmp->compression == XSLT_RVT_FUNC_RESULT) { | ||
| 54 | /* | ||
| 55 | * This will either register the RVT again or move it to the | ||
| 56 | * context variable. | ||
| 57 | */ | ||
| 58 | xsltRegisterLocalRVT(ctxt, tmp); | ||
| 59 | - tmp->psvi = XSLT_RVT_FUNC_RESULT; | ||
| 60 | + tmp->compression = XSLT_RVT_FUNC_RESULT; | ||
| 61 | } else { | ||
| 62 | xmlGenericError(xmlGenericErrorContext, | ||
| 63 | "xsltReleaseLocalRVTs: Unexpected RVT flag %p\n", | ||
| 64 | diff --git a/libxslt/variables.c b/libxslt/variables.c | ||
| 65 | index 4c972a4..dab0bab 100644 | ||
| 66 | --- a/libxslt/variables.c | ||
| 67 | +++ b/libxslt/variables.c | ||
| 68 | @@ -123,7 +123,7 @@ xsltRegisterTmpRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT) | ||
| 69 | return(-1); | ||
| 70 | |||
| 71 | RVT->prev = NULL; | ||
| 72 | - RVT->psvi = XSLT_RVT_LOCAL; | ||
| 73 | + RVT->compression = XSLT_RVT_LOCAL; | ||
| 74 | |||
| 75 | /* | ||
| 76 | * We'll restrict the lifetime of user-created fragments | ||
| 77 | @@ -163,7 +163,7 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt, | ||
| 78 | return(-1); | ||
| 79 | |||
| 80 | RVT->prev = NULL; | ||
| 81 | - RVT->psvi = XSLT_RVT_LOCAL; | ||
| 82 | + RVT->compression = XSLT_RVT_LOCAL; | ||
| 83 | |||
| 84 | /* | ||
| 85 | * When evaluating "select" expressions of xsl:variable | ||
| 86 | @@ -255,7 +255,7 @@ xsltExtensionInstructionResultRegister( | ||
| 87 | * Returns 0 in case of success and -1 in case of error. | ||
| 88 | */ | ||
| 89 | int | ||
| 90 | -xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) { | ||
| 91 | +xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, int val) { | ||
| 92 | int i; | ||
| 93 | xmlNodePtr cur; | ||
| 94 | xmlDocPtr doc; | ||
| 95 | @@ -302,34 +302,34 @@ xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) { | ||
| 96 | return(-1); | ||
| 97 | } | ||
| 98 | if (doc->name && (doc->name[0] == ' ') && | ||
| 99 | - doc->psvi != XSLT_RVT_GLOBAL) { | ||
| 100 | + doc->compression != XSLT_RVT_GLOBAL) { | ||
| 101 | /* | ||
| 102 | * This is a result tree fragment. | ||
| 103 | - * We store ownership information in the @psvi field. | ||
| 104 | + * We store ownership information in the @compression field. | ||
| 105 | * TODO: How do we know if this is a doc acquired via the | ||
| 106 | * document() function? | ||
| 107 | */ | ||
| 108 | #ifdef WITH_XSLT_DEBUG_VARIABLE | ||
| 109 | XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext, | ||
| 110 | - "Flagging RVT %p: %p -> %p\n", doc, doc->psvi, val)); | ||
| 111 | + "Flagging RVT %p: %d -> %d\n", doc, doc->compression, val)); | ||
| 112 | #endif | ||
| 113 | |||
| 114 | if (val == XSLT_RVT_LOCAL) { | ||
| 115 | - if (doc->psvi == XSLT_RVT_FUNC_RESULT) | ||
| 116 | - doc->psvi = XSLT_RVT_LOCAL; | ||
| 117 | + if (doc->compression == XSLT_RVT_FUNC_RESULT) | ||
| 118 | + doc->compression = XSLT_RVT_LOCAL; | ||
| 119 | } else if (val == XSLT_RVT_GLOBAL) { | ||
| 120 | - if (doc->psvi != XSLT_RVT_LOCAL) { | ||
| 121 | + if (doc->compression != XSLT_RVT_LOCAL) { | ||
| 122 | xmlGenericError(xmlGenericErrorContext, | ||
| 123 | - "xsltFlagRVTs: Invalid transition %p => GLOBAL\n", | ||
| 124 | - doc->psvi); | ||
| 125 | - doc->psvi = XSLT_RVT_GLOBAL; | ||
| 126 | + "xsltFlagRVTs: Invalid transition %d => GLOBAL\n", | ||
| 127 | + doc->compression); | ||
| 128 | + doc->compression = XSLT_RVT_GLOBAL; | ||
| 129 | return(-1); | ||
| 130 | } | ||
| 131 | |||
| 132 | /* Will be registered as persistant in xsltReleaseLocalRVTs. */ | ||
| 133 | - doc->psvi = XSLT_RVT_GLOBAL; | ||
| 134 | + doc->compression = XSLT_RVT_GLOBAL; | ||
| 135 | } else if (val == XSLT_RVT_FUNC_RESULT) { | ||
| 136 | - doc->psvi = val; | ||
| 137 | + doc->compression = val; | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 141 | @@ -382,7 +382,7 @@ xsltReleaseRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT) | ||
| 142 | /* | ||
| 143 | * Reset the ownership information. | ||
| 144 | */ | ||
| 145 | - RVT->psvi = NULL; | ||
| 146 | + RVT->compression = 0; | ||
| 147 | |||
| 148 | RVT->next = (xmlNodePtr) ctxt->cache->RVT; | ||
| 149 | ctxt->cache->RVT = RVT; | ||
| 150 | @@ -421,7 +421,7 @@ xsltRegisterPersistRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT) | ||
| 151 | { | ||
| 152 | if ((ctxt == NULL) || (RVT == NULL)) return(-1); | ||
| 153 | |||
| 154 | - RVT->psvi = XSLT_RVT_GLOBAL; | ||
| 155 | + RVT->compression = XSLT_RVT_GLOBAL; | ||
| 156 | RVT->prev = NULL; | ||
| 157 | RVT->next = (xmlNodePtr) ctxt->persistRVT; | ||
| 158 | if (ctxt->persistRVT != NULL) | ||
| 159 | @@ -580,15 +580,15 @@ xsltFreeStackElem(xsltStackElemPtr elem) { | ||
| 160 | cur = elem->fragment; | ||
| 161 | elem->fragment = (xmlDocPtr) cur->next; | ||
| 162 | |||
| 163 | - if (cur->psvi == XSLT_RVT_LOCAL) { | ||
| 164 | + if (cur->compression == XSLT_RVT_LOCAL) { | ||
| 165 | xsltReleaseRVT(elem->context, cur); | ||
| 166 | - } else if (cur->psvi == XSLT_RVT_FUNC_RESULT) { | ||
| 167 | + } else if (cur->compression == XSLT_RVT_FUNC_RESULT) { | ||
| 168 | xsltRegisterLocalRVT(elem->context, cur); | ||
| 169 | - cur->psvi = XSLT_RVT_FUNC_RESULT; | ||
| 170 | + cur->compression = XSLT_RVT_FUNC_RESULT; | ||
| 171 | } else { | ||
| 172 | xmlGenericError(xmlGenericErrorContext, | ||
| 173 | - "xsltFreeStackElem: Unexpected RVT flag %p\n", | ||
| 174 | - cur->psvi); | ||
| 175 | + "xsltFreeStackElem: Unexpected RVT flag %d\n", | ||
| 176 | + cur->compression); | ||
| 177 | } | ||
| 178 | } | ||
| 179 | } | ||
| 180 | @@ -989,7 +989,7 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable, | ||
| 181 | * the Result Tree Fragment. | ||
| 182 | */ | ||
| 183 | variable->fragment = container; | ||
| 184 | - container->psvi = XSLT_RVT_LOCAL; | ||
| 185 | + container->compression = XSLT_RVT_LOCAL; | ||
| 186 | |||
| 187 | oldOutput = ctxt->output; | ||
| 188 | oldInsert = ctxt->insert; | ||
| 189 | diff --git a/libxslt/variables.h b/libxslt/variables.h | ||
| 190 | index 039288f..e2adee0 100644 | ||
| 191 | --- a/libxslt/variables.h | ||
| 192 | +++ b/libxslt/variables.h | ||
| 193 | @@ -43,7 +43,7 @@ extern "C" { | ||
| 194 | * | ||
| 195 | * RVT is destroyed after the current instructions ends. | ||
| 196 | */ | ||
| 197 | -#define XSLT_RVT_LOCAL ((void *)1) | ||
| 198 | +#define XSLT_RVT_LOCAL 1 | ||
| 199 | |||
| 200 | /** | ||
| 201 | * XSLT_RVT_FUNC_RESULT: | ||
| 202 | @@ -52,14 +52,14 @@ extern "C" { | ||
| 203 | * destroyed after exiting a template and will be reset to XSLT_RVT_LOCAL or | ||
| 204 | * XSLT_RVT_VARIABLE in the template that receives the return value. | ||
| 205 | */ | ||
| 206 | -#define XSLT_RVT_FUNC_RESULT ((void *)2) | ||
| 207 | +#define XSLT_RVT_FUNC_RESULT 2 | ||
| 208 | |||
| 209 | /** | ||
| 210 | * XSLT_RVT_GLOBAL: | ||
| 211 | * | ||
| 212 | * RVT is part of a global variable. | ||
| 213 | */ | ||
| 214 | -#define XSLT_RVT_GLOBAL ((void *)3) | ||
| 215 | +#define XSLT_RVT_GLOBAL 3 | ||
| 216 | |||
| 217 | /* | ||
| 218 | * Interfaces for the variable module. | ||
| 219 | diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h | ||
| 220 | index b0125c2..74a2b64 100644 | ||
| 221 | --- a/libxslt/xsltInternals.h | ||
| 222 | +++ b/libxslt/xsltInternals.h | ||
| 223 | @@ -1916,7 +1916,7 @@ XSLTPUBFUN int XSLTCALL | ||
| 224 | xsltFlagRVTs( | ||
| 225 | xsltTransformContextPtr ctxt, | ||
| 226 | xmlXPathObjectPtr obj, | ||
| 227 | - void *val); | ||
| 228 | + int val); | ||
| 229 | XSLTPUBFUN void XSLTCALL | ||
| 230 | xsltFreeRVTs (xsltTransformContextPtr ctxt); | ||
| 231 | XSLTPUBFUN void XSLTCALL | ||
diff --git a/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-004.patch b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-004.patch new file mode 100644 index 0000000000..59e7c1bad3 --- /dev/null +++ b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-004.patch | |||
| @@ -0,0 +1,349 @@ | |||
| 1 | From 91c9c56dcca01bfe3f9dae74fb75dcf792ebe58b Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Nick Wellnhofer <wellnhofer@aevum.de> | ||
| 3 | Date: Wed, 31 Aug 2022 13:35:23 +0200 | ||
| 4 | Subject: [PATCH] Make generate-id() deterministic | ||
| 5 | |||
| 6 | Rework the generate-id() function to return deterministic values. We use | ||
| 7 | a simple incrementing counter and store ids in the 'psvi' member of | ||
| 8 | nodes which was freed up by previous commits. The presence of an id is | ||
| 9 | indicated by a new "source node" flag. | ||
| 10 | |||
| 11 | This fixes long-standing problems with reproducible builds, see | ||
| 12 | https://bugzilla.gnome.org/show_bug.cgi?id=751621 | ||
| 13 | |||
| 14 | This also hardens security, as the old implementation leaked the | ||
| 15 | difference between a heap and a global pointer, see | ||
| 16 | https://bugs.chromium.org/p/chromium/issues/detail?id=1356211 | ||
| 17 | |||
| 18 | The old implementation could also generate the same id for dynamically | ||
| 19 | created nodes which happened to reuse the same memory. Ids for namespace | ||
| 20 | nodes were completely broken. They now use the id of the parent element | ||
| 21 | together with the hex-encoded namespace prefix. | ||
| 22 | |||
| 23 | CVE: CVE-2023-40403 | ||
| 24 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/commit/82f6cbf8ca61b1f9e00dc04aa3b15d563e7bbc6d] | ||
| 25 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
| 26 | |||
| 27 | --- | ||
| 28 | libxslt/functions.c | 107 +++++++++++++++++++++++++----- | ||
| 29 | libxslt/xsltInternals.h | 1 + | ||
| 30 | libxslt/xsltutils.h | 1 + | ||
| 31 | tests/REC/test-12.4-1.out | 11 +++ | ||
| 32 | tests/REC/test-12.4-1.xml | 6 ++ | ||
| 33 | tests/REC/test-12.4-1.xsl | 38 +++++++++++ | ||
| 34 | tests/exslt/common/dynamic-id.out | 13 ++++ | ||
| 35 | tests/exslt/common/dynamic-id.xml | 1 + | ||
| 36 | tests/exslt/common/dynamic-id.xsl | 29 ++++++++ | ||
| 37 | 9 files changed, 191 insertions(+), 16 deletions(-) | ||
| 38 | create mode 100644 tests/REC/test-12.4-1.out | ||
| 39 | create mode 100644 tests/REC/test-12.4-1.xml | ||
| 40 | create mode 100644 tests/REC/test-12.4-1.xsl | ||
| 41 | create mode 100644 tests/exslt/common/dynamic-id.out | ||
| 42 | create mode 100644 tests/exslt/common/dynamic-id.xml | ||
| 43 | create mode 100644 tests/exslt/common/dynamic-id.xsl | ||
| 44 | |||
| 45 | diff --git a/libxslt/functions.c b/libxslt/functions.c | ||
| 46 | index 7887dda..da25c24 100644 | ||
| 47 | --- a/libxslt/functions.c | ||
| 48 | +++ b/libxslt/functions.c | ||
| 49 | @@ -693,11 +693,16 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) | ||
| 50 | */ | ||
| 51 | void | ||
| 52 | xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ | ||
| 53 | - static char base_address; | ||
| 54 | + xsltTransformContextPtr tctxt; | ||
| 55 | xmlNodePtr cur = NULL; | ||
| 56 | xmlXPathObjectPtr obj = NULL; | ||
| 57 | - long val; | ||
| 58 | - xmlChar str[30]; | ||
| 59 | + char *str; | ||
| 60 | + const xmlChar *nsPrefix = NULL; | ||
| 61 | + void **psviPtr; | ||
| 62 | + unsigned long id; | ||
| 63 | + size_t size, nsPrefixSize; | ||
| 64 | + | ||
| 65 | + tctxt = xsltXPathGetTransformContext(ctxt); | ||
| 66 | |||
| 67 | if (nargs == 0) { | ||
| 68 | cur = ctxt->context->node; | ||
| 69 | @@ -707,16 +712,15 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ | ||
| 70 | |||
| 71 | if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { | ||
| 72 | ctxt->error = XPATH_INVALID_TYPE; | ||
| 73 | - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, | ||
| 74 | + xsltTransformError(tctxt, NULL, NULL, | ||
| 75 | "generate-id() : invalid arg expecting a node-set\n"); | ||
| 76 | - return; | ||
| 77 | + goto out; | ||
| 78 | } | ||
| 79 | obj = valuePop(ctxt); | ||
| 80 | nodelist = obj->nodesetval; | ||
| 81 | if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) { | ||
| 82 | - xmlXPathFreeObject(obj); | ||
| 83 | valuePush(ctxt, xmlXPathNewCString("")); | ||
| 84 | - return; | ||
| 85 | + goto out; | ||
| 86 | } | ||
| 87 | cur = nodelist->nodeTab[0]; | ||
| 88 | for (i = 1;i < nodelist->nodeNr;i++) { | ||
| 89 | @@ -725,22 +729,93 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ | ||
| 90 | cur = nodelist->nodeTab[i]; | ||
| 91 | } | ||
| 92 | } else { | ||
| 93 | - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, | ||
| 94 | + xsltTransformError(tctxt, NULL, NULL, | ||
| 95 | "generate-id() : invalid number of args %d\n", nargs); | ||
| 96 | ctxt->error = XPATH_INVALID_ARITY; | ||
| 97 | - return; | ||
| 98 | + goto out; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + size = 30; /* for "id%lu" */ | ||
| 102 | + | ||
| 103 | + if (cur->type == XML_NAMESPACE_DECL) { | ||
| 104 | + xmlNsPtr ns = (xmlNsPtr) cur; | ||
| 105 | + | ||
| 106 | + nsPrefix = ns->prefix; | ||
| 107 | + if (nsPrefix == NULL) | ||
| 108 | + nsPrefix = BAD_CAST ""; | ||
| 109 | + nsPrefixSize = xmlStrlen(nsPrefix); | ||
| 110 | + /* For "ns" and hex-encoded string */ | ||
| 111 | + size += nsPrefixSize * 2 + 2; | ||
| 112 | + | ||
| 113 | + /* Parent is stored in 'next'. */ | ||
| 114 | + cur = (xmlNodePtr) ns->next; | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + psviPtr = xsltGetPSVIPtr(cur); | ||
| 118 | + if (psviPtr == NULL) { | ||
| 119 | + xsltTransformError(tctxt, NULL, NULL, | ||
| 120 | + "generate-id(): invalid node type %d\n", cur->type); | ||
| 121 | + ctxt->error = XPATH_INVALID_TYPE; | ||
| 122 | + goto out; | ||
| 123 | } | ||
| 124 | |||
| 125 | - if (obj) | ||
| 126 | - xmlXPathFreeObject(obj); | ||
| 127 | + if (xsltGetSourceNodeFlags(cur) & XSLT_SOURCE_NODE_HAS_ID) { | ||
| 128 | + id = (unsigned long) *psviPtr; | ||
| 129 | + } else { | ||
| 130 | + if (cur->type == XML_TEXT_NODE && cur->line == USHRT_MAX) { | ||
| 131 | + /* Text nodes store big line numbers in psvi. */ | ||
| 132 | + cur->line = 0; | ||
| 133 | + } else if (*psviPtr != NULL) { | ||
| 134 | + xsltTransformError(tctxt, NULL, NULL, | ||
| 135 | + "generate-id(): psvi already set\n"); | ||
| 136 | + ctxt->error = XPATH_MEMORY_ERROR; | ||
| 137 | + goto out; | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + if (tctxt->currentId == ULONG_MAX) { | ||
| 141 | + xsltTransformError(tctxt, NULL, NULL, | ||
| 142 | + "generate-id(): id overflow\n"); | ||
| 143 | + ctxt->error = XPATH_MEMORY_ERROR; | ||
| 144 | + goto out; | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + id = ++tctxt->currentId; | ||
| 148 | + *psviPtr = (void *) id; | ||
| 149 | + xsltSetSourceNodeFlags(tctxt, cur, XSLT_SOURCE_NODE_HAS_ID); | ||
| 150 | + } | ||
| 151 | |||
| 152 | - val = (long)((char *)cur - (char *)&base_address); | ||
| 153 | - if (val >= 0) { | ||
| 154 | - snprintf((char *)str, sizeof(str), "idp%ld", val); | ||
| 155 | + str = xmlMalloc(size); | ||
| 156 | + if (str == NULL) { | ||
| 157 | + xsltTransformError(tctxt, NULL, NULL, | ||
| 158 | + "generate-id(): out of memory\n"); | ||
| 159 | + ctxt->error = XPATH_MEMORY_ERROR; | ||
| 160 | + goto out; | ||
| 161 | + } | ||
| 162 | + if (nsPrefix == NULL) { | ||
| 163 | + snprintf(str, size, "id%lu", id); | ||
| 164 | } else { | ||
| 165 | - snprintf((char *)str, sizeof(str), "idm%ld", -val); | ||
| 166 | + size_t i, j; | ||
| 167 | + | ||
| 168 | + snprintf(str, size, "id%luns", id); | ||
| 169 | + | ||
| 170 | + /* | ||
| 171 | + * Only ASCII alphanumerics are allowed, so we hex-encode the prefix. | ||
| 172 | + */ | ||
| 173 | + j = strlen(str); | ||
| 174 | + for (i = 0; i < nsPrefixSize; i++) { | ||
| 175 | + int v; | ||
| 176 | + | ||
| 177 | + v = nsPrefix[i] >> 4; | ||
| 178 | + str[j++] = v < 10 ? '0' + v : 'A' + (v - 10); | ||
| 179 | + v = nsPrefix[i] & 15; | ||
| 180 | + str[j++] = v < 10 ? '0' + v : 'A' + (v - 10); | ||
| 181 | + } | ||
| 182 | + str[j] = '\0'; | ||
| 183 | } | ||
| 184 | - valuePush(ctxt, xmlXPathNewString(str)); | ||
| 185 | + valuePush(ctxt, xmlXPathWrapString(BAD_CAST str)); | ||
| 186 | + | ||
| 187 | +out: | ||
| 188 | + xmlXPathFreeObject(obj); | ||
| 189 | } | ||
| 190 | |||
| 191 | /** | ||
| 192 | diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h | ||
| 193 | index 74a2b64..2fd1f68 100644 | ||
| 194 | --- a/libxslt/xsltInternals.h | ||
| 195 | +++ b/libxslt/xsltInternals.h | ||
| 196 | @@ -1787,6 +1787,7 @@ struct _xsltTransformContext { | ||
| 197 | unsigned long opLimit; | ||
| 198 | unsigned long opCount; | ||
| 199 | int sourceDocDirty; | ||
| 200 | + unsigned long currentId; /* For generate-id() */ | ||
| 201 | }; | ||
| 202 | |||
| 203 | /** | ||
| 204 | diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h | ||
| 205 | index dcfd139..6c14ecf 100644 | ||
| 206 | --- a/libxslt/xsltutils.h | ||
| 207 | +++ b/libxslt/xsltutils.h | ||
| 208 | @@ -250,6 +250,7 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL | ||
| 209 | #ifdef IN_LIBXSLT | ||
| 210 | #define XSLT_SOURCE_NODE_MASK 15 | ||
| 211 | #define XSLT_SOURCE_NODE_HAS_KEY 1 | ||
| 212 | +#define XSLT_SOURCE_NODE_HAS_ID 2 | ||
| 213 | int | ||
| 214 | xsltGetSourceNodeFlags(xmlNodePtr node); | ||
| 215 | int | ||
| 216 | diff --git a/tests/REC/test-12.4-1.out b/tests/REC/test-12.4-1.out | ||
| 217 | new file mode 100644 | ||
| 218 | index 0000000..237a9f2 | ||
| 219 | --- /dev/null | ||
| 220 | +++ b/tests/REC/test-12.4-1.out | ||
| 221 | @@ -0,0 +1,11 @@ | ||
| 222 | +<?xml version="1.0"?> | ||
| 223 | +<result> | ||
| 224 | + <document>id1</document> | ||
| 225 | + <element>id2</element> | ||
| 226 | + <attribute>id3</attribute> | ||
| 227 | + <namespace>id2ns</namespace> | ||
| 228 | + <namespace>id2nsC3A4C3B6C3BC</namespace> | ||
| 229 | + <text>id4</text> | ||
| 230 | + <comment>id5</comment> | ||
| 231 | + <processing-instruction>id6</processing-instruction> | ||
| 232 | +</result> | ||
| 233 | diff --git a/tests/REC/test-12.4-1.xml b/tests/REC/test-12.4-1.xml | ||
| 234 | new file mode 100644 | ||
| 235 | index 0000000..84484f6 | ||
| 236 | --- /dev/null | ||
| 237 | +++ b/tests/REC/test-12.4-1.xml | ||
| 238 | @@ -0,0 +1,6 @@ | ||
| 239 | +<doc xmlns="s:def"> | ||
| 240 | + <elem attr="value" xmlns:äöü="uri"/> | ||
| 241 | + <text>text</text> | ||
| 242 | + <!-- comment --> | ||
| 243 | + <?pi content?> | ||
| 244 | +</doc> | ||
| 245 | diff --git a/tests/REC/test-12.4-1.xsl b/tests/REC/test-12.4-1.xsl | ||
| 246 | new file mode 100644 | ||
| 247 | index 0000000..5cf5dd3 | ||
| 248 | --- /dev/null | ||
| 249 | +++ b/tests/REC/test-12.4-1.xsl | ||
| 250 | @@ -0,0 +1,38 @@ | ||
| 251 | +<xsl:stylesheet | ||
| 252 | + version="1.0" | ||
| 253 | + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | ||
| 254 | + xmlns:d="s:def" | ||
| 255 | + exclude-result-prefixes="d"> | ||
| 256 | + | ||
| 257 | +<xsl:output indent="yes"/> | ||
| 258 | + | ||
| 259 | +<xsl:template match="/"> | ||
| 260 | + <result> | ||
| 261 | + <document> | ||
| 262 | + <xsl:value-of select="generate-id(/)"/> | ||
| 263 | + </document> | ||
| 264 | + <element> | ||
| 265 | + <xsl:value-of select="generate-id(/d:doc/d:elem)"/> | ||
| 266 | + </element> | ||
| 267 | + <attribute> | ||
| 268 | + <xsl:value-of select="generate-id(d:doc/d:elem/@attr)"/> | ||
| 269 | + </attribute> | ||
| 270 | + <namespace> | ||
| 271 | + <xsl:value-of select="generate-id(d:doc/d:elem/namespace::*[local-name()=''])"/> | ||
| 272 | + </namespace> | ||
| 273 | + <namespace> | ||
| 274 | + <xsl:value-of select="generate-id(d:doc/d:elem/namespace::äöü)"/> | ||
| 275 | + </namespace> | ||
| 276 | + <text> | ||
| 277 | + <xsl:value-of select="generate-id(d:doc/d:text/text())"/> | ||
| 278 | + </text> | ||
| 279 | + <comment> | ||
| 280 | + <xsl:value-of select="generate-id(d:doc/comment())"/> | ||
| 281 | + </comment> | ||
| 282 | + <processing-instruction> | ||
| 283 | + <xsl:value-of select="generate-id(d:doc/processing-instruction())"/> | ||
| 284 | + </processing-instruction> | ||
| 285 | + </result> | ||
| 286 | +</xsl:template> | ||
| 287 | + | ||
| 288 | +</xsl:stylesheet> | ||
| 289 | diff --git a/tests/exslt/common/dynamic-id.out b/tests/exslt/common/dynamic-id.out | ||
| 290 | new file mode 100644 | ||
| 291 | index 0000000..1b7b7ba | ||
| 292 | --- /dev/null | ||
| 293 | +++ b/tests/exslt/common/dynamic-id.out | ||
| 294 | @@ -0,0 +1,13 @@ | ||
| 295 | +<?xml version="1.0"?> | ||
| 296 | +<result xmlns:exsl="http://exslt.org/common"> | ||
| 297 | + <id>id1</id> | ||
| 298 | + <id>id2</id> | ||
| 299 | + <id>id3</id> | ||
| 300 | + <id>id4</id> | ||
| 301 | + <id>id5</id> | ||
| 302 | + <id>id6</id> | ||
| 303 | + <id>id7</id> | ||
| 304 | + <id>id8</id> | ||
| 305 | + <id>id9</id> | ||
| 306 | + <id>id10</id> | ||
| 307 | +</result> | ||
| 308 | diff --git a/tests/exslt/common/dynamic-id.xml b/tests/exslt/common/dynamic-id.xml | ||
| 309 | new file mode 100644 | ||
| 310 | index 0000000..69d62f2 | ||
| 311 | --- /dev/null | ||
| 312 | +++ b/tests/exslt/common/dynamic-id.xml | ||
| 313 | @@ -0,0 +1 @@ | ||
| 314 | +<doc/> | ||
| 315 | diff --git a/tests/exslt/common/dynamic-id.xsl b/tests/exslt/common/dynamic-id.xsl | ||
| 316 | new file mode 100644 | ||
| 317 | index 0000000..8478f6a | ||
| 318 | --- /dev/null | ||
| 319 | +++ b/tests/exslt/common/dynamic-id.xsl | ||
| 320 | @@ -0,0 +1,29 @@ | ||
| 321 | +<xsl:stylesheet | ||
| 322 | + version="1.0" | ||
| 323 | + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | ||
| 324 | + xmlns:exsl="http://exslt.org/common"> | ||
| 325 | + | ||
| 326 | +<xsl:output indent="yes"/> | ||
| 327 | + | ||
| 328 | +<xsl:template name="dynamic-id"> | ||
| 329 | + <id> | ||
| 330 | + <xsl:value-of select="generate-id(exsl:node-set('string'))"/> | ||
| 331 | + </id> | ||
| 332 | +</xsl:template> | ||
| 333 | + | ||
| 334 | +<xsl:template match="/"> | ||
| 335 | + <result> | ||
| 336 | + <xsl:call-template name="dynamic-id"/> | ||
| 337 | + <xsl:call-template name="dynamic-id"/> | ||
| 338 | + <xsl:call-template name="dynamic-id"/> | ||
| 339 | + <xsl:call-template name="dynamic-id"/> | ||
| 340 | + <xsl:call-template name="dynamic-id"/> | ||
| 341 | + <xsl:call-template name="dynamic-id"/> | ||
| 342 | + <xsl:call-template name="dynamic-id"/> | ||
| 343 | + <xsl:call-template name="dynamic-id"/> | ||
| 344 | + <xsl:call-template name="dynamic-id"/> | ||
| 345 | + <xsl:call-template name="dynamic-id"/> | ||
| 346 | + </result> | ||
| 347 | +</xsl:template> | ||
| 348 | + | ||
| 349 | +</xsl:stylesheet> | ||
diff --git a/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-005.patch b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-005.patch new file mode 100644 index 0000000000..e27034a0ec --- /dev/null +++ b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-005.patch | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | From 3014af50b22f1be89b5514faea284de7b63fa5dc Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Nick Wellnhofer <wellnhofer@aevum.de> | ||
| 3 | Date: Wed, 31 Aug 2022 21:37:44 +0200 | ||
| 4 | Subject: [PATCH] Clean up attributes in source doc | ||
| 5 | |||
| 6 | Also make bit flag constants unsigned to avoid implicit-conversion | ||
| 7 | warnings. | ||
| 8 | |||
| 9 | CVE: CVE-2023-40403 | ||
| 10 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/commit/452fb4ca9b9803448826008b9573987c615912a1] | ||
| 11 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
| 12 | |||
| 13 | --- | ||
| 14 | libxslt/transform.c | 10 ++++++++++ | ||
| 15 | libxslt/xsltutils.h | 6 +++--- | ||
| 16 | 2 files changed, 13 insertions(+), 3 deletions(-) | ||
| 17 | |||
| 18 | diff --git a/libxslt/transform.c b/libxslt/transform.c | ||
| 19 | index 19d7326..7299eb5 100644 | ||
| 20 | --- a/libxslt/transform.c | ||
| 21 | +++ b/libxslt/transform.c | ||
| 22 | @@ -5764,6 +5764,16 @@ xsltCleanupSourceDoc(xmlDocPtr doc) { | ||
| 23 | if (psviPtr) | ||
| 24 | *psviPtr = NULL; | ||
| 25 | |||
| 26 | + if (cur->type == XML_ELEMENT_NODE) { | ||
| 27 | + xmlAttrPtr prop = cur->properties; | ||
| 28 | + | ||
| 29 | + while (prop) { | ||
| 30 | + prop->atype &= ~(XSLT_SOURCE_NODE_MASK << 27); | ||
| 31 | + prop->psvi = NULL; | ||
| 32 | + prop = prop->next; | ||
| 33 | + } | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | if (cur->children != NULL && cur->type != XML_ENTITY_REF_NODE) { | ||
| 37 | cur = cur->children; | ||
| 38 | } else { | ||
| 39 | diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h | ||
| 40 | index 6c14ecf..2af4282 100644 | ||
| 41 | --- a/libxslt/xsltutils.h | ||
| 42 | +++ b/libxslt/xsltutils.h | ||
| 43 | @@ -248,9 +248,9 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL | ||
| 44 | int flags); | ||
| 45 | |||
| 46 | #ifdef IN_LIBXSLT | ||
| 47 | -#define XSLT_SOURCE_NODE_MASK 15 | ||
| 48 | -#define XSLT_SOURCE_NODE_HAS_KEY 1 | ||
| 49 | -#define XSLT_SOURCE_NODE_HAS_ID 2 | ||
| 50 | +#define XSLT_SOURCE_NODE_MASK 15u | ||
| 51 | +#define XSLT_SOURCE_NODE_HAS_KEY 1u | ||
| 52 | +#define XSLT_SOURCE_NODE_HAS_ID 2u | ||
| 53 | int | ||
| 54 | xsltGetSourceNodeFlags(xmlNodePtr node); | ||
| 55 | int | ||
diff --git a/meta/recipes-support/libxslt/libxslt_1.1.35.bb b/meta/recipes-support/libxslt/libxslt_1.1.35.bb index 3df372b267..2291ed2cad 100644 --- a/meta/recipes-support/libxslt/libxslt_1.1.35.bb +++ b/meta/recipes-support/libxslt/libxslt_1.1.35.bb | |||
| @@ -16,6 +16,11 @@ DEPENDS = "libxml2" | |||
| 16 | SRC_URI = "https://download.gnome.org/sources/libxslt/1.1/libxslt-${PV}.tar.xz \ | 16 | SRC_URI = "https://download.gnome.org/sources/libxslt/1.1/libxslt-${PV}.tar.xz \ |
| 17 | file://CVE-2024-55549.patch \ | 17 | file://CVE-2024-55549.patch \ |
| 18 | file://CVE-2025-24855.patch \ | 18 | file://CVE-2025-24855.patch \ |
| 19 | file://CVE-2023-40403-001.patch \ | ||
| 20 | file://CVE-2023-40403-002.patch \ | ||
| 21 | file://CVE-2023-40403-003.patch \ | ||
| 22 | file://CVE-2023-40403-004.patch \ | ||
| 23 | file://CVE-2023-40403-005.patch \ | ||
| 19 | " | 24 | " |
| 20 | 25 | ||
| 21 | SRC_URI[sha256sum] = "8247f33e9a872c6ac859aa45018bc4c4d00b97e2feac9eebc10c93ce1f34dd79" | 26 | SRC_URI[sha256sum] = "8247f33e9a872c6ac859aa45018bc4c4d00b97e2feac9eebc10c93ce1f34dd79" |
