Created
September 4, 2017 04:13
-
-
Save timb-machine/1e4f935bca8a5a516f7dfa61d2d9cfc2 to your computer and use it in GitHub Desktop.
CVE-2010-4577 & CVE-2010-0046 WebKit type confusion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CVE-2010-4577 | |
Red Hat - https://bugs.webkit.org/show_bug.cgi?id=49883 / http://trac.webkit.org/changeset/72685 | |
Bug report inaccessible but changeset: | |
CSSParserValueList* args = val->function->args.get(); | |
3632 3632 if (args && args->size() == 1) { | |
3633 if (equalIgnoringCase(val->function->name, "local(") && !expectComma) { | |
3633 if (equalIgnoringCase(val->function->name, "local(") && !expectComma && (args->current()->unit == CSSPrimitiveValue::CSS_STRING || args->current()->unit == CSSPrimitiveValue::CSS_IDENT)) { | |
3634 3634 expectComma = true; | |
3635 3635 allowFormat = false; | |
So it affects local()... | |
CVE-2010-0046 | |
Red Hat - https://bugs.webkit.org/show_bug.cgi?id=31815 / http://trac.webkit.org/changeset/51727 | |
Bug report inaccessible but changeset: | |
3339 3339 | |
3340 static bool isValidFormatFunction(CSSParserValue* val) | |
3341 { | |
3342 CSSParserValueList* args = val->function->args; | |
3343 return equalIgnoringCase(val->function->name, "format(") && (args->current()->unit == CSSPrimitiveValue::CSS_STRING || args->current()->unit == CSSPrimitiveValue::CSS_IDENT); | |
3344 } | |
3345 | |
3340 3346 bool CSSParser::parseFontFaceSrc() | |
3341 3347 { | |
… … | |
3365 3371 uriValue.clear(); | |
3366 3372 parsedValue = CSSFontFaceSrcValue::createLocal(a->string); | |
3367 } else if (equalIgnoringCase(val->function->name, "format(") && allowFormat && uriValue) { | |
3373 } else if (allowFormat && uriValue && isValidFormatFunction(val)) { | |
3368 3374 expectComma = true; | |
3369 3375 allowFormat = false; | |
So it affects format() | |
Context of the two issues: | |
static bool isValidFormatFunction(CSSParserValue* val) | |
3607 { | |
3608 CSSParserValueList* args = val->function->args.get(); | |
3609 return equalIgnoringCase(val->function->name, "format(") && (args->current()->unit == CSSPrimitiveValue::CSS_STRING || args->current()->unit == CSSPrimitiveValue::CSS_IDENT); | |
3610 } | |
3611 | |
3612 bool CSSParser::parseFontFaceSrc() | |
3613 { | |
3614 RefPtr<CSSValueList> values(CSSValueList::createCommaSeparated()); | |
3615 CSSParserValue* val; | |
3616 bool expectComma = false; | |
3617 bool allowFormat = false; | |
3618 bool failed = false; | |
3619 RefPtr<CSSFontFaceSrcValue> uriValue; | |
3620 while ((val = m_valueList->current())) { | |
3621 RefPtr<CSSFontFaceSrcValue> parsedValue; | |
3622 if (val->unit == CSSPrimitiveValue::CSS_URI && !expectComma && m_styleSheet) { | |
3623 // FIXME: The completeURL call should be done when using the CSSFontFaceSrcValue, | |
3624 // not when creating it. | |
3625 parsedValue = CSSFontFaceSrcValue::create(m_styleSheet->completeURL(val->string)); | |
3626 uriValue = parsedValue; | |
3627 allowFormat = true; | |
3628 expectComma = true; | |
3629 } else if (val->unit == CSSParserValue::Function) { | |
3630 // There are two allowed functions: local() and format(). | |
3631 CSSParserValueList* args = val->function->args.get(); | |
3632 if (args && args->size() == 1) { | |
3633 if (equalIgnoringCase(val->function->name, "local(") && !expectComma && (args->current()->unit == CSSPrimitiveValue::CSS_STRING || args->current()->unit == CSSPrimitiveValue::CSS_IDENT)) { | |
3634 expectComma = true; | |
3635 allowFormat = false; | |
3636 CSSParserValue* a = args->current(); | |
3637 uriValue.clear(); | |
3638 parsedValue = CSSFontFaceSrcValue::createLocal(a->string); | |
3639 } else if (allowFormat && uriValue && isValidFormatFunction(val)) { | |
3640 expectComma = true; | |
3641 allowFormat = false; | |
3642 uriValue->setFormat(args->current()->string); | |
3643 uriValue.clear(); | |
3644 m_valueList->next(); | |
3645 continue; | |
3646 } | |
3647 } | |
3648 } else if (val->unit == CSSParserValue::Operator && val->iValue == ',' && expectComma) { | |
3649 expectComma = false; | |
3650 allowFormat = false; | |
3651 uriValue.clear(); | |
3652 m_valueList->next(); | |
3653 continue; | |
3654 } | |
3655 | |
3656 if (parsedValue) | |
3657 values->append(parsedValue.release()); | |
3658 else { | |
3659 failed = true; | |
3660 break; | |
3661 } | |
3662 m_valueList->next(); | |
3663 } | |
3664 | |
3665 if (values->length() && !failed) { | |
3666 addProperty(CSSPropertySrc, values.release(), m_important); | |
3667 m_valueList->next(); | |
3668 return true; | |
3669 } | |
3670 | |
3671 return false; | |
3672 } | |
KDE patch: | |
https://projects.kde.org/projects/kde/kdelibs/repository/revisions/a872c8a969a8bd3706253d6ba24088e4f07f3352/entry/khtml/css/cssparser.cpp | |
diff --git a/khtml/css/cssparser.cpp b/khtml/css/cssparser.cpp | |
index 7559db3..c7472ba 100644 | |
--- a/khtml/css/cssparser.cpp | |
+++ b/khtml/css/cssparser.cpp | |
@@ -2275,8 +2275,11 @@ bool CSSParser::parseFontFaceSrc() | |
expectComma = true; | |
} else if (val->unit == Value::Function) { | |
// There are two allowed functions: local() and format(). | |
+ // For both we expect a string argument | |
ValueList *args = val->function->args; | |
- if (args && args->size() == 1) { | |
+ if (args && args->size() == 1 && | |
+ (args->current()->unit == CSSPrimitiveValue::CSS_STRING || | |
+ args->current()->unit == CSSPrimitiveValue::CSS_IDENT)) { | |
if (!strcasecmp(domString(val->function->name), "local(") && !expectComma) { | |
expectComma = true; | |
allowFormat = false; | |
Context: | |
} else if (val->unit == Value::Function) { | |
2277 | |
// There are two allowed functions: local() and format(). | |
2278 | |
// For both we expect a string argument | |
2279 | |
ValueList *args = val->function->args; | |
2280 | |
if (args && args->size() == 1 && | |
2281 | |
(args->current()->unit == CSSPrimitiveValue::CSS_STRING || | |
2282 | |
args->current()->unit == CSSPrimitiveValue::CSS_IDENT)) { | |
2283 | |
if (!strcasecmp(domString(val->function->name), "local(") && !expectComma) { | |
2284 | |
expectComma = true; | |
2285 | |
allowFormat = false; | |
2286 | |
Value* a = args->current(); | |
2287 | |
uriValue = 0; | |
2288 | |
parsedValue = new CSSFontFaceSrcValueImpl( domString( a->string ), true /*local src*/ ); | |
2289 | |
} else if (!strcasecmp(domString(val->function->name), "format(") && allowFormat && uriValue) { | |
2290 | |
expectComma = true; | |
2291 | |
allowFormat = false; | |
2292 | |
uriValue->setFormat( domString( args->current()->string ) ); | |
2293 | |
uriValue = 0; | |
2294 | |
valueList->next(); | |
2295 | |
continue; | |
2296 | |
} | |
2297 | |
} | |
i.e. fixes both. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment