diff options
3 files changed, 47 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java index 6052a6e037c7..d82b8b4605c3 100644 --- a/services/core/java/com/android/server/webkit/SystemImpl.java +++ b/services/core/java/com/android/server/webkit/SystemImpl.java @@ -110,9 +110,7 @@ public class SystemImpl implements SystemInterface { Log.e(TAG, "Found an element that is not a webview provider"); } } - } catch(XmlPullParserException e) { - throw new MissingWebViewPackageException("Error when parsing WebView meta data " + e); - } catch(IOException e) { + } catch (XmlPullParserException | IOException e) { throw new MissingWebViewPackageException("Error when parsing WebView meta data " + e); } finally { if (parser != null) parser.close(); @@ -120,6 +118,11 @@ public class SystemImpl implements SystemInterface { return webViewProviders.toArray(new WebViewProviderInfo[webViewProviders.size()]); } + public int getFactoryPackageVersion(String packageName) throws NameNotFoundException { + PackageManager pm = AppGlobals.getInitialApplication().getPackageManager(); + return pm.getPackageInfo(packageName, PackageManager.MATCH_FACTORY_ONLY).versionCode; + } + /** * Reads all signatures at the current depth (within the current provider) from the XML parser. */ diff --git a/services/core/java/com/android/server/webkit/SystemInterface.java b/services/core/java/com/android/server/webkit/SystemInterface.java index b5eb0a711fa3..7bde37a5a4fd 100644 --- a/services/core/java/com/android/server/webkit/SystemInterface.java +++ b/services/core/java/com/android/server/webkit/SystemInterface.java @@ -32,6 +32,7 @@ import android.webkit.WebViewProviderInfo; public interface SystemInterface { public WebViewProviderInfo[] getWebViewPackages(); public int onWebViewProviderChanged(PackageInfo packageInfo); + public int getFactoryPackageVersion(String packageName) throws NameNotFoundException; public String getUserChosenWebViewProvider(Context context); public void updateUserSetting(Context context, String newProviderName); diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java index 4669676320d9..17efcc2d2830 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java @@ -20,6 +20,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -61,6 +62,8 @@ public class WebViewUpdateService extends SystemService { private int NUMBER_OF_RELROS_UNKNOWN = Integer.MAX_VALUE; + private int mMinimumVersionCode = -1; + // The WebView package currently in use (or the one we are preparing). private PackageInfo mCurrentWebViewPackage = null; @@ -435,12 +438,46 @@ public class WebViewUpdateService extends SystemService { /** + * Gets the minimum version code allowed for a valid provider. It is the minimum versionCode of + * all available-by-default and non-fallback WebView provider packages. If there is no such + * WebView provider package on the system, then return -1, which means all positive versionCode + * WebView packages are accepted. + */ + private int getMinimumVersionCode() { + if (mMinimumVersionCode > 0) { + return mMinimumVersionCode; + } + + for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) { + if (provider.availableByDefault && !provider.isFallback) { + try { + int versionCode = mSystemInterface.getFactoryPackageVersion(provider.packageName); + if (mMinimumVersionCode < 0 || versionCode < mMinimumVersionCode) { + mMinimumVersionCode = versionCode; + } + } catch (PackageManager.NameNotFoundException e) { + // Safe to ignore. + } + } + } + + return mMinimumVersionCode; + } + + /** * Returns whether this provider is valid for use as a WebView provider. */ - public boolean isValidProvider(WebViewProviderInfo configInfo, + private boolean isValidProvider(WebViewProviderInfo configInfo, PackageInfo packageInfo) { - if (providerHasValidSignature(configInfo, packageInfo) && - WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo) != null) { + if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 + && packageInfo.versionCode < getMinimumVersionCode() + && !mSystemInterface.systemIsDebuggable()) { + // Non-system package webview providers may be downgraded arbitrarily low, prevent that + // by enforcing minimum version code. This check is only enforced for user builds. + return false; + } + if (providerHasValidSignature(configInfo, packageInfo) + && WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo) != null) { return true; } return false; |