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