commit:     2c5ef4bf3c0497dd26da1f97b48e3a4b2e11241e
Author:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Tue May 25 21:42:08 2021 +0000
Commit:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Tue May 25 21:42:19 2021 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=2c5ef4bf

dev-libs/libcroco: fix CVE-2020-12825

Bug: https://bugs.gentoo.org/722752
Package-Manager: Portage-3.0.18, Repoman-3.0.3
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>

 .../files/libcroco-0.6.13-CVE-2020-12825.patch     | 187 +++++++++++++++++++++
 dev-libs/libcroco/libcroco-0.6.13-r1.ebuild        |  57 +++++++
 2 files changed, 244 insertions(+)

diff --git a/dev-libs/libcroco/files/libcroco-0.6.13-CVE-2020-12825.patch 
b/dev-libs/libcroco/files/libcroco-0.6.13-CVE-2020-12825.patch
new file mode 100644
index 00000000000..26fc677eb16
--- /dev/null
+++ b/dev-libs/libcroco/files/libcroco-0.6.13-CVE-2020-12825.patch
@@ -0,0 +1,187 @@
+From 44cbd1e718d6a08e59b9300280c340218a84e089 Mon Sep 17 00:00:00 2001
+From: Michael Catanzaro <[email protected]>
+Date: Wed, 12 Aug 2020 13:54:15 -0500
+Subject: [PATCH] libcroco: Limit recursion in block and any productions
+ (CVE-2020-12825)
+
+If we don't have any limits, we can recurse forever and overflow the
+stack.
+
+This is per https://gitlab.gnome.org/Archive/libcroco/-/issues/8
+
+https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1404
+---
+ src/cr-parser.c | 44 ++++++++++++++++++++++++++--------------
+ 1 file changed, 29 insertions(+), 15 deletions(-)
+
+diff --git a/src/cr-parser.c b/src/cr-parser.c
+index 07f4ed9e8b..8304b75614 100644
+--- a/src/cr-parser.c
++++ b/src/cr-parser.c
+@@ -136,6 +136,8 @@ struct _CRParserPriv {
+ 
+ #define CHARS_TAB_SIZE 12
+ 
++#define RECURSIVE_CALLERS_LIMIT 100
++
+ /**
+  * IS_NUM:
+  *@a_char: the char to test.
+@@ -343,9 +345,11 @@ static enum CRStatus cr_parser_parse_selector_core 
(CRParser * a_this);
+ 
+ static enum CRStatus cr_parser_parse_declaration_core (CRParser * a_this);
+ 
+-static enum CRStatus cr_parser_parse_any_core (CRParser * a_this);
++static enum CRStatus cr_parser_parse_any_core (CRParser * a_this,
++                                               guint      n_calls);
+ 
+-static enum CRStatus cr_parser_parse_block_core (CRParser * a_this);
++static enum CRStatus cr_parser_parse_block_core (CRParser * a_this,
++                                                 guint      n_calls);
+ 
+ static enum CRStatus cr_parser_parse_value_core (CRParser * a_this);
+ 
+@@ -783,7 +787,7 @@ cr_parser_parse_atrule_core (CRParser * a_this)
+         cr_parser_try_to_skip_spaces_and_comments (a_this);
+ 
+         do {
+-                status = cr_parser_parse_any_core (a_this);
++                status = cr_parser_parse_any_core (a_this, 0);
+         } while (status == CR_OK);
+ 
+         status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr,
+@@ -794,7 +798,7 @@ cr_parser_parse_atrule_core (CRParser * a_this)
+                 cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, 
+                                       token);
+                 token = NULL;
+-                status = cr_parser_parse_block_core (a_this);
++                status = cr_parser_parse_block_core (a_this, 0);
+                 CHECK_PARSING_STATUS (status,
+                                       FALSE);
+                 goto done;
+@@ -929,11 +933,11 @@ cr_parser_parse_selector_core (CRParser * a_this)
+ 
+         RECORD_INITIAL_POS (a_this, &init_pos);
+ 
+-        status = cr_parser_parse_any_core (a_this);
++        status = cr_parser_parse_any_core (a_this, 0);
+         CHECK_PARSING_STATUS (status, FALSE);
+ 
+         do {
+-                status = cr_parser_parse_any_core (a_this);
++                status = cr_parser_parse_any_core (a_this, 0);
+ 
+         } while (status == CR_OK);
+ 
+@@ -955,10 +959,12 @@ cr_parser_parse_selector_core (CRParser * a_this)
+  *in chapter 4.1 of the css2 spec.
+  *block ::= '{' S* [ any | block | ATKEYWORD S* | ';' ]* '}' S*;
+  *@param a_this the current instance of #CRParser.
++ *@param n_calls used to limit recursion depth
+  *FIXME: code this function.
+  */
+ static enum CRStatus
+-cr_parser_parse_block_core (CRParser * a_this)
++cr_parser_parse_block_core (CRParser * a_this,
++                            guint      n_calls)
+ {
+         CRToken *token = NULL;
+         CRInputPos init_pos;
+@@ -966,6 +972,9 @@ cr_parser_parse_block_core (CRParser * a_this)
+ 
+         g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR);
+ 
++        if (n_calls > RECURSIVE_CALLERS_LIMIT)
++                return CR_ERROR;
++
+         RECORD_INITIAL_POS (a_this, &init_pos);
+ 
+         status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token);
+@@ -995,13 +1004,13 @@ cr_parser_parse_block_core (CRParser * a_this)
+         } else if (token->type == CBO_TK) {
+                 cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token);
+                 token = NULL;
+-                status = cr_parser_parse_block_core (a_this);
++                status = cr_parser_parse_block_core (a_this, n_calls + 1);
+                 CHECK_PARSING_STATUS (status, FALSE);
+                 goto parse_block_content;
+         } else {
+                 cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token);
+                 token = NULL;
+-                status = cr_parser_parse_any_core (a_this);
++                status = cr_parser_parse_any_core (a_this, n_calls + 1);
+                 CHECK_PARSING_STATUS (status, FALSE);
+                 goto parse_block_content;
+         }
+@@ -1108,7 +1117,7 @@ cr_parser_parse_value_core (CRParser * a_this)
+                 status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr,
+                                                token);
+                 token = NULL;
+-                status = cr_parser_parse_block_core (a_this);
++                status = cr_parser_parse_block_core (a_this, 0);
+                 CHECK_PARSING_STATUS (status, FALSE);
+                 ref++;
+                 goto continue_parsing;
+@@ -1122,7 +1131,7 @@ cr_parser_parse_value_core (CRParser * a_this)
+                 status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr,
+                                                token);
+                 token = NULL;
+-                status = cr_parser_parse_any_core (a_this);
++                status = cr_parser_parse_any_core (a_this, 0);
+                 if (status == CR_OK) {
+                         ref++;
+                         goto continue_parsing;
+@@ -1161,10 +1170,12 @@ cr_parser_parse_value_core (CRParser * a_this)
+  *        | FUNCTION | DASHMATCH | '(' any* ')' | '[' any* ']' ] S*;
+  *
+  *@param a_this the current instance of #CRParser.
++ *@param n_calls used to limit recursion depth
+  *@return CR_OK upon successfull completion, an error code otherwise.
+  */
+ static enum CRStatus
+-cr_parser_parse_any_core (CRParser * a_this)
++cr_parser_parse_any_core (CRParser * a_this,
++                          guint      n_calls)
+ {
+         CRToken *token1 = NULL,
+                 *token2 = NULL;
+@@ -1173,6 +1184,9 @@ cr_parser_parse_any_core (CRParser * a_this)
+ 
+         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
+ 
++        if (n_calls > RECURSIVE_CALLERS_LIMIT)
++                return CR_ERROR;
++
+         RECORD_INITIAL_POS (a_this, &init_pos);
+ 
+         status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token1);
+@@ -1211,7 +1225,7 @@ cr_parser_parse_any_core (CRParser * a_this)
+                  *We consider parameter as being an "any*" production.
+                  */
+                 do {
+-                        status = cr_parser_parse_any_core (a_this);
++                        status = cr_parser_parse_any_core (a_this, n_calls + 
1);
+                 } while (status == CR_OK);
+ 
+                 ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
+@@ -1236,7 +1250,7 @@ cr_parser_parse_any_core (CRParser * a_this)
+                 }
+ 
+                 do {
+-                        status = cr_parser_parse_any_core (a_this);
++                        status = cr_parser_parse_any_core (a_this, n_calls + 
1);
+                 } while (status == CR_OK);
+ 
+                 ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
+@@ -1264,7 +1278,7 @@ cr_parser_parse_any_core (CRParser * a_this)
+                 }
+ 
+                 do {
+-                        status = cr_parser_parse_any_core (a_this);
++                        status = cr_parser_parse_any_core (a_this, n_calls + 
1);
+                 } while (status == CR_OK);
+ 
+                 ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
+-- 
+GitLab
+

