1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import static android.os.SecurityStateManager.KEY_KERNEL_VERSION; 20 import static android.os.SecurityStateManager.KEY_SYSTEM_SPL; 21 import static android.os.SecurityStateManager.KEY_VENDOR_SPL; 22 23 import android.content.Context; 24 import android.content.pm.PackageManager; 25 import android.os.Binder; 26 import android.os.Build; 27 import android.os.Bundle; 28 import android.os.ISecurityStateManager; 29 import android.os.SystemProperties; 30 import android.os.VintfRuntimeInfo; 31 import android.text.TextUtils; 32 import android.util.Slog; 33 import android.webkit.WebViewProviderInfo; 34 import android.webkit.WebViewUpdateService; 35 36 import com.android.internal.R; 37 38 import java.util.regex.Matcher; 39 import java.util.regex.Pattern; 40 41 public class SecurityStateManagerService extends ISecurityStateManager.Stub { 42 43 private static final String TAG = "SecurityStateManagerService"; 44 45 static final String VENDOR_SECURITY_PATCH_PROPERTY_KEY = "ro.vendor.build" 46 + ".security_patch"; 47 static final Pattern KERNEL_RELEASE_PATTERN = Pattern.compile("(\\d+\\.\\d+\\.\\d+)(" 48 + ".*)"); 49 50 private final Context mContext; 51 private final PackageManager mPackageManager; 52 SecurityStateManagerService(Context context)53 public SecurityStateManagerService(Context context) { 54 mContext = context; 55 mPackageManager = context.getPackageManager(); 56 } 57 58 @Override getGlobalSecurityState()59 public Bundle getGlobalSecurityState() { 60 final long token = Binder.clearCallingIdentity(); 61 try { 62 return getGlobalSecurityStateInternal(); 63 } finally { 64 Binder.restoreCallingIdentity(token); 65 } 66 } 67 getGlobalSecurityStateInternal()68 private Bundle getGlobalSecurityStateInternal() { 69 Bundle globalSecurityState = new Bundle(); 70 globalSecurityState.putString(KEY_SYSTEM_SPL, Build.VERSION.SECURITY_PATCH); 71 globalSecurityState.putString(KEY_VENDOR_SPL, 72 SystemProperties.get(VENDOR_SECURITY_PATCH_PROPERTY_KEY, "")); 73 String moduleMetadataProviderPackageName = 74 mContext.getString(R.string.config_defaultModuleMetadataProvider); 75 if (!moduleMetadataProviderPackageName.isEmpty()) { 76 globalSecurityState.putString(moduleMetadataProviderPackageName, 77 getSpl(moduleMetadataProviderPackageName)); 78 } 79 globalSecurityState.putString(KEY_KERNEL_VERSION, getKernelVersion()); 80 addWebViewPackages(globalSecurityState); 81 addSecurityStatePackages(globalSecurityState); 82 return globalSecurityState; 83 } 84 getSpl(String packageName)85 private String getSpl(String packageName) { 86 if (!TextUtils.isEmpty(packageName)) { 87 try { 88 return mPackageManager.getPackageInfo(packageName, 0 /* flags */).versionName; 89 } catch (PackageManager.NameNotFoundException e) { 90 Slog.e(TAG, TextUtils.formatSimple("Failed to get SPL for package %s.", 91 packageName), e); 92 } 93 } 94 return ""; 95 } 96 getKernelVersion()97 private String getKernelVersion() { 98 Matcher matcher = KERNEL_RELEASE_PATTERN.matcher(VintfRuntimeInfo.getKernelVersion()); 99 if (matcher.matches()) { 100 return matcher.group(1); 101 } 102 return ""; 103 } 104 addWebViewPackages(Bundle bundle)105 private void addWebViewPackages(Bundle bundle) { 106 for (WebViewProviderInfo info : WebViewUpdateService.getAllWebViewPackages()) { 107 String packageName = info.packageName; 108 bundle.putString(packageName, getSpl(packageName)); 109 } 110 } 111 addSecurityStatePackages(Bundle bundle)112 private void addSecurityStatePackages(Bundle bundle) { 113 String[] packageNames; 114 packageNames = mContext.getResources().getStringArray(R.array.config_securityStatePackages); 115 for (String packageName : packageNames) { 116 bundle.putString(packageName, getSpl(packageName)); 117 } 118 } 119 } 120