Package: libcroco3 Version: 0.6.12-2 Severity: normal Dear Maintainer,
The cr_sel_eng_get_matched_rulesets() function in cr-sel-eng.c can cause a denial of service (infinite loop) via a crafted CSS file. In the while loop(line 1378) of funtion cr_sel_eng_get_matched_rulesets(), cr_sel_eng_get_matched_rulesets_real() will always return "CR_OUTPUT_TOO_SHORT_ERROR" when parsing a malformed file, leading the while loop run infinitely. cr_sel_eng_get_matched_rulesets_real() returns array of the ruleset statements that matches the given xml node, it's prototype is as below: static enum CRStatus cr_sel_eng_get_matched_rulesets_real (CRSelEng * a_this, CRStyleSheet * a_stylesheet, xmlNode * a_node, CRStatement ** a_rulesets, gulong * a_len) *@param a_sel_eng the current selection engine *@param a_node the xml node for which the request *is being made. *@param a_sel_list the list of selectors to perform the search in. *@param a_rulesets in/out parameter. A pointer to the *returned array of rulesets statements that match the xml node *given in parameter. The caller allocates the array before calling this *function. *@param a_len in/out parameter the length (in sizeof (#CRStatement*)) *of the returned array. *(the length of a_rulesets, more precisely). *The caller must set it to the length of a_ruleset prior to calling this *function. In return, the function sets it to the length *(in sizeof (#CRStatement)) of the actually returned CRStatement array. *@return CR_OUTPUT_TOO_SHORT_ERROR if found more rulesets than the size *of the a_rulesets array. In this case, the first *a_len rulesets found *are put in a_rulesets, and a further call will return the following *ruleset(s) following the same principle. *@return CR_OK if all the rulesets found have been returned. In this *case, *a_len is set to the actual number of ruleset found. *@return CR_BAD_PARAM_ERROR in case any of the given parameter are *bad (e.g null pointer). *@return CR_ERROR if any other error occurred. */ CR_OUTPUT_TOO_SHORT_ERROR is returned if found more rulesets than the size of the a_rulesets array. In this case, the first *a_len rulesets found are put in a_rulesets, and a further call will return the following ruleset(s) following the same principle. However, if more than *a_len rulesets found , in a further call, the "a_this", "a_stylesheet" and "a_node" parameter will not change. Besides, the *a_len will always be 8 (see below) in this fuction ,thus results in another CR_OUTPUT_TOO_SHORT_ERROR, make the while loop run infinitely. *a_len not changed in every call: 1355 gulong tab_size = 0, 1356 tab_len = 0, 1357 index = 0; 1358 gushort stmts_chunck_size = 8; //stmts_chunck_size is a fixed value ... 1375 tab_size = stmts_chunck_size; 1376 tab_len = tab_size; //tab_size ,tab_len and stmts_chunck_size are equal(value is 8) 1377 1378 while ((status = cr_sel_eng_get_matched_rulesets_real 1379 (a_this, a_sheet, a_node, stmts_tab + index, &tab_len)) 1380 == CR_OUTPUT_TOO_SHORT_ERROR) { 1381 stmts_tab = g_try_realloc (stmts_tab, 1382 (tab_size + stmts_chunck_size) 1383 * sizeof (CRStatement *)); 1384 if (!stmts_tab) { 1385 cr_utils_trace_info ("Out of memory"); 1386 status = CR_ERROR; 1387 goto error; 1388 } 1389 tab_size += stmts_chunck_size;// tab_size always incresed by 8 1390 index += tab_len; // index's initial value is 0, the first time index incresed by 8 1391 tab_len = tab_size - index; /* tab_len will be 8 the first time,and causing index always incresed by 8, so in every loop ,tab_len is always 8, which will pass to cr_sel_eng_get_matched_rulesets_real() in the further call. So, in fuction cr_sel_eng_get_matched_rulesets_real, *a_len will not changed and always be 8. */ 1392 } -- System Information: Debian Release: 9.4 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'stable') Architecture: amd64 (x86_64) Kernel: Linux 4.9.0-6-amd64 (SMP w/1 CPU core) Locale: LANG=en_HK.UTF-8, LC_CTYPE=en_HK.UTF-8 (charmap=UTF-8), LANGUAGE=en_HK:en (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages libcroco3 depends on: ii libc6 2.24-11+deb9u3 ii libglib2.0-0 2.50.3-2 ii libxml2 2.9.4+dfsg1-2.2+deb9u2 -- Jin Huang, ADLab of Venustech