From 0d9ae266bf9ed995be95a100aba3d104a0d0b118 Mon Sep 17 00:00:00 2001 From: wk333 <13474090681@163.com> Date: Thu, 28 Dec 2023 11:25:18 +0800 Subject: [PATCH] Fix CVE-2021-33391 (cherry picked from commit 53ddcbae70afb28af0f8d2db892750df089e63e5) --- CVE-2021-33391-pre.patch | 213 +++++++++++++++++++++++++++++++++++++++ CVE-2021-33391.patch | 63 ++++++++++++ tidy.spec | 7 +- 3 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 CVE-2021-33391-pre.patch create mode 100644 CVE-2021-33391.patch diff --git a/CVE-2021-33391-pre.patch b/CVE-2021-33391-pre.patch new file mode 100644 index 0000000..bdfc024 --- /dev/null +++ b/CVE-2021-33391-pre.patch @@ -0,0 +1,213 @@ +Origin: https://launchpadlibrarian.net/697070499/tidy-html5_2%3A5.6.0-11_2%3A5.6.0-11ubuntu0.20.04.1.diff.gz + +Partial backport of: + +From e56716f154f13b14fc5585146a85000fdd26d319 Mon Sep 17 00:00:00 2001 +From: Jim Derry +Date: Wed, 28 Jul 2021 19:45:57 -0400 +Subject: [PATCH] Improve internal documentation. Start general conversion to + eliminate and/or reduce recursion. + +--- + src/clean.c | 83 +- + src/lexer.c | 122 +- + src/lexer.h | 698 +++++--- + src/parser.c | 4554 ++++++++++++++++++++++++++++++++++-------------- + src/parser.h | 71 +- + src/tags.c | 4 +- + src/tags.h | 7 +- + src/tidy-int.h | 16 +- + src/tidylib.c | 2 + + 9 files changed, 3873 insertions(+), 1684 deletions(-) + +--- a/src/lexer.c ++++ b/src/lexer.c +@@ -4425,6 +4425,106 @@ static Node *ParseDocTypeDecl(TidyDocImp + return NULL; + } + ++ ++/****************************************************************************//* ++ ** MARK: - Node Stack ++ ***************************************************************************/ ++ ++ ++/** ++ * Create a new stack with a given starting capacity. If memory allocation ++ * fails, then the allocator will panic the program automatically. ++ */ ++Stack* TY_(newStack)(TidyDocImpl *doc, uint capacity) ++{ ++ Stack *stack = (Stack *)TidyAlloc(doc->allocator, sizeof(Stack)); ++ stack->top = -1; ++ stack->capacity = capacity; ++ stack->firstNode = (Node **)TidyAlloc(doc->allocator, stack->capacity * sizeof(Node**)); ++ stack->allocator = doc->allocator; ++ return stack; ++} ++ ++ ++/** ++ * Increase the stack size. This will be called automatically when the ++ * current stack is full. If memory allocation fails, then the allocator ++ * will panic the program automatically. ++ */ ++void TY_(growStack)(Stack *stack) ++{ ++ uint new_capacity = stack->capacity * 2; ++ ++ Node **firstNode = (Node **)TidyAlloc(stack->allocator, new_capacity); ++ ++ memcpy( firstNode, stack->firstNode, sizeof(Node**) * (stack->top + 1) ); ++ TidyFree(stack->allocator, stack->firstNode); ++ ++ stack->firstNode = firstNode; ++ stack->capacity = new_capacity; ++} ++ ++ ++/** ++ * Stack is full when top is equal to the last index. ++ */ ++Bool TY_(stackFull)(Stack *stack) ++{ ++ return stack->top == stack->capacity - 1; ++} ++ ++ ++/** ++ * Stack is empty when top is equal to -1 ++ */ ++Bool TY_(stackEmpty)(Stack *stack) ++{ ++ return stack->top == -1; ++} ++ ++ ++/** ++ * Push an item to the stack. ++ */ ++void TY_(push)(Stack *stack, Node *node) ++{ ++ if (TY_(stackFull)(stack)) ++ TY_(growStack)(stack); ++ ++ if (node) ++ stack->firstNode[++stack->top] = node; ++} ++ ++ ++/** ++ * Pop an item from the stack. ++ */ ++Node* TY_(pop)(Stack *stack) ++{ ++ return TY_(stackEmpty)(stack) ? NULL : stack->firstNode[stack->top--]; ++} ++ ++ ++/** ++ * Peek at the stack. ++ */ ++FUNC_UNUSED Node* TY_(peek)(Stack *stack) ++{ ++ return TY_(stackEmpty)(stack) ? NULL : stack->firstNode[stack->top--]; ++} ++ ++/** ++ * Frees the stack when done. ++ */ ++void TY_(freeStack)(Stack *stack) ++{ ++ TidyFree( stack->allocator, stack->firstNode ); ++ stack->top = -1; ++ stack->capacity = 0; ++ stack->firstNode = NULL; ++ stack->allocator = NULL; ++} ++ + /* + * local variables: + * mode: c +--- a/src/lexer.h ++++ b/src/lexer.h +@@ -594,6 +594,78 @@ Node* TY_(InsertedToken)( TidyDocImpl* d + Bool TY_(SwitchInline)( TidyDocImpl* doc, Node* element, Node* node ); + Bool TY_(InlineDup1)( TidyDocImpl* doc, Node* node, Node* element ); + ++/** @} ++ * @name Generic stack of nodes. ++ * @{ ++ */ ++ ++ ++/** ++ * This typedef represents a stack of addresses to nodes. Tidy uses these to ++ * try to limit recursion by pushing nodes to a stack when possible instead ++ * of recursing. ++ */ ++typedef struct _Stack { ++ int top; /**< Current top position. */ ++ unsigned capacity; /**< Current capacity. Can be expanded. */ ++ Node **firstNode; /** A pointer to the first pointer to a Node in an array of node addresses. */ ++ TidyAllocator* allocator; /**< Tidy's allocator, used at instantiation and expanding. */ ++} Stack; ++ ++ ++/** ++ * Create a new stack with a given starting capacity. If memory allocation ++ * fails, then the allocator will panic the program automatically. ++ */ ++Stack* TY_(newStack)(TidyDocImpl *doc, uint capacity); ++ ++ ++/** ++ * Increase the stack size. This will be called automatically when the ++ * current stack is full. If memory allocation fails, then the allocator ++ * will panic the program automatically. ++ */ ++void TY_(growStack)(Stack *stack); ++ ++ ++/** ++ * Stack is full when top is equal to the last index. ++ */ ++Bool TY_(stackFull)(Stack *stack); ++ ++ ++/** ++ * Stack is empty when top is equal to -1 ++ */ ++Bool TY_(stackEmpty)(Stack *stack); ++ ++ ++/** ++ * Push an item to the stack. ++ */ ++void TY_(push)(Stack *stack, Node *node); ++ ++ ++/** ++ * Pop an item from the stack. ++ */ ++Node* TY_(pop)(Stack *stack); ++ ++ ++/** ++ * Peek at the stack. ++ */ ++Node* TY_(peek)(Stack *stack); ++ ++/** ++ * Frees the stack when done. ++ */ ++void TY_(freeStack)(Stack *stack); ++ ++ ++/** @} ++ */ ++ + #ifdef __cplusplus + } + #endif + diff --git a/CVE-2021-33391.patch b/CVE-2021-33391.patch new file mode 100644 index 0000000..0cf5b94 --- /dev/null +++ b/CVE-2021-33391.patch @@ -0,0 +1,63 @@ +Origin: https://launchpadlibrarian.net/697070499/tidy-html5_2%3A5.6.0-11_2%3A5.6.0-11ubuntu0.20.04.1.diff.gz + +Backport of: + +From efa61528aa500a1efbd2768121820742d3bb709b Mon Sep 17 00:00:00 2001 +From: Jim Derry +Date: Sat, 31 Jul 2021 08:26:16 -0400 +Subject: [PATCH] Fixes #946 by refactoring the recursion into a loop with a + heap-based stack. + +--- + .../cases/github-cases/case-946.conf | 3 + + .../cases/github-cases/case-946@1.html | Bin 0 -> 11558 bytes + .../cases/github-expects/case-946.html | 44 +++ + .../cases/github-expects/case-946.txt | 330 ++++++++++++++++++ + src/gdoc.c | 13 +- + version.txt | 4 +- + 6 files changed, 388 insertions(+), 6 deletions(-) + create mode 100755 regression_testing/cases/github-cases/case-946.conf + create mode 100644 regression_testing/cases/github-cases/case-946@1.html + create mode 100644 regression_testing/cases/github-expects/case-946.html + create mode 100644 regression_testing/cases/github-expects/case-946.txt + +diff --git a/src/gdoc.c b/src/gdoc.c +index 50cd9bc33..8f5f8ffd7 100644 +--- a/src/gdoc.c ++++ b/src/gdoc.c +@@ -96,14 +96,15 @@ static void DiscardContainer( TidyDocImpl* doc, Node *element, Node **pnode) + + static void CleanNode( TidyDocImpl* doc, Node *node ) + { ++ Stack *stack = TY_(newStack)(doc, 16); + Node *child, *next; + +- if (node->content) ++ if ( (child = node->content) ) + { +- for (child = node->content; child != NULL; child = next) ++ while (child) + { + next = child->next; +- ++ + if (TY_(nodeIsElement)(child)) + { + if (nodeIsSTYLE(child)) +@@ -131,10 +132,14 @@ static void CleanNode( TidyDocImpl* doc, Node *node ) + if (child->attributes) + TY_(DropAttrByName)( doc, child, "class" ); + +- CleanNode(doc, child); ++ TY_(push)(stack,next); ++ child = child->content; ++ continue; + } + } ++ child = next ? next : TY_(pop)(stack); + } ++ TY_(freeStack)(stack); + } + } + + diff --git a/tidy.spec b/tidy.spec index dbedbb4..88afdaf 100644 --- a/tidy.spec +++ b/tidy.spec @@ -3,7 +3,7 @@ Name: tidy Version: 5.6.0 -Release: 4 +Release: 5 Summary: Utility to clean up and pretty print HTML/XHTML/XML License: W3C URL: http://www.html-tidy.org/ @@ -12,6 +12,8 @@ Source0: https://github.com/htacg/%{upname}/archive/%{version}.tar.gz#/%{u Patch0001: 0002-Issue-656-protect-against-NULL-node-set-in-loop.patch Patch0002: fix-memleak-in-GetTokenFromStream.patch Patch0003: free-attributes-before-return-NULL.patch +Patch0004: CVE-2021-33391-pre.patch +Patch0005: CVE-2021-33391.patch BuildRequires: gcc-c++ cmake gcc libxslt pkgconfig Provides: tidy-html5 = %{version}-%{release} @@ -82,6 +84,9 @@ ln -s tidyplatform.h $RPM_BUILD_ROOT%{_includedir}/platform.h %{_mandir}/* %changelog +* Thu Dec 28 2023 wangkai <13474090681@163.com> - 5.6.0-5 +- Fix CVE-2021-33391 + * Thu Nov 26 2020 yuboyun - 5.6.0-4 - Type:bugfix - ID:NA -- Gitee