diff --git a/dev-libs/libcroco/libcroco-0.6.13-r1.ebuild 
b/dev-libs/libcroco/libcroco-0.6.13-r1.ebuild
new file mode 100644
index 00000000000..8e6f4779040
--- /dev/null
+++ b/dev-libs/libcroco/libcroco-0.6.13-r1.ebuild
@@ -0,0 +1,57 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit gnome2 multilib-minimal
+
+DESCRIPTION="Generic Cascading Style Sheet (CSS) parsing and manipulation 
toolkit"
+HOMEPAGE="https://gitlab.gnome.org/Archive/libcroco";
+
+LICENSE="LGPL-2"
+SLOT="0.6"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 
~sparc ~x86 ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~sparc-solaris 
~x64-solaris ~x86-solaris"
+IUSE="test"
+RESTRICT="!test? ( test )"
+
+RDEPEND="
+       >=dev-libs/glib-2.34.3:2[${MULTILIB_USEDEP}]
+       >=dev-libs/libxml2-2.9.1-r4[${MULTILIB_USEDEP}]
+"
+DEPEND="${RDEPEND}"
+BDEPEND="
+       dev-util/gtk-doc-am
+       virtual/pkgconfig
+"
+
+PATCHES=( "${FILESDIR}"/${PN}-0.6.13-CVE-2020-12825.patch )
+
+src_prepare() {
+       if ! use test; then
+               # don't waste time building tests
+               sed 's/^\(SUBDIRS .*\=.*\)tests\(.*\)$/\1\2/' -i Makefile.am 
Makefile.in \
+                       || die "sed failed"
+       fi
+
+       gnome2_src_prepare
+}
+
+multilib_src_configure() {
+       ECONF_SOURCE=${S} \
+       gnome2_src_configure \
+               --disable-static \
+               $([[ ${CHOST} == *-darwin* ]] && echo --disable-Bsymbolic)
+
+       if multilib_is_native_abi; then
+               ln -s "${S}"/docs/reference/html docs/reference/html || die
+       fi
+}
+
+multilib_src_install() {
+       gnome2_src_install
+}
+
+multilib_src_install_all() {
+       DOCS=( AUTHORS ChangeLog HACKING NEWS README TODO )
+       einstalldocs
+}

Reply via email to