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