Stop loading other package's font by default.

Since CONTEXT_RESTRICTED is not a default flag of createPackageContext,
we can't rely on it for preventing unexpected font injections.
To protect developers and existing apps from a risk of font injection,
stop loading font from other package's resouce unless the developer
explicitly set CONTEXT_IGNORE_SECURITY.

Bug: 62813533
Bug: 62879353
Test: Manually done
Merged-In: I4442ddc48dadb5c968b444be86038b602074d301
Change-Id: I4442ddc48dadb5c968b444be86038b602074d301
(cherry picked from commit 6d6cd68660)
This commit is contained in:
Seigo Nonaka
2017-06-22 08:22:18 -07:00
committed by Neil Fuller
parent 17c78a1e6b
commit c25c3da8b6
5 changed files with 29 additions and 3 deletions

View File

@@ -2156,6 +2156,14 @@ class ContextImpl extends Context {
return (mFlags & Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) != 0; return (mFlags & Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) != 0;
} }
@Override
public boolean canLoadUnsafeResources() {
if (getPackageName().equals(getOpPackageName())) {
return true;
}
return (mFlags & Context.CONTEXT_IGNORE_SECURITY) != 0;
}
@Override @Override
public Display getDisplay() { public Display getDisplay() {
if (mDisplay == null) { if (mDisplay == null) {

View File

@@ -4680,6 +4680,12 @@ public abstract class Context {
@SystemApi @SystemApi
public abstract boolean isCredentialProtectedStorage(); public abstract boolean isCredentialProtectedStorage();
/**
* Returns true if the context can load unsafe resources, e.g. fonts.
* @hide
*/
public abstract boolean canLoadUnsafeResources();
/** /**
* @hide * @hide
*/ */

View File

@@ -925,6 +925,12 @@ public class ContextWrapper extends Context {
return mBase.isCredentialProtectedStorage(); return mBase.isCredentialProtectedStorage();
} }
/** {@hide} */
@Override
public boolean canLoadUnsafeResources() {
return mBase.canLoadUnsafeResources();
}
/** /**
* @hide * @hide
*/ */

View File

@@ -913,7 +913,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break; break;
case com.android.internal.R.styleable.TextAppearance_fontFamily: case com.android.internal.R.styleable.TextAppearance_fontFamily:
if (!context.isRestricted()) { if (!context.isRestricted() && context.canLoadUnsafeResources()) {
try { try {
fontTypeface = appearance.getFont(attr); fontTypeface = appearance.getFont(attr);
} catch (UnsupportedOperationException } catch (UnsupportedOperationException
@@ -1233,7 +1233,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break; break;
case com.android.internal.R.styleable.TextView_fontFamily: case com.android.internal.R.styleable.TextView_fontFamily:
if (!context.isRestricted()) { if (!context.isRestricted() && context.canLoadUnsafeResources()) {
try { try {
fontTypeface = a.getFont(attr); fontTypeface = a.getFont(attr);
} catch (UnsupportedOperationException | Resources.NotFoundException e) { } catch (UnsupportedOperationException | Resources.NotFoundException e) {
@@ -3417,7 +3417,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Typeface fontTypeface = null; Typeface fontTypeface = null;
String fontFamily = null; String fontFamily = null;
if (!context.isRestricted()) { if (!context.isRestricted() && context.canLoadUnsafeResources()) {
try { try {
fontTypeface = ta.getFont(R.styleable.TextAppearance_fontFamily); fontTypeface = ta.getFont(R.styleable.TextAppearance_fontFamily);
} catch (UnsupportedOperationException | Resources.NotFoundException e) { } catch (UnsupportedOperationException | Resources.NotFoundException e) {

View File

@@ -814,6 +814,12 @@ public class MockContext extends Context {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/** {@hide} */
@Override
public boolean canLoadUnsafeResources() {
throw new UnsupportedOperationException();
}
/** {@hide} */ /** {@hide} */
@Override @Override
public IBinder getActivityToken() { public IBinder getActivityToken() {