Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save timb-machine/1e4f935bca8a5a516f7dfa61d2d9cfc2 to your computer and use it in GitHub Desktop.
Save timb-machine/1e4f935bca8a5a516f7dfa61d2d9cfc2 to your computer and use it in GitHub Desktop.
CVE-2010-4577 & CVE-2010-0046 WebKit type confusion
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