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.service.persistentdata.PersistentDataBlockManager; 35 import android.util.Slog; 36 37 import com.android.server.LocalServices; 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 @Override 182 public boolean isOemUnlockAllowed() { 183 enforceOemUnlockReadPermission(); 184 185 final long token = Binder.clearCallingIdentity(); 186 try { 187 return mOemLock.isOemUnlockAllowedByCarrier() && 188 mOemLock.isOemUnlockAllowedByDevice(); 189 } finally { 190 Binder.restoreCallingIdentity(token); 191 } 192 } 193 194 @Override 195 public boolean isDeviceOemUnlocked() { 196 enforceOemUnlockReadPermission(); 197 198 String locked = SystemProperties.get(FLASH_LOCK_PROP); 199 switch (locked) { 200 case FLASH_LOCK_UNLOCKED: 201 return true; 202 default: 203 return false; 204 } 205 } 206 }; 207 208 /** 209 * Always synchronize the OemUnlockAllowed bit to the FRP partition, which 210 * is used to erase FRP information on a unlockable device. 211 */ 212 private void setPersistentDataBlockOemUnlockAllowedBit(boolean allowed) { 213 final PersistentDataBlockManager pdbm = (PersistentDataBlockManager) 214 mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); 215 // if mOemLock is PersistentDataBlockLock, then the bit should have already been set 216 if (pdbm != null && !(mOemLock instanceof PersistentDataBlockLock)) { 217 Slog.i(TAG, "Update OEM Unlock bit in pst partition to " + allowed); 218 pdbm.setOemUnlockEnabled(allowed); 219 } 220 } 221 222 private boolean isOemUnlockAllowedByAdmin() { 223 return !UserManager.get(mContext) 224 .hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET, UserHandle.SYSTEM); 225 } 226 227 private void enforceManageCarrierOemUnlockPermission() { 228 mContext.enforceCallingOrSelfPermission( 229 Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE, 230 "Can't manage OEM unlock allowed by carrier"); 231 } 232 233 private void enforceManageUserOemUnlockPermission() { 234 mContext.enforceCallingOrSelfPermission( 235 Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE, 236 "Can't manage OEM unlock allowed by user"); 237 } 238 239 private void enforceOemUnlockReadPermission() { 240 if (mContext.checkCallingOrSelfPermission(Manifest.permission.READ_OEM_UNLOCK_STATE) 241 == PackageManager.PERMISSION_DENIED 242 && mContext.checkCallingOrSelfPermission(Manifest.permission.OEM_UNLOCK_STATE) 243 == PackageManager.PERMISSION_DENIED) { 244 throw new SecurityException("Can't access OEM unlock state. Requires " 245 + "READ_OEM_UNLOCK_STATE or OEM_UNLOCK_STATE permission."); 246 } 247 } 248 249 private void enforceUserIsAdmin() { 250 final int userId = UserHandle.getCallingUserId(); 251 final long token = Binder.clearCallingIdentity(); 252 try { 253 if (!UserManager.get(mContext).isUserAdmin(userId)) { 254 throw new SecurityException("Must be an admin user"); 255 } 256 } finally { 257 Binder.restoreCallingIdentity(token); 258 } 259 } 260 } 261