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 56 public static boolean isHalPresent() { 57 return VendorLock.getOemLockHalService() != null; 58 } 59 60 /** Select the OEM lock implementation */ 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 72 public OemLockService(Context context) { 73 this(context, getOemLock(context)); 74 } 75 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 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 public void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) { 117 enforceManageCarrierOemUnlockPermission(); 118 enforceUserIsAdmin(); 119 120 final long token = Binder.clearCallingIdentity(); 121 try { 122 mOemLock.setOemUnlockAllowedByCarrier(allowed, signature); 123 } finally { 124 Binder.restoreCallingIdentity(token); 125 } 126 } 127 128 @Override 129 public boolean isOemUnlockAllowedByCarrier() { 130 enforceManageCarrierOemUnlockPermission(); 131 132 final long token = Binder.clearCallingIdentity(); 133 try { 134 return mOemLock.isOemUnlockAllowedByCarrier(); 135 } finally { 136 Binder.restoreCallingIdentity(token); 137 } 138 } 139 140 // The user has the final say so if they allow unlock, then the device allows the bootloader 141 // to OEM unlock it. 142 @Override 143 public void setOemUnlockAllowedByUser(boolean allowedByUser) { 144 if (ActivityManager.isUserAMonkey()) { 145 // Prevent a monkey from changing this 146 return; 147 } 148 149 enforceManageUserOemUnlockPermission(); 150 enforceUserIsAdmin(); 151 152 final long token = Binder.clearCallingIdentity(); 153 try { 154 if (!isOemUnlockAllowedByAdmin()) { 155 throw new SecurityException("Admin does not allow OEM unlock"); 156 } 157 158 if (!mOemLock.isOemUnlockAllowedByCarrier()) { 159 throw new SecurityException("Carrier does not allow OEM unlock"); 160 } 161 162 mOemLock.setOemUnlockAllowedByDevice(allowedByUser); 163 setPersistentDataBlockOemUnlockAllowedBit(allowedByUser); 164 } finally { 165 Binder.restoreCallingIdentity(token); 166 } 167 } 168 169 @Override 170 public boolean isOemUnlockAllowedByUser() { 171 enforceManageUserOemUnlockPermission(); 172 173 final long token = Binder.clearCallingIdentity(); 174 try { 175 return mOemLock.isOemUnlockAllowedByDevice(); 176 } finally { 177 Binder.restoreCallingIdentity(token); 178 } 179 } 180 181 /** Currently MasterClearConfirm will call isOemUnlockAllowed() 182 * to sync PersistentDataBlockOemUnlockAllowedBit which 183 * is needed before factory reset 184 * TODO: Figure out better place to run sync e.g. adding new API 185 */ 186 @Override 187 public boolean isOemUnlockAllowed() { 188 enforceOemUnlockReadPermission(); 189 190 final long token = Binder.clearCallingIdentity(); 191 try { 192 boolean allowed = mOemLock.isOemUnlockAllowedByCarrier() 193 && mOemLock.isOemUnlockAllowedByDevice(); 194 setPersistentDataBlockOemUnlockAllowedBit(allowed); 195 return allowed; 196 } finally { 197 Binder.restoreCallingIdentity(token); 198 } 199 } 200 201 @Override 202 public boolean isDeviceOemUnlocked() { 203 enforceOemUnlockReadPermission(); 204 205 String locked = SystemProperties.get(FLASH_LOCK_PROP); 206 switch (locked) { 207 case FLASH_LOCK_UNLOCKED: 208 return true; 209 default: 210 return false; 211 } 212 } 213 }; 214 215 /** 216 * Always synchronize the OemUnlockAllowed bit to the FRP partition, which 217 * is used to erase FRP information on a unlockable device. 218 */ 219 private void setPersistentDataBlockOemUnlockAllowedBit(boolean allowed) { 220 final PersistentDataBlockManagerInternal pdbmi 221 = LocalServices.getService(PersistentDataBlockManagerInternal.class); 222 // if mOemLock is PersistentDataBlockLock, then the bit should have already been set 223 if (pdbmi != null && !(mOemLock instanceof PersistentDataBlockLock)) { 224 Slog.i(TAG, "Update OEM Unlock bit in pst partition to " + allowed); 225 pdbmi.forceOemUnlockEnabled(allowed); 226 } 227 } 228 229 private boolean isOemUnlockAllowedByAdmin() { 230 return !UserManager.get(mContext) 231 .hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET, UserHandle.SYSTEM); 232 } 233 234 private void enforceManageCarrierOemUnlockPermission() { 235 mContext.enforceCallingOrSelfPermission( 236 Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE, 237 "Can't manage OEM unlock allowed by carrier"); 238 } 239 240 private void enforceManageUserOemUnlockPermission() { 241 mContext.enforceCallingOrSelfPermission( 242 Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE, 243 "Can't manage OEM unlock allowed by user"); 244 } 245 246 private void enforceOemUnlockReadPermission() { 247 if (mContext.checkCallingOrSelfPermission(Manifest.permission.READ_OEM_UNLOCK_STATE) 248 == PackageManager.PERMISSION_DENIED 249 && mContext.checkCallingOrSelfPermission(Manifest.permission.OEM_UNLOCK_STATE) 250 == PackageManager.PERMISSION_DENIED) { 251 throw new SecurityException("Can't access OEM unlock state. Requires " 252 + "READ_OEM_UNLOCK_STATE or OEM_UNLOCK_STATE permission."); 253 } 254 } 255 256 private void enforceUserIsAdmin() { 257 final int userId = UserHandle.getCallingUserId(); 258 final long token = Binder.clearCallingIdentity(); 259 try { 260 if (!UserManager.get(mContext).isUserAdmin(userId)) { 261 throw new SecurityException("Must be an admin user"); 262 } 263 } finally { 264 Binder.restoreCallingIdentity(token); 265 } 266 } 267 } 268