Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9e8c0584 authored by Hui Shu's avatar Hui Shu
Browse files

Disallow WebView provider packages lower version than Chrome Stable

Doing so has security benefits, making sure the device is at least as secure as
the MonoChrome Stable on the system image.

This is implemented as checking WebView provider package versionCode against the
default available, non-fallback WebView provider package. On GMS devices, this
is MonoChrome Stable. On AOSP devices, this is standalone WebView.

BUG: 27469181
Change-Id: Id5b68ee28401a24843421cfcc3755e63196ac0f9
parent 70dc7e2f
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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.
     */
+1 −0
Original line number Diff line number Diff line
@@ -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);
+40 −3
Original line number Diff line number Diff line
@@ -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;

@@ -434,13 +437,47 @@ 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;