1 /* 2 * Copyright (C) 2017 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.oemlock; 18 19 import static android.Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE; 20 import static android.Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE; 21 import static android.Manifest.permission.OEM_UNLOCK_STATE; 22 import static android.Manifest.permission.READ_OEM_UNLOCK_STATE; 23 24 import android.annotation.EnforcePermission; 25 import android.annotation.Nullable; 26 import android.app.ActivityManager; 27 import android.content.Context; 28 import android.os.Binder; 29 import android.os.Bundle; 30 import android.os.IBinder; 31 import android.os.SystemProperties; 32 import android.os.UserHandle; 33 import android.os.UserManager; 34 import android.service.oemlock.IOemLockService; 35 import android.util.Slog; 36 37 import com.android.server.LocalServices; 38 import com.android.server.SystemService; 39 import com.android.server.pdb.PersistentDataBlockManagerInternal; 40 import com.android.server.pm.UserManagerInternal; 41 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; 42 import com.android.server.pm.UserRestrictionsUtils; 43 44 /** 45 * Service for managing the OEM lock state of the device. 46 * 47 * The OemLock HAL will be used if it is available, otherwise the persistent data block will be 48 * used. 49 */ 50 public class OemLockService extends SystemService { 51 private static final String TAG = "OemLock"; 52 53 private static final String FLASH_LOCK_PROP = "ro.boot.flash.locked"; 54 private static final String FLASH_LOCK_UNLOCKED = "0"; 55 56 private Context mContext; 57 private OemLock mOemLock; 58 isHalPresent()59 public static boolean isHalPresent() { 60 return (VendorLockHidl.getOemLockHalService() != null) 61 || (VendorLockAidl.getOemLockHalService() != null); 62 } 63 64 /** Select the OEM lock implementation */ getOemLock(Context context)65 private static OemLock getOemLock(Context context) { 66 if (VendorLockAidl.getOemLockHalService() != null) { 67 Slog.i(TAG, "Using vendor lock via the HAL(aidl)"); 68 return new VendorLockAidl(context); 69 } else if (VendorLockHidl.getOemLockHalService() != null) { 70 Slog.i(TAG, "Using vendor lock via the HAL(hidl)"); 71 return new VendorLockHidl(context); 72 } else { 73 Slog.i(TAG, "Using persistent data block based lock"); 74 return new PersistentDataBlockLock(context); 75 } 76 } 77 OemLockService(Context context)78 public OemLockService(Context context) { 79 this(context, getOemLock(context)); 80 } 81 OemLockService(Context context, OemLock oemLock)82 OemLockService(Context context, OemLock oemLock) { 83 super(context); 84 mContext = context; 85 mOemLock = oemLock; 86 87 LocalServices.getService(UserManagerInternal.class) 88 .addUserRestrictionsListener(mUserRestrictionsListener); 89 } 90 91 @Override onStart()92 public void onStart() { 93 publishBinderService(Context.OEM_LOCK_SERVICE, mService); 94 } 95 96 private final UserRestrictionsListener mUserRestrictionsListener = 97 new UserRestrictionsListener() { 98 @Override 99 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions, 100 Bundle prevRestrictions) { 101 // The admin can prevent OEM unlock with the DISALLOW_FACTORY_RESET user restriction 102 if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions, 103 UserManager.DISALLOW_FACTORY_RESET)) { 104 final boolean unlockAllowedByAdmin = 105 !newRestrictions.getBoolean(UserManager.DISALLOW_FACTORY_RESET); 106 if (!unlockAllowedByAdmin) { 107 mOemLock.setOemUnlockAllowedByDevice(false); 108 setPersistentDataBlockOemUnlockAllowedBit(false); 109 } 110 } 111 } 112 }; 113 114 /** 115 * Implements the binder interface for the service. 116 * 117 * This checks for the relevant permissions before forwarding the call to the OEM lock 118 * implementation being used on this device. 119 */ 120 private final IBinder mService = new IOemLockService.Stub() { 121 @Override 122 @Nullable 123 @EnforcePermission(MANAGE_CARRIER_OEM_UNLOCK_STATE) 124 public String getLockName() { 125 super.getLockName_enforcePermission(); 126 127 final long token = Binder.clearCallingIdentity(); 128 try { 129 return mOemLock.getLockName(); 130 } finally { 131 Binder.restoreCallingIdentity(token); 132 } 133 } 134 135 @Override 136 @EnforcePermission(MANAGE_CARRIER_OEM_UNLOCK_STATE) 137 public void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) { 138 super.setOemUnlockAllowedByCarrier_enforcePermission(); 139 140 enforceUserIsAdmin(); 141 142 final long token = Binder.clearCallingIdentity(); 143 try { 144 mOemLock.setOemUnlockAllowedByCarrier(allowed, signature); 145 } finally { 146 Binder.restoreCallingIdentity(token); 147 } 148 } 149 150 @Override 151 @EnforcePermission(MANAGE_CARRIER_OEM_UNLOCK_STATE) 152 public boolean isOemUnlockAllowedByCarrier() { 153 super.isOemUnlockAllowedByCarrier_enforcePermission(); 154 155 final long token = Binder.clearCallingIdentity(); 156 try { 157 return mOemLock.isOemUnlockAllowedByCarrier(); 158 } finally { 159 Binder.restoreCallingIdentity(token); 160 } 161 } 162 163 // The user has the final say so if they allow unlock, then the device allows the bootloader 164 // to OEM unlock it. 165 @Override 166 @EnforcePermission(MANAGE_USER_OEM_UNLOCK_STATE) 167 public void setOemUnlockAllowedByUser(boolean allowedByUser) { 168 super.setOemUnlockAllowedByUser_enforcePermission(); 169 170 if (ActivityManager.isUserAMonkey()) { 171 // Prevent a monkey from changing this 172 return; 173 } 174 enforceUserIsAdmin(); 175 176 final long token = Binder.clearCallingIdentity(); 177 try { 178 if (!isOemUnlockAllowedByAdmin()) { 179 throw new SecurityException("Admin does not allow OEM unlock"); 180 } 181 182 if (!mOemLock.isOemUnlockAllowedByCarrier()) { 183 throw new SecurityException("Carrier does not allow OEM unlock"); 184 } 185 186 mOemLock.setOemUnlockAllowedByDevice(allowedByUser); 187 setPersistentDataBlockOemUnlockAllowedBit(allowedByUser); 188 } finally { 189 Binder.restoreCallingIdentity(token); 190 } 191 } 192 193 @Override 194 @EnforcePermission(MANAGE_USER_OEM_UNLOCK_STATE) 195 public boolean isOemUnlockAllowedByUser() { 196 super.isOemUnlockAllowedByUser_enforcePermission(); 197 198 final long token = Binder.clearCallingIdentity(); 199 try { 200 return mOemLock.isOemUnlockAllowedByDevice(); 201 } finally { 202 Binder.restoreCallingIdentity(token); 203 } 204 } 205 206 /** Currently MasterClearConfirm will call isOemUnlockAllowed() 207 * to sync PersistentDataBlockOemUnlockAllowedBit which 208 * is needed before factory reset 209 * TODO: Figure out better place to run sync e.g. adding new API 210 */ 211 @Override 212 @EnforcePermission(anyOf = {READ_OEM_UNLOCK_STATE, OEM_UNLOCK_STATE}) 213 public boolean isOemUnlockAllowed() { 214 super.isOemUnlockAllowed_enforcePermission(); 215 216 final long token = Binder.clearCallingIdentity(); 217 try { 218 boolean allowed = mOemLock.isOemUnlockAllowedByCarrier() 219 && mOemLock.isOemUnlockAllowedByDevice(); 220 setPersistentDataBlockOemUnlockAllowedBit(allowed); 221 return allowed; 222 } finally { 223 Binder.restoreCallingIdentity(token); 224 } 225 } 226 227 @Override 228 @EnforcePermission(anyOf = {READ_OEM_UNLOCK_STATE, OEM_UNLOCK_STATE}) 229 public boolean isDeviceOemUnlocked() { 230 super.isDeviceOemUnlocked_enforcePermission(); 231 232 String locked = SystemProperties.get(FLASH_LOCK_PROP); 233 switch (locked) { 234 case FLASH_LOCK_UNLOCKED: 235 return true; 236 default: 237 return false; 238 } 239 } 240 }; 241 242 /** 243 * Always synchronize the OemUnlockAllowed bit to the FRP partition, which 244 * is used to erase FRP information on a unlockable device. 245 */ setPersistentDataBlockOemUnlockAllowedBit(boolean allowed)246 private void setPersistentDataBlockOemUnlockAllowedBit(boolean allowed) { 247 final PersistentDataBlockManagerInternal pdbmi 248 = LocalServices.getService(PersistentDataBlockManagerInternal.class); 249 // if mOemLock is PersistentDataBlockLock, then the bit should have already been set 250 if (pdbmi != null && !(mOemLock instanceof PersistentDataBlockLock)) { 251 Slog.i(TAG, "Update OEM Unlock bit in pst partition to " + allowed); 252 pdbmi.forceOemUnlockEnabled(allowed); 253 } 254 } 255 isOemUnlockAllowedByAdmin()256 private boolean isOemUnlockAllowedByAdmin() { 257 return !UserManager.get(mContext) 258 .hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET, UserHandle.SYSTEM); 259 } 260 enforceUserIsAdmin()261 private void enforceUserIsAdmin() { 262 final int userId = UserHandle.getCallingUserId(); 263 final long token = Binder.clearCallingIdentity(); 264 try { 265 if (!UserManager.get(mContext).isUserAdmin(userId)) { 266 throw new SecurityException("Must be an admin user"); 267 } 268 } finally { 269 Binder.restoreCallingIdentity(token); 270 } 271 } 272 } 273