blob: cb529f30b09f64c851ad9c71f16d63b3a689c500 [file] [log] [blame]
Todd Kennedy0eb97382017-10-03 16:57:22 -07001/*
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
17package com.android.server.pm.permission;
18
Todd Kennedyc971a452019-07-08 16:04:52 -070019import static android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY;
Todd Kennedy0eb97382017-10-03 16:57:22 -070020import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
21import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070022import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
23import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070024import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
25import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
Todd Kennedy3bc94722017-10-10 09:55:53 -070026import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Philip P. Moltmann48456672019-01-20 13:14:03 -080027import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070028import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
29import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
30import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
31import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070032import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
Philip P. Moltmannba742062019-04-08 13:22:44 -070035import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
Todd Kennedyc5b0e862019-07-16 09:47:58 -070036import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
Hongwei Wangf391b552018-04-06 13:52:46 -070037import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Todd Kennedyc971a452019-07-08 16:04:52 -070038import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070039import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
Hongwei Wangf391b552018-04-06 13:52:46 -070040
Todd Kennedyc29b11a2017-10-23 15:55:59 -070041import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
42import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
43import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
44import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
45import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Todd Kennedyc971a452019-07-08 16:04:52 -070046import static com.android.server.pm.permission.PermissionManagerService.killUid;
Philip P. Moltmann48456672019-01-20 13:14:03 -080047import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
48
49import static java.util.concurrent.TimeUnit.SECONDS;
Todd Kennedy0eb97382017-10-03 16:57:22 -070050
51import android.Manifest;
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -070052import android.annotation.IntDef;
Todd Kennedy0eb97382017-10-03 16:57:22 -070053import android.annotation.NonNull;
54import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070055import android.annotation.UserIdInt;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070056import android.app.ActivityManager;
Hai Zhang4ffebb72019-07-18 14:50:58 -070057import android.app.AppOpsManager;
Eugene Suslad516bee2019-05-01 09:48:43 -070058import android.app.ApplicationPackageManager;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070059import android.app.IActivityManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070060import android.content.Context;
61import android.content.pm.PackageManager;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070062import android.content.pm.PackageManager.PermissionGroupInfoFlags;
63import android.content.pm.PackageManager.PermissionInfoFlags;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070064import android.content.pm.PackageManager.PermissionWhitelistFlags;
Todd Kennedy0eb97382017-10-03 16:57:22 -070065import android.content.pm.PackageManagerInternal;
66import android.content.pm.PackageParser;
Hongwei Wangf391b552018-04-06 13:52:46 -070067import android.content.pm.PackageParser.Package;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070068import android.content.pm.ParceledListSlice;
Todd Kennedy460f28c2017-10-06 13:46:22 -070069import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070070import android.content.pm.PermissionInfo;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070071import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070072import android.os.Binder;
73import android.os.Build;
74import android.os.Handler;
75import android.os.HandlerThread;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070076import android.os.Looper;
77import android.os.Message;
Todd Kennedy0eb97382017-10-03 16:57:22 -070078import android.os.Process;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070079import android.os.RemoteCallbackList;
80import android.os.RemoteException;
Todd Kennedy8f135982019-07-02 07:35:15 -070081import android.os.ServiceManager;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070082import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070083import android.os.UserHandle;
84import android.os.UserManager;
85import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070086import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070087import android.os.storage.StorageManagerInternal;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070088import android.permission.IOnPermissionsChangeListener;
Todd Kennedy8f135982019-07-02 07:35:15 -070089import android.permission.IPermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -080090import android.permission.PermissionControllerManager;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070091import android.permission.PermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -080092import android.permission.PermissionManagerInternal;
Todd Kennedyca1ea172019-07-03 15:02:28 -070093import android.permission.PermissionManagerInternal.CheckPermissionDelegate;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070094import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070095import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070096import android.util.ArrayMap;
97import android.util.ArraySet;
Eugene Suslad516bee2019-05-01 09:48:43 -070098import android.util.DebugUtils;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -070099import android.util.EventLog;
Todd Kennedyc971a452019-07-08 16:04:52 -0700100import android.util.IntArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700101import android.util.Log;
102import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700103import android.util.SparseArray;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800104import android.util.SparseBooleanArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700105
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700106import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700107import com.android.internal.logging.MetricsLogger;
108import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700109import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700110import com.android.internal.util.ArrayUtils;
Todd Kennedyc971a452019-07-08 16:04:52 -0700111import com.android.internal.util.IntPair;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700112import com.android.internal.util.Preconditions;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700113import com.android.internal.util.function.pooled.PooledLambda;
114import com.android.server.FgThread;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700115import com.android.server.LocalServices;
116import com.android.server.ServiceThread;
117import com.android.server.SystemConfig;
118import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700119import com.android.server.pm.PackageManagerServiceUtils;
120import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700121import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700122import com.android.server.pm.UserManagerService;
Todd Kennedy583378d2019-07-12 06:50:30 -0700123import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider;
124import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider;
125import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800126import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700127import com.android.server.pm.permission.PermissionsState.PermissionState;
Svet Ganov3c499ea2019-07-26 17:45:56 -0700128import com.android.server.policy.PermissionPolicyInternal;
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -0700129import com.android.server.policy.SoftRestrictedPermissionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700130
131import libcore.util.EmptyArray;
132
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -0700133import java.lang.annotation.Retention;
134import java.lang.annotation.RetentionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700135import java.util.ArrayList;
Hongwei Wangf391b552018-04-06 13:52:46 -0700136import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700137import java.util.Iterator;
138import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700139import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700140import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700141import java.util.Set;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800142import java.util.concurrent.CompletableFuture;
143import java.util.concurrent.ExecutionException;
144import java.util.concurrent.TimeUnit;
145import java.util.concurrent.TimeoutException;
Todd Kennedy230c0a72019-07-03 13:06:35 -0700146import java.util.function.Consumer;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700147
148/**
149 * Manages all permissions and handles permissions related tasks.
150 */
Todd Kennedy8f135982019-07-02 07:35:15 -0700151public class PermissionManagerService extends IPermissionManager.Stub {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700152 private static final String TAG = "PackageManager";
153
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700154 /** Permission grant: not grant the permission. */
155 private static final int GRANT_DENIED = 1;
156 /** Permission grant: grant the permission as an install permission. */
157 private static final int GRANT_INSTALL = 2;
158 /** Permission grant: grant the permission as a runtime one. */
159 private static final int GRANT_RUNTIME = 3;
160 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
161 private static final int GRANT_UPGRADE = 4;
162
Philip P. Moltmann48456672019-01-20 13:14:03 -0800163 private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
164
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700165 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
166 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
167 /** Empty array to avoid allocations */
168 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700169
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -0800170 /**
171 * When these flags are set, the system should not automatically modify the permission grant
172 * state.
173 */
174 private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
175 | FLAG_PERMISSION_POLICY_FIXED
176 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
177
178 /** Permission flags set by the user */
179 private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
180 | FLAG_PERMISSION_USER_FIXED;
181
Hongwei Wangf391b552018-04-06 13:52:46 -0700182 /** If the permission of the value is granted, so is the key */
183 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
184
185 static {
186 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
187 Manifest.permission.ACCESS_FINE_LOCATION);
188 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
189 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
190 }
191
Todd Kennedy0eb97382017-10-03 16:57:22 -0700192 /** Lock to protect internal data access */
193 private final Object mLock;
194
195 /** Internal connection to the package manager */
196 private final PackageManagerInternal mPackageManagerInt;
197
198 /** Internal connection to the user manager */
199 private final UserManagerInternal mUserManagerInt;
200
Philip P. Moltmann48456672019-01-20 13:14:03 -0800201 /** Permission controller: User space permission management */
202 private PermissionControllerManager mPermissionControllerManager;
203
Todd Kennedy0eb97382017-10-03 16:57:22 -0700204 /** Default permission policy to provide proper behaviour out-of-the-box */
205 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
206
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700207 /**
208 * Built-in permissions. Read from system configuration files. Mapping is from
209 * UID to permission name.
210 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700211 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700212
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700213 /** Built-in group IDs given to all packages. Read from system configuration files. */
214 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700215
216 private final HandlerThread mHandlerThread;
217 private final Handler mHandler;
218 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700219 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700220
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700221 /** Internal storage for permissions and related settings */
222 @GuardedBy("mLock")
223 private final PermissionSettings mSettings;
224
225 @GuardedBy("mLock")
226 private ArraySet<String> mPrivappPermissionsViolations;
227
228 @GuardedBy("mLock")
229 private boolean mSystemReady;
230
Svet Ganov3c499ea2019-07-26 17:45:56 -0700231 @GuardedBy("mLock")
232 private PermissionPolicyInternal mPermissionPolicyInternal;
233
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700234 /**
235 * For each foreground/background permission the mapping:
236 * Background permission -> foreground permissions
237 */
238 @GuardedBy("mLock")
239 private ArrayMap<String, List<String>> mBackgroundPermissions;
240
Philip P. Moltmann48456672019-01-20 13:14:03 -0800241 /**
242 * A permission backup might contain apps that are not installed. In this case we delay the
243 * restoration until the app is installed.
244 *
245 * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
246 * there is <u>no more</u> delayed backup left.
247 */
248 @GuardedBy("mLock")
249 private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
250
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700251 /** Listeners for permission state (granting and flags) changes */
252 @GuardedBy("mLock")
253 final private ArrayList<OnRuntimePermissionStateChangedListener>
254 mRuntimePermissionStateChangedListeners = new ArrayList<>();
255
Todd Kennedyca1ea172019-07-03 15:02:28 -0700256 @GuardedBy("mLock")
257 private CheckPermissionDelegate mCheckPermissionDelegate;
258
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700259 @GuardedBy("mLock")
260 private final OnPermissionChangeListeners mOnPermissionChangeListeners;
261
Todd Kennedy583378d2019-07-12 06:50:30 -0700262 @GuardedBy("mLock")
263 private DefaultBrowserProvider mDefaultBrowserProvider;
264
265 @GuardedBy("mLock")
266 private DefaultDialerProvider mDefaultDialerProvider;
267
268 @GuardedBy("mLock")
269 private DefaultHomeProvider mDefaultHomeProvider;
270
Todd Kennedy230c0a72019-07-03 13:06:35 -0700271 // TODO: Take a look at the methods defined in the callback.
272 // The callback was initially created to support the split between permission
273 // manager and the package manager. However, it's started to be used for other
274 // purposes. It may make sense to keep as an abstraction, but, the methods
275 // necessary to be overridden may be different than what was initially needed
276 // for the split.
277 private PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
278 @Override
279 public void onGidsChanged(int appId, int userId) {
Todd Kennedyc971a452019-07-08 16:04:52 -0700280 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
Todd Kennedy230c0a72019-07-03 13:06:35 -0700281 }
282 @Override
283 public void onPermissionGranted(int uid, int userId) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700284 mOnPermissionChangeListeners.onPermissionsChanged(uid);
285
286 // Not critical; if this is lost, the application has to request again.
287 mPackageManagerInt.writeSettings(true);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700288 }
289 @Override
290 public void onInstallPermissionGranted() {
291 mPackageManagerInt.writeSettings(true);
292 }
293 @Override
294 public void onPermissionRevoked(int uid, int userId) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700295 mOnPermissionChangeListeners.onPermissionsChanged(uid);
296
297 // Critical; after this call the application should never have the permission
298 mPackageManagerInt.writeSettings(false);
299 final int appId = UserHandle.getAppId(uid);
300 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700301 }
302 @Override
303 public void onInstallPermissionRevoked() {
304 mPackageManagerInt.writeSettings(true);
305 }
306 @Override
307 public void onPermissionUpdated(int[] userIds, boolean sync) {
308 mPackageManagerInt.writePermissionSettings(userIds, !sync);
309 }
310 @Override
311 public void onInstallPermissionUpdated() {
312 mPackageManagerInt.writeSettings(true);
313 }
314 @Override
315 public void onPermissionRemoved() {
316 mPackageManagerInt.writeSettings(false);
317 }
318 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync,
319 int uid) {
320 onPermissionUpdated(updatedUserIds, sync);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700321 mOnPermissionChangeListeners.onPermissionsChanged(uid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700322 }
323 public void onInstallPermissionUpdatedNotifyListener(int uid) {
324 onInstallPermissionUpdated();
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700325 mOnPermissionChangeListeners.onPermissionsChanged(uid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700326 }
327 };
328
Todd Kennedy0eb97382017-10-03 16:57:22 -0700329 PermissionManagerService(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700330 @NonNull Object externalLock) {
331 mContext = context;
332 mLock = externalLock;
333 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
334 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700335 mSettings = new PermissionSettings(mLock);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700336
337 mHandlerThread = new ServiceThread(TAG,
338 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
339 mHandlerThread.start();
340 mHandler = new Handler(mHandlerThread.getLooper());
341 Watchdog.getInstance().addThread(mHandler);
342
343 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700344 context, mHandlerThread.getLooper(), this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700345 SystemConfig systemConfig = SystemConfig.getInstance();
346 mSystemPermissions = systemConfig.getSystemPermissions();
347 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700348 mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());
Todd Kennedy0eb97382017-10-03 16:57:22 -0700349
350 // propagate permission configuration
351 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
352 SystemConfig.getInstance().getPermissions();
353 synchronized (mLock) {
354 for (int i=0; i<permConfig.size(); i++) {
355 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
356 BasePermission bp = mSettings.getPermissionLocked(perm.name);
357 if (bp == null) {
358 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
359 mSettings.putPermissionLocked(perm.name, bp);
360 }
361 if (perm.gids != null) {
362 bp.setGids(perm.gids, perm.perUser);
363 }
364 }
365 }
366
Philip P. Moltmann48456672019-01-20 13:14:03 -0800367 PermissionManagerServiceInternalImpl localService =
368 new PermissionManagerServiceInternalImpl();
369 LocalServices.addService(PermissionManagerServiceInternal.class, localService);
370 LocalServices.addService(PermissionManagerInternal.class, localService);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700371 }
372
373 /**
374 * Creates and returns an initialized, internal service for use by other components.
375 * <p>
376 * The object returned is identical to the one returned by the LocalServices class using:
Philip P. Moltmann48456672019-01-20 13:14:03 -0800377 * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
Todd Kennedy0eb97382017-10-03 16:57:22 -0700378 * <p>
379 * NOTE: The external lock is temporary and should be removed. This needs to be a
380 * lock created by the permission manager itself.
381 */
Philip P. Moltmann48456672019-01-20 13:14:03 -0800382 public static PermissionManagerServiceInternal create(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700383 @NonNull Object externalLock) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800384 final PermissionManagerServiceInternal permMgrInt =
385 LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700386 if (permMgrInt != null) {
387 return permMgrInt;
388 }
Todd Kennedy8f135982019-07-02 07:35:15 -0700389 PermissionManagerService permissionService =
390 (PermissionManagerService) ServiceManager.getService("permissionmgr");
391 if (permissionService == null) {
392 permissionService =
393 new PermissionManagerService(context, externalLock);
394 ServiceManager.addService("permissionmgr", permissionService);
395 }
Philip P. Moltmann48456672019-01-20 13:14:03 -0800396 return LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700397 }
398
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700399 /**
400 * This method should typically only be used when granting or revoking
401 * permissions, since the app may immediately restart after this call.
402 * <p>
403 * If you're doing surgery on app code/data, use {@link PackageFreezer} to
404 * guard your work against the app being relaunched.
405 */
406 public static void killUid(int appId, int userId, String reason) {
407 final long identity = Binder.clearCallingIdentity();
408 try {
409 IActivityManager am = ActivityManager.getService();
410 if (am != null) {
411 try {
412 am.killUid(appId, userId, reason);
413 } catch (RemoteException e) {
414 /* ignore - same process */
415 }
416 }
417 } finally {
418 Binder.restoreCallingIdentity(identity);
419 }
420 }
421
Todd Kennedy0eb97382017-10-03 16:57:22 -0700422 @Nullable BasePermission getPermission(String permName) {
423 synchronized (mLock) {
424 return mSettings.getPermissionLocked(permName);
425 }
426 }
427
Todd Kennedy8f135982019-07-02 07:35:15 -0700428 @Override
429 public String[] getAppOpPermissionPackages(String permName) {
430 return getAppOpPermissionPackagesInternal(permName, getCallingUid());
431 }
432
433 private String[] getAppOpPermissionPackagesInternal(String permName, int callingUid) {
434 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
435 return null;
436 }
437 synchronized (mLock) {
438 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
439 if (pkgs == null) {
440 return null;
441 }
442 return pkgs.toArray(new String[pkgs.size()]);
443 }
444 }
445
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700446 @Override
447 @NonNull
448 public ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(
449 @PermissionGroupInfoFlags int flags) {
450 final int callingUid = getCallingUid();
451 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
452 return ParceledListSlice.emptyList();
453 }
454 synchronized (mLock) {
455 final int n = mSettings.mPermissionGroups.size();
456 final ArrayList<PermissionGroupInfo> out =
457 new ArrayList<PermissionGroupInfo>(n);
458 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
459 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
460 }
461 return new ParceledListSlice<>(out);
462 }
463 }
464
465
466 @Override
467 @Nullable
468 public PermissionGroupInfo getPermissionGroupInfo(String groupName,
469 @PermissionGroupInfoFlags int flags) {
470 final int callingUid = getCallingUid();
471 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
472 return null;
473 }
474 synchronized (mLock) {
475 return PackageParser.generatePermissionGroupInfo(
476 mSettings.mPermissionGroups.get(groupName), flags);
477 }
478 }
479
480
481 @Override
482 @Nullable
483 public PermissionInfo getPermissionInfo(String permName, String packageName,
484 @PermissionInfoFlags int flags) {
485 final int callingUid = getCallingUid();
486 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
487 return null;
488 }
489 synchronized (mLock) {
490 final BasePermission bp = mSettings.getPermissionLocked(permName);
491 if (bp == null) {
492 return null;
493 }
494 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
495 bp.getProtectionLevel(), packageName, callingUid);
496 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
497 }
498 }
499
500 @Override
501 @Nullable
502 public ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
503 @PermissionInfoFlags int flags) {
504 final int callingUid = getCallingUid();
505 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
506 return null;
507 }
508 synchronized (mLock) {
509 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
510 return null;
511 }
512 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
513 for (BasePermission bp : mSettings.mPermissions.values()) {
514 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
515 if (pi != null) {
516 out.add(pi);
517 }
518 }
519 return new ParceledListSlice<>(out);
520 }
521 }
522
Todd Kennedy6ffc5a62019-07-03 09:35:31 -0700523 @Override
524 public boolean addPermission(PermissionInfo info, boolean async) {
525 final int callingUid = getCallingUid();
526 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
527 throw new SecurityException("Instant apps can't add permissions");
528 }
529 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
530 throw new SecurityException("Label must be specified in permission");
531 }
532 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
533 final boolean added;
534 final boolean changed;
535 synchronized (mLock) {
536 BasePermission bp = mSettings.getPermissionLocked(info.name);
537 added = bp == null;
538 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
539 if (added) {
540 enforcePermissionCapLocked(info, tree);
541 bp = new BasePermission(info.name, tree.getSourcePackageName(),
542 BasePermission.TYPE_DYNAMIC);
543 } else if (!bp.isDynamic()) {
544 throw new SecurityException("Not allowed to modify non-dynamic permission "
545 + info.name);
546 }
547 changed = bp.addToTree(fixedLevel, info, tree);
548 if (added) {
549 mSettings.putPermissionLocked(info.name, bp);
550 }
551 }
552 if (changed) {
553 mPackageManagerInt.writeSettings(async);
554 }
555 return added;
556 }
557
558 @Override
559 public void removePermission(String permName) {
560 final int callingUid = getCallingUid();
561 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
562 throw new SecurityException("Instant applications don't have access to this method");
563 }
564 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
565 synchronized (mLock) {
566 final BasePermission bp = mSettings.getPermissionLocked(permName);
567 if (bp == null) {
568 return;
569 }
570 if (bp.isDynamic()) {
571 // TODO: switch this back to SecurityException
572 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
573 + permName);
574 }
575 mSettings.removePermissionLocked(permName);
576 mPackageManagerInt.writeSettings(false);
577 }
578 }
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700579
Todd Kennedy230c0a72019-07-03 13:06:35 -0700580 @Override
581 public int getPermissionFlags(String permName, String packageName, int userId) {
582 final int callingUid = getCallingUid();
583 return getPermissionFlagsInternal(permName, packageName, callingUid, userId);
584 }
585
586 private int getPermissionFlagsInternal(
587 String permName, String packageName, int callingUid, int userId) {
588 if (!mUserManagerInt.exists(userId)) {
589 return 0;
590 }
591
592 enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
593 enforceCrossUserPermission(callingUid, userId,
594 true, // requireFullPermission
595 false, // checkShell
596 false, // requirePermissionWhenSameUser
597 "getPermissionFlags");
598
599 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
600 if (pkg == null || pkg.mExtras == null) {
601 return 0;
602 }
603 synchronized (mLock) {
604 if (mSettings.getPermissionLocked(permName) == null) {
605 return 0;
606 }
607 }
608 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
609 return 0;
610 }
611 final PackageSetting ps = (PackageSetting) pkg.mExtras;
612 PermissionsState permissionsState = ps.getPermissionsState();
613 return permissionsState.getPermissionFlags(permName, userId);
614 }
615
616 @Override
617 public void updatePermissionFlags(String permName, String packageName, int flagMask,
618 int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) {
619 final int callingUid = getCallingUid();
620 boolean overridePolicy = false;
621
622 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
623 long callingIdentity = Binder.clearCallingIdentity();
624 try {
625 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
626 if (checkAdjustPolicyFlagPermission) {
627 mContext.enforceCallingOrSelfPermission(
628 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
629 "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
630 + " to change policy flags");
631 } else if (mPackageManagerInt.getTargetSdk(callingUid)
632 >= Build.VERSION_CODES.Q) {
633 throw new IllegalArgumentException(
634 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
635 + " to be checked for packages targeting "
636 + Build.VERSION_CODES.Q + " or later when changing policy "
637 + "flags");
638 }
639 overridePolicy = true;
640 }
641 } finally {
642 Binder.restoreCallingIdentity(callingIdentity);
643 }
644 }
645
646 updatePermissionFlagsInternal(
647 permName, packageName, flagMask, flagValues, callingUid, userId,
648 overridePolicy, mDefaultPermissionCallback);
649 }
650
651 private void updatePermissionFlagsInternal(String permName, String packageName, int flagMask,
652 int flagValues, int callingUid, int userId, boolean overridePolicy,
653 PermissionCallback callback) {
654 if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
655 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
656 Log.i(TAG, "System is updating flags for "
657 + permName + " for user " + userId + " "
658 + DebugUtils.flagsToString(
659 PackageManager.class, "FLAG_PERMISSION_", flagMask)
660 + " := "
661 + DebugUtils.flagsToString(
662 PackageManager.class, "FLAG_PERMISSION_", flagValues)
663 + " on behalf of uid " + callingUid
664 + " " + mPackageManagerInt.getNameForUid(callingUid),
665 new RuntimeException());
666 }
667
668 if (!mUserManagerInt.exists(userId)) {
669 return;
670 }
671
672 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
673
674 enforceCrossUserPermission(callingUid, userId,
675 true, // requireFullPermission
676 true, // checkShell
677 false, // requirePermissionWhenSameUser
678 "updatePermissionFlags");
679
680 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
681 throw new SecurityException("updatePermissionFlags requires "
682 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
683 }
684
685 // Only the system can change these flags and nothing else.
686 if (callingUid != Process.SYSTEM_UID) {
687 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
688 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
689 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
690 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
691 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
692 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
693 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
694 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
695 flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
696 }
697
698 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
699 if (pkg == null || pkg.mExtras == null) {
700 Log.e(TAG, "Unknown package: " + packageName);
701 return;
702 }
703 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
704 throw new IllegalArgumentException("Unknown package: " + packageName);
705 }
706
707 final BasePermission bp;
708 synchronized (mLock) {
709 bp = mSettings.getPermissionLocked(permName);
710 }
711 if (bp == null) {
712 throw new IllegalArgumentException("Unknown permission: " + permName);
713 }
714
715 final PackageSetting ps = (PackageSetting) pkg.mExtras;
716 final PermissionsState permissionsState = ps.getPermissionsState();
717 final boolean hadState =
718 permissionsState.getRuntimePermissionState(permName, userId) != null;
719 final boolean permissionUpdated =
720 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
721 if (permissionUpdated && bp.isRuntime()) {
722 notifyRuntimePermissionStateChanged(packageName, userId);
723 }
724 if (permissionUpdated && callback != null) {
725 // Install and runtime permissions are stored in different places,
726 // so figure out what permission changed and persist the change.
727 if (permissionsState.getInstallPermissionState(permName) != null) {
728 callback.onInstallPermissionUpdatedNotifyListener(pkg.applicationInfo.uid);
729 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
730 || hadState) {
731 callback.onPermissionUpdatedNotifyListener(new int[] { userId }, false,
732 pkg.applicationInfo.uid);
733 }
734 }
735 }
736
737 /**
738 * Update the permission flags for all packages and runtime permissions of a user in order
739 * to allow device or profile owner to remove POLICY_FIXED.
740 */
741 @Override
742 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues,
743 final int userId) {
744 final int callingUid = getCallingUid();
745 if (!mUserManagerInt.exists(userId)) {
746 return;
747 }
748
749 enforceGrantRevokeRuntimePermissionPermissions(
750 "updatePermissionFlagsForAllApps");
751 enforceCrossUserPermission(callingUid, userId,
752 true, // requireFullPermission
753 true, // checkShell
754 false, // requirePermissionWhenSameUser
755 "updatePermissionFlagsForAllApps");
756
757 // Only the system can change system fixed flags.
758 final int effectiveFlagMask = (callingUid != Process.SYSTEM_UID)
759 ? flagMask : flagMask & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
760 final int effectiveFlagValues = (callingUid != Process.SYSTEM_UID)
761 ? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
762
763 final boolean[] changed = new boolean[1];
764 mPackageManagerInt.forEachPackage(new Consumer<PackageParser.Package>() {
765 @Override
766 public void accept(Package pkg) {
767 final PackageSetting ps = (PackageSetting) pkg.mExtras;
768 if (ps == null) {
769 return;
770 }
771 final PermissionsState permissionsState = ps.getPermissionsState();
772 changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions(
773 userId, effectiveFlagMask, effectiveFlagValues);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700774 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700775 }
776 });
777
778 if (changed[0]) {
779 mPackageManagerInt.writePermissionSettings(new int[] { userId }, true);
780 }
781 }
782
Todd Kennedyca1ea172019-07-03 15:02:28 -0700783 @Override
784 public int checkPermission(String permName, String pkgName, int userId) {
785 final CheckPermissionDelegate checkPermissionDelegate;
786 synchronized (mLock) {
787 if (mCheckPermissionDelegate == null) {
788 return checkPermissionImpl(permName, pkgName, userId);
789 }
790 checkPermissionDelegate = mCheckPermissionDelegate;
791 }
792 return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
793 PermissionManagerService.this::checkPermissionImpl);
794 }
795
796 private int checkPermissionImpl(String permName, String pkgName, int userId) {
797 return checkPermissionInternal(permName, pkgName, getCallingUid(), userId);
798 }
799
800 private int checkPermissionInternal(String permName, String packageName, int callingUid,
801 int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700802 if (!mUserManagerInt.exists(userId)) {
803 return PackageManager.PERMISSION_DENIED;
804 }
Todd Kennedyca1ea172019-07-03 15:02:28 -0700805 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
Patrick Baumann97b9b532018-04-11 14:51:30 +0000806 if (pkg != null && pkg.mExtras != null) {
807 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700808 return PackageManager.PERMISSION_DENIED;
809 }
Patrick Baumann97b9b532018-04-11 14:51:30 +0000810 final PackageSetting ps = (PackageSetting) pkg.mExtras;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700811 final boolean instantApp = ps.getInstantApp(userId);
812 final PermissionsState permissionsState = ps.getPermissionsState();
813 if (permissionsState.hasPermission(permName, userId)) {
814 if (instantApp) {
815 synchronized (mLock) {
816 BasePermission bp = mSettings.getPermissionLocked(permName);
817 if (bp != null && bp.isInstant()) {
818 return PackageManager.PERMISSION_GRANTED;
819 }
820 }
821 } else {
822 return PackageManager.PERMISSION_GRANTED;
823 }
824 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700825 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700826 return PackageManager.PERMISSION_GRANTED;
827 }
828 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700829 return PackageManager.PERMISSION_DENIED;
830 }
831
Todd Kennedyca1ea172019-07-03 15:02:28 -0700832 @Override
833 public int checkUidPermission(String permName, int uid) {
834 final CheckPermissionDelegate checkPermissionDelegate;
835 synchronized (mLock) {
836 if (mCheckPermissionDelegate == null) {
837 return checkUidPermissionImpl(permName, uid);
838 }
839 checkPermissionDelegate = mCheckPermissionDelegate;
840 }
841 return checkPermissionDelegate.checkUidPermission(permName, uid,
842 PermissionManagerService.this::checkUidPermissionImpl);
843 }
844
845 private int checkUidPermissionImpl(@NonNull String permName, int uid) {
846 final PackageParser.Package pkg = mPackageManagerInt.getPackage(uid);
847 synchronized (mLock) {
848 return checkUidPermissionInternal(permName, pkg, uid, getCallingUid());
849 }
850 }
851
852 /**
853 * Checks whether or not the given package has been granted the specified
854 * permission. If the given package is {@code null}, we instead check the
855 * system permissions for the given UID.
856 *
857 * @see SystemConfig#getSystemPermissions()
858 */
859 private int checkUidPermissionInternal(@NonNull String permName,
860 @Nullable PackageParser.Package pkg, int uid, int callingUid) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700861 final int callingUserId = UserHandle.getUserId(callingUid);
862 final boolean isCallerInstantApp =
863 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
864 final boolean isUidInstantApp =
865 mPackageManagerInt.getInstantAppPackageName(uid) != null;
866 final int userId = UserHandle.getUserId(uid);
867 if (!mUserManagerInt.exists(userId)) {
868 return PackageManager.PERMISSION_DENIED;
869 }
870
Todd Kennedy3c714492017-10-27 09:12:50 -0700871 if (pkg != null) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700872 if (pkg.mSharedUserId != null) {
873 if (isCallerInstantApp) {
874 return PackageManager.PERMISSION_DENIED;
875 }
Todd Kennedy3c714492017-10-27 09:12:50 -0700876 } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
877 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700878 }
879 final PermissionsState permissionsState =
880 ((PackageSetting) pkg.mExtras).getPermissionsState();
881 if (permissionsState.hasPermission(permName, userId)) {
882 if (isUidInstantApp) {
883 if (mSettings.isPermissionInstant(permName)) {
884 return PackageManager.PERMISSION_GRANTED;
885 }
886 } else {
887 return PackageManager.PERMISSION_GRANTED;
888 }
889 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700890 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700891 return PackageManager.PERMISSION_GRANTED;
892 }
893 } else {
894 ArraySet<String> perms = mSystemPermissions.get(uid);
895 if (perms != null) {
896 if (perms.contains(permName)) {
897 return PackageManager.PERMISSION_GRANTED;
898 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700899 if (FULLER_PERMISSION_MAP.containsKey(permName)
900 && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700901 return PackageManager.PERMISSION_GRANTED;
902 }
903 }
904 }
905 return PackageManager.PERMISSION_DENIED;
906 }
907
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700908 @Override
909 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
910 mContext.enforceCallingOrSelfPermission(
911 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
912 "addOnPermissionsChangeListener");
913
914 synchronized (mLock) {
915 mOnPermissionChangeListeners.addListenerLocked(listener);
916 }
917 }
918
919 @Override
920 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
921 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
922 throw new SecurityException("Instant applications don't have access to this method");
923 }
924 synchronized (mLock) {
925 mOnPermissionChangeListeners.removeListenerLocked(listener);
926 }
927 }
928
929 @Override
930 @Nullable public List<String> getWhitelistedRestrictedPermissions(@NonNull String packageName,
931 @PermissionWhitelistFlags int flags, @UserIdInt int userId) {
932 Preconditions.checkNotNull(packageName);
933 Preconditions.checkFlagsArgument(flags,
934 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
935 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
936 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
937 Preconditions.checkArgumentNonNegative(userId, null);
938
939 if (UserHandle.getCallingUserId() != userId) {
940 mContext.enforceCallingOrSelfPermission(
941 android.Manifest.permission.INTERACT_ACROSS_USERS,
942 "getWhitelistedRestrictedPermissions for user " + userId);
943 }
944
945 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
946 if (pkg == null) {
947 return null;
948 }
949
950 final int callingUid = Binder.getCallingUid();
951 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
952 return null;
953 }
954 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
955 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
956 == PackageManager.PERMISSION_GRANTED;
957 final boolean isCallerInstallerOnRecord =
958 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
959
960 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
961 && !isCallerPrivileged) {
962 throw new SecurityException("Querying system whitelist requires "
963 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
964 }
965
966 if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
967 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) {
968 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
969 throw new SecurityException("Querying upgrade or installer whitelist"
970 + " requires being installer on record or "
971 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
972 }
973 }
974
975 final long identity = Binder.clearCallingIdentity();
976 try {
977 final PermissionsState permissionsState =
978 PackageManagerServiceUtils.getPermissionsState(pkg);
979 if (permissionsState == null) {
980 return null;
981 }
982
983 int queryFlags = 0;
984 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
985 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
986 }
987 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
988 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
989 }
990 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
991 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
992 }
993
994 ArrayList<String> whitelistedPermissions = null;
995
996 final int permissionCount = pkg.requestedPermissions.size();
997 for (int i = 0; i < permissionCount; i++) {
998 final String permissionName = pkg.requestedPermissions.get(i);
999 final int currentFlags =
1000 permissionsState.getPermissionFlags(permissionName, userId);
1001 if ((currentFlags & queryFlags) != 0) {
1002 if (whitelistedPermissions == null) {
1003 whitelistedPermissions = new ArrayList<>();
1004 }
1005 whitelistedPermissions.add(permissionName);
1006 }
1007 }
1008
1009 return whitelistedPermissions;
1010 } finally {
1011 Binder.restoreCallingIdentity(identity);
1012 }
1013 }
1014
1015 @Override
1016 public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
1017 @NonNull String permName, @PermissionWhitelistFlags int flags,
1018 @UserIdInt int userId) {
1019 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
1020 Preconditions.checkNotNull(permName);
1021
1022 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1023 return false;
1024 }
1025
1026 List<String> permissions =
1027 getWhitelistedRestrictedPermissions(packageName, flags, userId);
1028 if (permissions == null) {
1029 permissions = new ArrayList<>(1);
1030 }
1031 if (permissions.indexOf(permName) < 0) {
1032 permissions.add(permName);
1033 return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
1034 flags, userId);
1035 }
1036 return false;
1037 }
1038
1039 private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
1040 @NonNull String permName) {
1041 synchronized (mLock) {
1042 final BasePermission bp = mSettings.getPermissionLocked(permName);
1043 if (bp == null) {
1044 Slog.w(TAG, "No such permissions: " + permName);
1045 return false;
1046 }
1047 if (bp.isHardOrSoftRestricted() && bp.isImmutablyRestricted()
1048 && mContext.checkCallingOrSelfPermission(
1049 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1050 != PackageManager.PERMISSION_GRANTED) {
1051 throw new SecurityException("Cannot modify whitelisting of an immutably "
1052 + "restricted permission: " + permName);
1053 }
1054 return true;
1055 }
1056 }
1057
1058 @Override
1059 public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
1060 @NonNull String permName, @PermissionWhitelistFlags int flags,
1061 @UserIdInt int userId) {
1062 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
1063 Preconditions.checkNotNull(permName);
1064
1065 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1066 return false;
1067 }
1068
1069 final List<String> permissions =
1070 getWhitelistedRestrictedPermissions(packageName, flags, userId);
1071 if (permissions != null && permissions.remove(permName)) {
1072 return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
1073 flags, userId);
1074 }
1075 return false;
1076 }
1077
1078 private boolean setWhitelistedRestrictedPermissionsInternal(@NonNull String packageName,
1079 @Nullable List<String> permissions, @PermissionWhitelistFlags int flags,
1080 @UserIdInt int userId) {
1081 Preconditions.checkNotNull(packageName);
1082 Preconditions.checkFlagsArgument(flags,
1083 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1084 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
1085 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
1086 Preconditions.checkArgument(Integer.bitCount(flags) == 1);
1087 Preconditions.checkArgumentNonNegative(userId, null);
1088
1089 if (UserHandle.getCallingUserId() != userId) {
1090 mContext.enforceCallingOrSelfPermission(
1091 Manifest.permission.INTERACT_ACROSS_USERS,
1092 "setWhitelistedRestrictedPermissions for user " + userId);
1093 }
1094
1095 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1096 if (pkg == null) {
1097 return false;
1098 }
1099
1100 final int callingUid = Binder.getCallingUid();
1101 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
1102 return false;
1103 }
1104
1105 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1106 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1107 == PackageManager.PERMISSION_GRANTED;
1108 final boolean isCallerInstallerOnRecord =
1109 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1110
1111 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
1112 && !isCallerPrivileged) {
1113 throw new SecurityException("Modifying system whitelist requires "
1114 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1115 }
1116
1117 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1118 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1119 throw new SecurityException("Modifying upgrade whitelist requires"
1120 + " being installer on record or "
1121 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1122 }
1123 final List<String> whitelistedPermissions =
1124 getWhitelistedRestrictedPermissions(pkg.packageName, flags, userId);
1125 if (permissions == null || permissions.isEmpty()) {
1126 if (whitelistedPermissions == null || whitelistedPermissions.isEmpty()) {
1127 return true;
1128 }
1129 } else {
1130 // Only the system can add and remove while the installer can only remove.
1131 final int permissionCount = permissions.size();
1132 for (int i = 0; i < permissionCount; i++) {
1133 if ((whitelistedPermissions == null
1134 || !whitelistedPermissions.contains(permissions.get(i)))
1135 && !isCallerPrivileged) {
1136 throw new SecurityException("Adding to upgrade whitelist requires"
1137 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1138 }
1139 }
1140 }
1141
1142 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1143 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1144 throw new SecurityException("Modifying installer whitelist requires"
1145 + " being installer on record or "
1146 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1147 }
1148 }
1149 }
1150
1151 final long identity = Binder.clearCallingIdentity();
1152 try {
1153 setWhitelistedRestrictedPermissionsForUser(
1154 pkg, userId, permissions, Process.myUid(), flags, mDefaultPermissionCallback);
1155 } finally {
1156 Binder.restoreCallingIdentity(identity);
1157 }
1158
1159 return true;
1160 }
1161
Todd Kennedyc971a452019-07-08 16:04:52 -07001162 @Override
1163 public void grantRuntimePermission(String packageName, String permName, final int userId) {
1164 final int callingUid = Binder.getCallingUid();
1165 final boolean overridePolicy =
1166 checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
1167 == PackageManager.PERMISSION_GRANTED;
1168
1169 grantRuntimePermissionInternal(permName, packageName, overridePolicy,
1170 callingUid, userId, mDefaultPermissionCallback);
1171 }
1172
1173 // TODO swap permission name and package name
1174 private void grantRuntimePermissionInternal(String permName, String packageName,
1175 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
1176 if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
1177 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
1178 Log.i(TAG, "System is granting "
1179 + permName + " for user " + userId + " on behalf of uid " + callingUid
1180 + " " + mPackageManagerInt.getNameForUid(callingUid),
1181 new RuntimeException());
1182 }
1183 if (!mUserManagerInt.exists(userId)) {
1184 Log.e(TAG, "No such user:" + userId);
1185 return;
1186 }
1187
1188 mContext.enforceCallingOrSelfPermission(
1189 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1190 "grantRuntimePermission");
1191
1192 enforceCrossUserPermission(callingUid, userId,
1193 true, // requireFullPermission
1194 true, // checkShell
1195 false, // requirePermissionWhenSameUser
1196 "grantRuntimePermission");
1197
1198 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1199 if (pkg == null || pkg.mExtras == null) {
1200 throw new IllegalArgumentException("Unknown package: " + packageName);
1201 }
1202 final BasePermission bp;
1203 synchronized (mLock) {
1204 bp = mSettings.getPermissionLocked(permName);
1205 }
1206 if (bp == null) {
1207 throw new IllegalArgumentException("Unknown permission: " + permName);
1208 }
1209 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1210 throw new IllegalArgumentException("Unknown package: " + packageName);
1211 }
1212
1213 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1214
1215 // If a permission review is required for legacy apps we represent
1216 // their permissions as always granted runtime ones since we need
1217 // to keep the review required permission flag per user while an
1218 // install permission's state is shared across all users.
1219 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
1220 && bp.isRuntime()) {
1221 return;
1222 }
1223
1224 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1225
1226 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1227 final PermissionsState permissionsState = ps.getPermissionsState();
1228
1229 final int flags = permissionsState.getPermissionFlags(permName, userId);
1230 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1231 Log.e(TAG, "Cannot grant system fixed permission "
1232 + permName + " for package " + packageName);
1233 return;
1234 }
1235 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1236 Log.e(TAG, "Cannot grant policy fixed permission "
1237 + permName + " for package " + packageName);
1238 return;
1239 }
1240
1241 if (bp.isHardRestricted()
1242 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
1243 Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
1244 + permName + " for package " + packageName);
1245 return;
1246 }
1247
1248 if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
1249 pkg.applicationInfo, UserHandle.of(userId), permName).canBeGranted()) {
1250 Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
1251 + packageName);
1252 return;
1253 }
1254
1255 if (bp.isDevelopment()) {
1256 // Development permissions must be handled specially, since they are not
1257 // normal runtime permissions. For now they apply to all users.
1258 if (permissionsState.grantInstallPermission(bp)
1259 != PERMISSION_OPERATION_FAILURE) {
1260 if (callback != null) {
1261 callback.onInstallPermissionGranted();
1262 }
1263 }
1264 return;
1265 }
1266
1267 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1268 throw new SecurityException("Cannot grant non-ephemeral permission"
1269 + permName + " for package " + packageName);
1270 }
1271
1272 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1273 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1274 return;
1275 }
1276
1277 final int result = permissionsState.grantRuntimePermission(bp, userId);
1278 switch (result) {
1279 case PERMISSION_OPERATION_FAILURE: {
1280 return;
1281 }
1282
1283 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1284 if (callback != null) {
1285 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
1286 }
1287 }
1288 break;
1289 }
1290
1291 if (bp.isRuntime()) {
1292 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
1293 }
1294
1295 if (callback != null) {
1296 callback.onPermissionGranted(uid, userId);
1297 }
1298
1299 if (bp.isRuntime()) {
1300 notifyRuntimePermissionStateChanged(packageName, userId);
1301 }
1302
1303 // Only need to do this if user is initialized. Otherwise it's a new user
1304 // and there are no processes running as the user yet and there's no need
1305 // to make an expensive call to remount processes for the changed permissions.
1306 if (READ_EXTERNAL_STORAGE.equals(permName)
1307 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1308 final long token = Binder.clearCallingIdentity();
1309 try {
1310 if (mUserManagerInt.isUserInitialized(userId)) {
1311 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1312 StorageManagerInternal.class);
1313 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1314 }
1315 } finally {
1316 Binder.restoreCallingIdentity(token);
1317 }
1318 }
1319
1320 }
1321
1322 @Override
1323 public void revokeRuntimePermission(String packageName, String permName, int userId) {
1324 final int callingUid = Binder.getCallingUid();
1325 final boolean overridePolicy =
1326 checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
1327 == PackageManager.PERMISSION_GRANTED;
1328
1329 revokeRuntimePermissionInternal(permName, packageName, overridePolicy, callingUid, userId,
1330 mDefaultPermissionCallback);
1331 }
1332
1333 // TODO swap permission name and package name
1334 private void revokeRuntimePermissionInternal(String permName, String packageName,
1335 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
1336 if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
1337 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
1338 Log.i(TAG, "System is revoking "
1339 + permName + " for user " + userId + " on behalf of uid " + callingUid
1340 + " " + mPackageManagerInt.getNameForUid(callingUid),
1341 new RuntimeException());
1342 }
1343 if (!mUserManagerInt.exists(userId)) {
1344 Log.e(TAG, "No such user:" + userId);
1345 return;
1346 }
1347
1348 mContext.enforceCallingOrSelfPermission(
1349 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1350 "revokeRuntimePermission");
1351
1352 enforceCrossUserPermission(callingUid, userId,
1353 true, // requireFullPermission
1354 true, // checkShell
1355 false, // requirePermissionWhenSameUser
1356 "revokeRuntimePermission");
1357
1358 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1359 if (pkg == null || pkg.mExtras == null) {
1360 throw new IllegalArgumentException("Unknown package: " + packageName);
1361 }
1362 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1363 throw new IllegalArgumentException("Unknown package: " + packageName);
1364 }
1365 final BasePermission bp = mSettings.getPermissionLocked(permName);
1366 if (bp == null) {
1367 throw new IllegalArgumentException("Unknown permission: " + permName);
1368 }
1369
1370 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1371
1372 // If a permission review is required for legacy apps we represent
1373 // their permissions as always granted runtime ones since we need
1374 // to keep the review required permission flag per user while an
1375 // install permission's state is shared across all users.
1376 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
1377 && bp.isRuntime()) {
1378 return;
1379 }
1380
1381 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1382 final PermissionsState permissionsState = ps.getPermissionsState();
1383
1384 final int flags = permissionsState.getPermissionFlags(permName, userId);
1385 // Only the system may revoke SYSTEM_FIXED permissions.
1386 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1387 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1388 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
1389 + permName + " for package " + packageName);
1390 }
1391 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1392 throw new SecurityException("Cannot revoke policy fixed permission "
1393 + permName + " for package " + packageName);
1394 }
1395
1396 if (bp.isDevelopment()) {
1397 // Development permissions must be handled specially, since they are not
1398 // normal runtime permissions. For now they apply to all users.
1399 if (permissionsState.revokeInstallPermission(bp)
1400 != PERMISSION_OPERATION_FAILURE) {
1401 if (callback != null) {
1402 mDefaultPermissionCallback.onInstallPermissionRevoked();
1403 }
1404 }
1405 return;
1406 }
1407
1408 // Permission is already revoked, no need to do anything.
1409 if (!permissionsState.hasRuntimePermission(permName, userId)) {
1410 return;
1411 }
1412
1413 if (permissionsState.revokeRuntimePermission(bp, userId)
1414 == PERMISSION_OPERATION_FAILURE) {
1415 return;
1416 }
1417
1418 if (bp.isRuntime()) {
1419 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
1420 }
1421
1422 if (callback != null) {
1423 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
1424 }
1425
1426 if (bp.isRuntime()) {
1427 notifyRuntimePermissionStateChanged(packageName, userId);
1428 }
1429 }
1430
1431 @Override
1432 public void resetRuntimePermissions() {
1433 mContext.enforceCallingOrSelfPermission(
1434 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1435 "revokeRuntimePermission");
1436
1437 final int callingUid = Binder.getCallingUid();
1438 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
1439 mContext.enforceCallingOrSelfPermission(
1440 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1441 "resetRuntimePermissions");
1442 }
1443
1444 updateAllPermissions(
1445 StorageManager.UUID_PRIVATE_INTERNAL, false, mDefaultPermissionCallback);
1446 for (final int userId : UserManagerService.getInstance().getUserIds()) {
1447 mPackageManagerInt.forEachPackage(
1448 (PackageParser.Package pkg) -> resetRuntimePermissionsInternal(pkg, userId));
1449 }
1450 }
1451
1452 /**
1453 * Reverts user permission state changes (permissions and flags).
1454 *
Hai Zhang4ffebb72019-07-18 14:50:58 -07001455 * @param pkg The package for which to reset.
Todd Kennedyc971a452019-07-08 16:04:52 -07001456 * @param userId The device user for which to do a reset.
1457 */
Patrick Baumann865fd3a2019-07-26 14:53:02 -07001458 @GuardedBy("mLock")
Todd Kennedyc971a452019-07-08 16:04:52 -07001459 private void resetRuntimePermissionsInternal(final PackageParser.Package pkg,
1460 final int userId) {
1461 final String packageName = pkg.packageName;
1462
1463 // These are flags that can change base on user actions.
1464 final int userSettableMask = FLAG_PERMISSION_USER_SET
1465 | FLAG_PERMISSION_USER_FIXED
1466 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
1467 | FLAG_PERMISSION_REVIEW_REQUIRED;
1468
1469 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
1470 | FLAG_PERMISSION_POLICY_FIXED;
1471
1472 // Delay and combine non-async permission callbacks
1473 final int permissionCount = pkg.requestedPermissions.size();
1474 final boolean[] permissionRemoved = new boolean[1];
1475 final ArraySet<Long> revokedPermissions = new ArraySet<>();
1476 final IntArray syncUpdatedUsers = new IntArray(permissionCount);
1477 final IntArray asyncUpdatedUsers = new IntArray(permissionCount);
1478
1479 PermissionCallback delayingPermCallback = new PermissionCallback() {
1480 public void onGidsChanged(int appId, int userId) {
1481 mDefaultPermissionCallback.onGidsChanged(appId, userId);
1482 }
1483
1484 public void onPermissionChanged() {
1485 mDefaultPermissionCallback.onPermissionChanged();
1486 }
1487
1488 public void onPermissionGranted(int uid, int userId) {
1489 mDefaultPermissionCallback.onPermissionGranted(uid, userId);
1490 }
1491
1492 public void onInstallPermissionGranted() {
1493 mDefaultPermissionCallback.onInstallPermissionGranted();
1494 }
1495
1496 public void onPermissionRevoked(int uid, int userId) {
1497 revokedPermissions.add(IntPair.of(uid, userId));
1498
1499 syncUpdatedUsers.add(userId);
1500 }
1501
1502 public void onInstallPermissionRevoked() {
1503 mDefaultPermissionCallback.onInstallPermissionRevoked();
1504 }
1505
1506 public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1507 for (int userId : updatedUserIds) {
1508 if (sync) {
1509 syncUpdatedUsers.add(userId);
1510 asyncUpdatedUsers.remove(userId);
1511 } else {
1512 // Don't override sync=true by sync=false
1513 if (syncUpdatedUsers.indexOf(userId) == -1) {
1514 asyncUpdatedUsers.add(userId);
1515 }
1516 }
1517 }
1518 }
1519
1520 public void onPermissionRemoved() {
1521 permissionRemoved[0] = true;
1522 }
1523
1524 public void onInstallPermissionUpdated() {
1525 mDefaultPermissionCallback.onInstallPermissionUpdated();
1526 }
1527 };
1528
Hai Zhang4ffebb72019-07-18 14:50:58 -07001529 final AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
Todd Kennedyc971a452019-07-08 16:04:52 -07001530 for (int i = 0; i < permissionCount; i++) {
1531 final String permName = pkg.requestedPermissions.get(i);
1532 final BasePermission bp;
1533 synchronized (mLock) {
1534 bp = mSettings.getPermissionLocked(permName);
1535 }
1536 if (bp == null) {
1537 continue;
1538 }
1539
1540 if (bp.isRemoved()) {
1541 continue;
1542 }
1543
1544 // If shared user we just reset the state to which only this app contributed.
1545 final String sharedUserId =
1546 mPackageManagerInt.getSharedUserIdForPackage(pkg.packageName);
1547 final String[] pkgNames =
1548 mPackageManagerInt.getPackagesForSharedUserId(sharedUserId, userId);
1549 if (pkgNames != null && pkgNames.length > 0) {
1550 boolean used = false;
1551 final int packageCount = pkgNames.length;
1552 for (int j = 0; j < packageCount; j++) {
1553 final String sharedPkgName = pkgNames[j];
1554 final PackageParser.Package sharedPkg =
1555 mPackageManagerInt.getPackage(sharedPkgName);
1556 if (sharedPkg != null && !sharedPkg.packageName.equals(packageName)
1557 && sharedPkg.requestedPermissions.contains(permName)) {
1558 used = true;
1559 break;
1560 }
1561 }
1562 if (used) {
1563 continue;
1564 }
1565 }
1566
1567 final int oldFlags =
1568 getPermissionFlagsInternal(permName, packageName, Process.SYSTEM_UID, userId);
1569
1570 // Always clear the user settable flags.
1571 // If permission review is enabled and this is a legacy app, mark the
1572 // permission as requiring a review as this is the initial state.
1573 final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
1574 final int targetSdk = mPackageManagerInt.getTargetSdk(uid);
1575 final int flags = (targetSdk < Build.VERSION_CODES.M && bp.isRuntime())
1576 ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKE_ON_UPGRADE
1577 : 0;
1578
1579 updatePermissionFlagsInternal(
1580 permName, packageName, userSettableMask, flags, Process.SYSTEM_UID, userId,
1581 false, delayingPermCallback);
1582
1583 // Below is only runtime permission handling.
1584 if (!bp.isRuntime()) {
1585 continue;
1586 }
1587
1588 // Never clobber system or policy.
1589 if ((oldFlags & policyOrSystemFlags) != 0) {
1590 continue;
1591 }
1592
1593 // If this permission was granted by default, make sure it is.
1594 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
1595 grantRuntimePermissionInternal(permName, packageName, false,
1596 Process.SYSTEM_UID, userId, delayingPermCallback);
Hai Zhang4ffebb72019-07-18 14:50:58 -07001597 // Allow app op later as we are holding mPackages
1598 // PermissionPolicyService will handle the app op for foreground/background
1599 // permissions.
1600 String appOp = AppOpsManager.permissionToOp(permName);
1601 if (appOp != null) {
1602 mHandler.post(() -> appOpsManager.setUidMode(appOp, uid,
1603 AppOpsManager.MODE_ALLOWED));
1604 }
Todd Kennedyc971a452019-07-08 16:04:52 -07001605 // If permission review is enabled the permissions for a legacy apps
1606 // are represented as constantly granted runtime ones, so don't revoke.
1607 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
1608 // Otherwise, reset the permission.
1609 revokeRuntimePermissionInternal(permName, packageName, false, Process.SYSTEM_UID,
1610 userId, delayingPermCallback);
1611 }
1612 }
1613
1614 // Execute delayed callbacks
1615 if (permissionRemoved[0]) {
1616 mDefaultPermissionCallback.onPermissionRemoved();
1617 }
1618
1619 // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
1620 // kill uid while holding mPackages-lock
1621 if (!revokedPermissions.isEmpty()) {
1622 int numRevokedPermissions = revokedPermissions.size();
1623 for (int i = 0; i < numRevokedPermissions; i++) {
1624 int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
1625 int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));
1626
1627 mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);
1628
1629 // Kill app later as we are holding mPackages
1630 mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
1631 KILL_APP_REASON_PERMISSIONS_REVOKED));
1632 }
1633 }
1634
1635 mPackageManagerInt.writePermissionSettings(syncUpdatedUsers.toArray(), false);
1636 mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true);
1637 }
1638
Todd Kennedy583378d2019-07-12 06:50:30 -07001639 @Override
1640 public String getDefaultBrowser(int userId) {
1641 final int callingUid = Binder.getCallingUid();
1642 if (UserHandle.getUserId(callingUid) != userId) {
1643 mContext.enforceCallingOrSelfPermission(
1644 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
1645 }
1646 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
1647 return null;
1648 }
1649 synchronized (mLock) {
1650 return mDefaultBrowserProvider == null
1651 ? null : mDefaultBrowserProvider.getDefaultBrowser(userId);
1652 }
1653 }
1654
1655 @Override
1656 public boolean setDefaultBrowser(String packageName, int userId) {
1657 mContext.enforceCallingOrSelfPermission(
1658 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
1659 if (UserHandle.getCallingUserId() != userId) {
1660 mContext.enforceCallingOrSelfPermission(
1661 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
1662 }
1663 return setDefaultBrowserInternal(packageName, false, true, userId);
1664 }
1665
1666 private boolean setDefaultBrowserInternal(String packageName, boolean async,
1667 boolean doGrant, int userId) {
1668 synchronized (mLock) {
1669 if (userId == UserHandle.USER_ALL) {
1670 return false;
1671 }
1672 if (mDefaultBrowserProvider == null) {
1673 return false;
1674 }
1675 if (async) {
1676 mDefaultBrowserProvider.setDefaultBrowserAsync(packageName, userId);
1677 } else {
1678 if (!mDefaultBrowserProvider.setDefaultBrowser(packageName, userId)) {
1679 return false;
1680 }
1681 }
1682 if (doGrant && packageName != null) {
1683 mDefaultPermissionGrantPolicy
1684 .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
1685 }
1686 }
1687 return true;
1688 }
1689
1690 @Override
1691 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
1692 final int callingUid = Binder.getCallingUid();
1693 PackageManagerServiceUtils
1694 .enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
1695 synchronized (mLock) {
1696 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1697 .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
1698 }
1699 }
1700
1701 @Override
1702 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
1703 final int callingUid = Binder.getCallingUid();
1704 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1705 "grantDefaultPermissionsToEnabledImsServices", callingUid);
1706 synchronized (mLock) {
1707 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1708 .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
1709 }
1710 }
1711
1712 @Override
1713 public void grantDefaultPermissionsToEnabledTelephonyDataServices(
1714 String[] packageNames, int userId) {
1715 final int callingUid = Binder.getCallingUid();
1716 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1717 "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
1718 synchronized (mLock) {
1719 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1720 .grantDefaultPermissionsToEnabledTelephonyDataServices(
1721 packageNames, userId));
1722 }
1723 }
1724
1725 @Override
1726 public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
1727 String[] packageNames, int userId) {
1728 final int callingUid = Binder.getCallingUid();
1729 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1730 "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
1731 synchronized (mLock) {
1732 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1733 .revokeDefaultPermissionsFromDisabledTelephonyDataServices(
1734 packageNames, userId));
1735 }
1736 }
1737
1738 @Override
1739 public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
1740 final int callingUid = Binder.getCallingUid();
1741 PackageManagerServiceUtils
1742 .enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
1743 synchronized (mLock) {
1744 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1745 .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
1746 }
1747 }
1748
1749 @Override
1750 public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
1751 final int callingUid = Binder.getCallingUid();
1752 PackageManagerServiceUtils
1753 .enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
1754 synchronized (mLock) {
1755 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1756 .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
1757 }
1758 }
1759
Todd Kennedyc5b0e862019-07-16 09:47:58 -07001760 @Override
1761 public void setPermissionEnforced(String permName, boolean enforced) {
1762 // TODO: Now that we no longer change GID for storage, this should to away.
1763 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1764 "setPermissionEnforced");
1765 if (READ_EXTERNAL_STORAGE.equals(permName)) {
1766 mPackageManagerInt.setReadExternalStorageEnforced(enforced);
1767 // kill any non-foreground processes so we restart them and
1768 // grant/revoke the GID.
1769 final IActivityManager am = ActivityManager.getService();
1770 if (am != null) {
1771 final long token = Binder.clearCallingIdentity();
1772 try {
1773 am.killProcessesBelowForeground("setPermissionEnforcement");
1774 } catch (RemoteException e) {
1775 } finally {
1776 Binder.restoreCallingIdentity(token);
1777 }
1778 }
1779 } else {
1780 throw new IllegalArgumentException("No selective enforcement for " + permName);
1781 }
1782 }
1783
1784 /** @deprecated */
1785 @Override
1786 @Deprecated
1787 public boolean isPermissionEnforced(String permName) {
1788 // allow instant applications
1789 return true;
1790 }
1791
1792 @Override
1793 public boolean shouldShowRequestPermissionRationale(String permName,
1794 String packageName, int userId) {
1795 final int callingUid = Binder.getCallingUid();
1796 if (UserHandle.getCallingUserId() != userId) {
1797 mContext.enforceCallingPermission(
1798 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1799 "canShowRequestPermissionRationale for user " + userId);
1800 }
1801
1802 final int uid =
1803 mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
1804 if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) {
1805 return false;
1806 }
1807
1808 if (checkPermission(permName, packageName, userId)
1809 == PackageManager.PERMISSION_GRANTED) {
1810 return false;
1811 }
1812
1813 final int flags;
1814
1815 final long identity = Binder.clearCallingIdentity();
1816 try {
1817 flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
1818 } finally {
1819 Binder.restoreCallingIdentity(identity);
1820 }
1821
1822 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1823 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
1824 | PackageManager.FLAG_PERMISSION_USER_FIXED;
1825
1826 if ((flags & fixedFlags) != 0) {
1827 return false;
1828 }
1829
1830 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
1831 }
1832
1833 @Override
1834 public boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId) {
1835 if (UserHandle.getCallingUserId() != userId) {
1836 mContext.enforceCallingPermission(
1837 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1838 "isPermissionRevokedByPolicy for user " + userId);
1839 }
1840
1841 if (checkPermission(permName, packageName, userId) == PackageManager.PERMISSION_GRANTED) {
1842 return false;
1843 }
1844
1845 final int callingUid = Binder.getCallingUid();
1846 if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) {
1847 return false;
1848 }
1849
1850 final long identity = Binder.clearCallingIdentity();
1851 try {
1852 final int flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
1853 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
1854 } finally {
1855 Binder.restoreCallingIdentity(identity);
1856 }
1857 }
1858
Hongwei Wangf391b552018-04-06 13:52:46 -07001859 /**
Philip P. Moltmann48456672019-01-20 13:14:03 -08001860 * Get the state of the runtime permissions as xml file.
1861 *
1862 * <p>Can not be called on main thread.
1863 *
1864 * @param user The user the data should be extracted for
1865 *
1866 * @return The state as a xml file
1867 */
1868 private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
1869 CompletableFuture<byte[]> backup = new CompletableFuture<>();
1870 mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
1871 backup::complete);
1872
1873 try {
1874 return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
1875 } catch (InterruptedException | ExecutionException | TimeoutException e) {
1876 Slog.e(TAG, "Cannot create permission backup for " + user, e);
1877 return null;
1878 }
1879 }
1880
1881 /**
1882 * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
1883 *
1884 * <p>If not all state can be restored, the un-appliable state will be delayed and can be
1885 * applied via {@link #restoreDelayedRuntimePermissions}.
1886 *
1887 * @param backup The state as an xml file
1888 * @param user The user the data should be restored for
1889 */
1890 private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
1891 synchronized (mLock) {
1892 mHasNoDelayedPermBackup.delete(user.getIdentifier());
1893 mPermissionControllerManager.restoreRuntimePermissionBackup(backup, user);
1894 }
1895 }
1896
1897 /**
1898 * Try to apply permission backup that was previously not applied.
1899 *
1900 * <p>Can not be called on main thread.
1901 *
1902 * @param packageName The package that is newly installed
1903 * @param user The user the package is installed for
1904 *
1905 * @see #restoreRuntimePermissions
1906 */
1907 private void restoreDelayedRuntimePermissions(@NonNull String packageName,
1908 @NonNull UserHandle user) {
1909 synchronized (mLock) {
1910 if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
1911 return;
1912 }
1913
1914 mPermissionControllerManager.restoreDelayedRuntimePermissionBackup(packageName, user,
1915 mContext.getMainExecutor(), (hasMoreBackup) -> {
1916 if (hasMoreBackup) {
1917 return;
1918 }
1919
1920 synchronized (mLock) {
1921 mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
1922 }
1923 });
1924 }
1925 }
1926
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001927 private void addOnRuntimePermissionStateChangedListener(@NonNull
1928 OnRuntimePermissionStateChangedListener listener) {
1929 synchronized (mLock) {
1930 mRuntimePermissionStateChangedListeners.add(listener);
1931 }
1932 }
1933
1934 private void removeOnRuntimePermissionStateChangedListener(@NonNull
1935 OnRuntimePermissionStateChangedListener listener) {
1936 synchronized (mLock) {
1937 mRuntimePermissionStateChangedListeners.remove(listener);
1938 }
1939 }
1940
1941 private void notifyRuntimePermissionStateChanged(@NonNull String packageName,
1942 @UserIdInt int userId) {
1943 FgThread.getHandler().sendMessage(PooledLambda.obtainMessage
1944 (PermissionManagerService::doNotifyRuntimePermissionStateChanged,
1945 PermissionManagerService.this, packageName, userId));
1946 }
1947
1948 private void doNotifyRuntimePermissionStateChanged(@NonNull String packageName,
1949 @UserIdInt int userId) {
1950 final ArrayList<OnRuntimePermissionStateChangedListener> listeners;
1951 synchronized (mLock) {
1952 if (mRuntimePermissionStateChangedListeners.isEmpty()) {
1953 return;
1954 }
1955 listeners = new ArrayList<>(mRuntimePermissionStateChangedListeners);
1956 }
1957 final int listenerCount = listeners.size();
1958 for (int i = 0; i < listenerCount; i++) {
1959 listeners.get(i).onRuntimePermissionStateChanged(packageName, userId);
1960 }
1961 }
1962
Philip P. Moltmann48456672019-01-20 13:14:03 -08001963 /**
Hongwei Wangf391b552018-04-06 13:52:46 -07001964 * Returns {@code true} if the permission can be implied from another granted permission.
1965 * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
1966 * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
1967 * it access to any implied permissions.
1968 */
1969 private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
1970 String permName, int userId) {
1971 return FULLER_PERMISSION_MAP.containsKey(permName)
1972 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
1973 }
1974
Todd Kennedy0eb97382017-10-03 16:57:22 -07001975 private int adjustPermissionProtectionFlagsLocked(
1976 int protectionLevel, String packageName, int uid) {
1977 // Signature permission flags area always reported
1978 final int protectionLevelMasked = protectionLevel
1979 & (PermissionInfo.PROTECTION_NORMAL
1980 | PermissionInfo.PROTECTION_DANGEROUS
1981 | PermissionInfo.PROTECTION_SIGNATURE);
1982 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
1983 return protectionLevel;
1984 }
1985 // System sees all flags.
1986 final int appId = UserHandle.getAppId(uid);
1987 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
1988 || appId == Process.SHELL_UID) {
1989 return protectionLevel;
1990 }
1991 // Normalize package name to handle renamed packages and static libs
1992 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1993 if (pkg == null) {
1994 return protectionLevel;
1995 }
1996 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
1997 return protectionLevelMasked;
1998 }
1999 // Apps that target O see flags for all protection levels.
2000 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2001 if (ps == null) {
2002 return protectionLevel;
2003 }
2004 if (ps.getAppId() != appId) {
2005 return protectionLevel;
2006 }
2007 return protectionLevel;
2008 }
2009
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002010 /**
2011 * We might auto-grant permissions if any permission of the group is already granted. Hence if
2012 * the group of a granted permission changes we need to revoke it to avoid having permissions of
2013 * the new group auto-granted.
2014 *
2015 * @param newPackage The new package that was installed
2016 * @param oldPackage The old package that was updated
2017 * @param allPackageNames All package names
2018 * @param permissionCallback Callback for permission changed
2019 */
2020 private void revokeRuntimePermissionsIfGroupChanged(
2021 @NonNull PackageParser.Package newPackage,
2022 @NonNull PackageParser.Package oldPackage,
2023 @NonNull ArrayList<String> allPackageNames,
2024 @NonNull PermissionCallback permissionCallback) {
2025 final int numOldPackagePermissions = oldPackage.permissions.size();
2026 final ArrayMap<String, String> oldPermissionNameToGroupName
2027 = new ArrayMap<>(numOldPackagePermissions);
2028
2029 for (int i = 0; i < numOldPackagePermissions; i++) {
2030 final PackageParser.Permission permission = oldPackage.permissions.get(i);
2031
2032 if (permission.group != null) {
2033 oldPermissionNameToGroupName.put(permission.info.name,
2034 permission.group.info.name);
2035 }
2036 }
2037
Todd Kennedyc971a452019-07-08 16:04:52 -07002038 final int callingUid = Binder.getCallingUid();
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002039 final int numNewPackagePermissions = newPackage.permissions.size();
2040 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
2041 newPermissionNum++) {
2042 final PackageParser.Permission newPermission =
2043 newPackage.permissions.get(newPermissionNum);
2044 final int newProtection = newPermission.info.getProtection();
2045
2046 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
2047 final String permissionName = newPermission.info.name;
2048 final String newPermissionGroupName =
2049 newPermission.group == null ? null : newPermission.group.info.name;
2050 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
2051 permissionName);
2052
2053 if (newPermissionGroupName != null
2054 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
2055 final int[] userIds = mUserManagerInt.getUserIds();
2056 final int numUserIds = userIds.length;
2057 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
2058 final int userId = userIds[userIdNum];
2059
2060 final int numPackages = allPackageNames.size();
2061 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
2062 final String packageName = allPackageNames.get(packageNum);
Todd Kennedyca1ea172019-07-03 15:02:28 -07002063 final int permissionState = checkPermissionInternal(
2064 permissionName, packageName, UserHandle.USER_SYSTEM, userId);
2065 if (permissionState == PackageManager.PERMISSION_GRANTED) {
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002066 EventLog.writeEvent(0x534e4554, "72710897",
2067 newPackage.applicationInfo.uid,
Koji Fukuiacae3ef2018-05-09 11:38:01 +09002068 "Revoking permission " + permissionName +
2069 " from package " + packageName +
2070 " as the group changed from " + oldPermissionGroupName +
2071 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002072
2073 try {
Todd Kennedyc971a452019-07-08 16:04:52 -07002074 revokeRuntimePermissionInternal(permissionName, packageName,
2075 false, callingUid, userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002076 } catch (IllegalArgumentException e) {
2077 Slog.e(TAG, "Could not revoke " + permissionName + " from "
2078 + packageName, e);
2079 }
2080 }
2081 }
2082 }
2083 }
2084 }
2085 }
2086 }
2087
Todd Kennedyc8423932017-10-05 08:58:36 -07002088 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
2089 final int N = pkg.permissions.size();
2090 for (int i=0; i<N; i++) {
2091 PackageParser.Permission p = pkg.permissions.get(i);
2092
2093 // Assume by default that we did not install this permission into the system.
2094 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
2095
Todd Kennedyc8423932017-10-05 08:58:36 -07002096 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002097 // Now that permission groups have a special meaning, we ignore permission
2098 // groups for legacy apps to prevent unexpected behavior. In particular,
2099 // permissions for one app being granted to someone just because they happen
2100 // to be in a group defined by another app (before this had no implications).
2101 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
2102 p.group = mSettings.mPermissionGroups.get(p.info.group);
2103 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002104 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -07002105 && p.info.group != null && p.group == null) {
2106 Slog.i(TAG, "Permission " + p.info.name + " from package "
2107 + p.info.packageName + " in an unknown group " + p.info.group);
2108 }
2109 }
2110
Todd Kennedyc8423932017-10-05 08:58:36 -07002111 if (p.tree) {
2112 final BasePermission bp = BasePermission.createOrUpdate(
2113 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
2114 mSettings.getAllPermissionTreesLocked(), chatty);
2115 mSettings.putPermissionTreeLocked(p.info.name, bp);
2116 } else {
2117 final BasePermission bp = BasePermission.createOrUpdate(
2118 mSettings.getPermissionLocked(p.info.name),
2119 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
2120 mSettings.putPermissionLocked(p.info.name, bp);
2121 }
2122 }
2123 }
2124 }
2125
Todd Kennedy460f28c2017-10-06 13:46:22 -07002126 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
2127 final int N = pkg.permissionGroups.size();
2128 StringBuilder r = null;
2129 for (int i=0; i<N; i++) {
2130 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
2131 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
2132 final String curPackageName = (cur == null) ? null : cur.info.packageName;
2133 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
2134 if (cur == null || isPackageUpdate) {
2135 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002136 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002137 if (r == null) {
2138 r = new StringBuilder(256);
2139 } else {
2140 r.append(' ');
2141 }
2142 if (isPackageUpdate) {
2143 r.append("UPD:");
2144 }
2145 r.append(pg.info.name);
2146 }
2147 } else {
2148 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
2149 + pg.info.packageName + " ignored: original from "
2150 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002151 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002152 if (r == null) {
2153 r = new StringBuilder(256);
2154 } else {
2155 r.append(' ');
2156 }
2157 r.append("DUP:");
2158 r.append(pg.info.name);
2159 }
2160 }
2161 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002162 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002163 Log.d(TAG, " Permission Groups: " + r);
2164 }
2165
2166 }
2167
Hongming Jinae750fb2018-09-27 23:00:20 +00002168 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002169 synchronized (mLock) {
2170 int N = pkg.permissions.size();
2171 StringBuilder r = null;
2172 for (int i=0; i<N; i++) {
2173 PackageParser.Permission p = pkg.permissions.get(i);
2174 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
2175 if (bp == null) {
2176 bp = mSettings.mPermissionTrees.get(p.info.name);
2177 }
2178 if (bp != null && bp.isPermission(p)) {
2179 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002180 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002181 if (r == null) {
2182 r = new StringBuilder(256);
2183 } else {
2184 r.append(' ');
2185 }
2186 r.append(p.info.name);
2187 }
2188 }
2189 if (p.isAppOp()) {
2190 ArraySet<String> appOpPkgs =
2191 mSettings.mAppOpPermissionPackages.get(p.info.name);
2192 if (appOpPkgs != null) {
2193 appOpPkgs.remove(pkg.packageName);
2194 }
2195 }
2196 }
2197 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002198 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -07002199 }
2200
2201 N = pkg.requestedPermissions.size();
2202 r = null;
2203 for (int i=0; i<N; i++) {
2204 String perm = pkg.requestedPermissions.get(i);
2205 if (mSettings.isPermissionAppOp(perm)) {
2206 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
2207 if (appOpPkgs != null) {
2208 appOpPkgs.remove(pkg.packageName);
2209 if (appOpPkgs.isEmpty()) {
2210 mSettings.mAppOpPermissionPackages.remove(perm);
2211 }
2212 }
2213 }
2214 }
2215 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002216 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -07002217 }
2218 }
2219 }
2220
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002221 /**
2222 * Restore the permission state for a package.
2223 *
2224 * <ul>
2225 * <li>During boot the state gets restored from the disk</li>
2226 * <li>During app update the state gets restored from the last version of the app</li>
2227 * </ul>
2228 *
2229 * <p>This restores the permission state for all users.
2230 *
2231 * @param pkg the package the permissions belong to
2232 * @param replace if the package is getting replaced (this might change the requested
2233 * permissions of this package)
2234 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
2235 * @param callback Result call back
2236 */
2237 private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
2238 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002239 // IMPORTANT: There are two types of permissions: install and runtime.
2240 // Install time permissions are granted when the app is installed to
2241 // all device users and users added in the future. Runtime permissions
2242 // are granted at runtime explicitly to specific users. Normal and signature
2243 // protected permissions are install time permissions. Dangerous permissions
2244 // are install permissions if the app's target SDK is Lollipop MR1 or older,
2245 // otherwise they are runtime permissions. This function does not manage
2246 // runtime permissions except for the case an app targeting Lollipop MR1
2247 // being upgraded to target a newer SDK, in which case dangerous permissions
2248 // are transformed from install time to runtime ones.
2249
2250 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2251 if (ps == null) {
2252 return;
2253 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002254
2255 final PermissionsState permissionsState = ps.getPermissionsState();
2256 PermissionsState origPermissions = permissionsState;
2257
2258 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2259
2260 boolean runtimePermissionsRevoked = false;
2261 int[] updatedUserIds = EMPTY_INT_ARRAY;
2262
2263 boolean changedInstallPermission = false;
2264
2265 if (replace) {
2266 ps.setInstallPermissionsFixed(false);
2267 if (!ps.isSharedUser()) {
2268 origPermissions = new PermissionsState(permissionsState);
2269 permissionsState.reset();
2270 } else {
2271 // We need to know only about runtime permission changes since the
2272 // calling code always writes the install permissions state but
2273 // the runtime ones are written only if changed. The only cases of
2274 // changed runtime permissions here are promotion of an install to
2275 // runtime and revocation of a runtime from a shared user.
2276 synchronized (mLock) {
2277 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
2278 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
2279 if (!ArrayUtils.isEmpty(updatedUserIds)) {
2280 runtimePermissionsRevoked = true;
2281 }
2282 }
2283 }
2284 }
2285
2286 permissionsState.setGlobalGids(mGlobalGids);
2287
2288 synchronized (mLock) {
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002289 ArraySet<String> newImplicitPermissions = new ArraySet<>();
2290
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002291 final int N = pkg.requestedPermissions.size();
2292 for (int i = 0; i < N; i++) {
2293 final String permName = pkg.requestedPermissions.get(i);
2294 final BasePermission bp = mSettings.getPermissionLocked(permName);
2295 final boolean appSupportsRuntimePermissions =
2296 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
Zimuzoe6411402019-05-13 16:32:57 +01002297 String upgradedActivityRecognitionPermission = null;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002298
2299 if (DEBUG_INSTALL) {
2300 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
2301 }
2302
2303 if (bp == null || bp.getSourcePackageSetting() == null) {
2304 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
2305 if (DEBUG_PERMISSIONS) {
2306 Slog.i(TAG, "Unknown permission " + permName
2307 + " in package " + pkg.packageName);
2308 }
2309 }
2310 continue;
2311 }
2312
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002313 // Cache newImplicitPermissions before modifing permissionsState as for the shared
2314 // uids the original and new state are the same object
2315 if (!origPermissions.hasRequestedPermission(permName)
Zimuzoe6411402019-05-13 16:32:57 +01002316 && (pkg.implicitPermissions.contains(permName)
2317 || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
2318 if (pkg.implicitPermissions.contains(permName)) {
2319 // If permName is an implicit permission, try to auto-grant
2320 newImplicitPermissions.add(permName);
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002321
Zimuzoe6411402019-05-13 16:32:57 +01002322 if (DEBUG_PERMISSIONS) {
2323 Slog.i(TAG, permName + " is newly added for " + pkg.packageName);
2324 }
2325 } else {
2326 // Special case for Activity Recognition permission. Even if AR permission
2327 // is not an implicit permission we want to add it to the list (try to
2328 // auto-grant it) if the app was installed on a device before AR permission
2329 // was split, regardless of if the app now requests the new AR permission
2330 // or has updated its target SDK and AR is no longer implicit to it.
2331 // This is a compatibility workaround for apps when AR permission was
2332 // split in Q.
2333 int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
2334 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
2335 PermissionManager.SplitPermissionInfo sp =
2336 PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
2337 String splitPermName = sp.getSplitPermission();
2338 if (sp.getNewPermissions().contains(permName)
2339 && origPermissions.hasInstallPermission(splitPermName)) {
2340 upgradedActivityRecognitionPermission = splitPermName;
2341 newImplicitPermissions.add(permName);
2342
2343 if (DEBUG_PERMISSIONS) {
2344 Slog.i(TAG, permName + " is newly added for "
2345 + pkg.packageName);
2346 }
2347 break;
2348 }
2349 }
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002350 }
2351 }
2352
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002353 // Limit ephemeral apps to ephemeral allowed permissions.
2354 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
2355 if (DEBUG_PERMISSIONS) {
2356 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
2357 + " for package " + pkg.packageName);
2358 }
2359 continue;
2360 }
2361
2362 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
2363 if (DEBUG_PERMISSIONS) {
2364 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
2365 + " for package " + pkg.packageName);
2366 }
2367 continue;
2368 }
2369
2370 final String perm = bp.getName();
2371 boolean allowedSig = false;
2372 int grant = GRANT_DENIED;
2373
2374 // Keep track of app op permissions.
2375 if (bp.isAppOp()) {
2376 mSettings.addAppOpPackage(perm, pkg.packageName);
2377 }
2378
2379 if (bp.isNormal()) {
2380 // For all apps normal permissions are install time ones.
2381 grant = GRANT_INSTALL;
2382 } else if (bp.isRuntime()) {
Zimuzoe6411402019-05-13 16:32:57 +01002383 if (origPermissions.hasInstallPermission(bp.getName())
2384 || upgradedActivityRecognitionPermission != null) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002385 // Before Q we represented some runtime permissions as install permissions,
2386 // in Q we cannot do this anymore. Hence upgrade them all.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002387 grant = GRANT_UPGRADE;
2388 } else {
2389 // For modern apps keep runtime permissions unchanged.
2390 grant = GRANT_RUNTIME;
2391 }
2392 } else if (bp.isSignature()) {
2393 // For all apps signature permissions are install time ones.
2394 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
2395 if (allowedSig) {
2396 grant = GRANT_INSTALL;
2397 }
2398 }
2399
2400 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002401 Slog.i(TAG, "Considering granting permission " + perm + " to package "
2402 + pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002403 }
2404
2405 if (grant != GRANT_DENIED) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002406 if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002407 // If this is an existing, non-system package, then
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002408 // we can't add any new permissions to it. Runtime
2409 // permissions can be added any time - they ad dynamic.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002410 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
2411 // Except... if this is a permission that was added
2412 // to the platform (note: need to only do this when
2413 // updating the platform).
2414 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
2415 grant = GRANT_DENIED;
2416 }
2417 }
2418 }
2419
2420 switch (grant) {
2421 case GRANT_INSTALL: {
2422 // Revoke this as runtime permission to handle the case of
2423 // a runtime permission being downgraded to an install one.
2424 // Also in permission review mode we keep dangerous permissions
2425 // for legacy apps
2426 for (int userId : UserManagerService.getInstance().getUserIds()) {
2427 if (origPermissions.getRuntimePermissionState(
2428 perm, userId) != null) {
2429 // Revoke the runtime permission and clear the flags.
2430 origPermissions.revokeRuntimePermission(bp, userId);
2431 origPermissions.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002432 PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002433 // If we revoked a permission permission, we have to write.
2434 updatedUserIds = ArrayUtils.appendInt(
2435 updatedUserIds, userId);
2436 }
2437 }
2438 // Grant an install permission.
2439 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002440 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002441 changedInstallPermission = true;
2442 }
2443 } break;
2444
2445 case GRANT_RUNTIME: {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002446 boolean hardRestricted = bp.isHardRestricted();
2447 boolean softRestricted = bp.isSoftRestricted();
2448
Philip P. Moltmann48456672019-01-20 13:14:03 -08002449 for (int userId : currentUserIds) {
Svet Ganov3c499ea2019-07-26 17:45:56 -07002450 // If permission policy is not ready we don't deal with restricted
2451 // permissions as the policy may whitelist some permissions. Once
2452 // the policy is initialized we would re-evaluate permissions.
2453 final boolean permissionPolicyInitialized =
2454 mPermissionPolicyInternal != null
2455 && mPermissionPolicyInternal.isInitialized(userId);
2456
Philip P. Moltmann48456672019-01-20 13:14:03 -08002457 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002458 .getRuntimePermissionState(perm, userId);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002459 int flags = permState != null ? permState.getFlags() : 0;
2460
2461 boolean wasChanged = false;
2462
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002463 boolean restrictionExempt =
2464 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002465 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2466 boolean restrictionApplied = (origPermissions.getPermissionFlags(
2467 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2468
Philip P. Moltmann48456672019-01-20 13:14:03 -08002469 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002470 // If hard restricted we don't allow holding it
Svet Ganov3c499ea2019-07-26 17:45:56 -07002471 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002472 if (!restrictionExempt) {
2473 if (permState != null && permState.isGranted()
2474 && permissionsState.revokeRuntimePermission(
2475 bp, userId) != PERMISSION_OPERATION_FAILURE) {
2476 wasChanged = true;
2477 }
2478 if (!restrictionApplied) {
2479 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2480 wasChanged = true;
2481 }
2482 }
2483 // If soft restricted we allow holding in a restricted form
Svet Ganov3c499ea2019-07-26 17:45:56 -07002484 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002485 // Regardless if granted set the restriction flag as it
2486 // may affect app treatment based on this permission.
2487 if (!restrictionExempt && !restrictionApplied) {
2488 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2489 wasChanged = true;
2490 }
2491 }
2492
Philip P. Moltmann48456672019-01-20 13:14:03 -08002493 // Remove review flag as it is not necessary anymore
2494 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2495 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2496 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002497 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002498
2499 if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
2500 flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
2501 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002502 // Hard restricted permissions cannot be held.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002503 } else if (!permissionPolicyInitialized
2504 || (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002505 if (permState != null && permState.isGranted()) {
2506 if (permissionsState.grantRuntimePermission(bp, userId)
2507 == PERMISSION_OPERATION_FAILURE) {
2508 wasChanged = true;
2509 }
2510 }
2511 }
2512 } else {
2513 if (permState == null) {
2514 // New permission
2515 if (PLATFORM_PACKAGE_NAME.equals(
2516 bp.getSourcePackageName())) {
2517 if (!bp.isRemoved()) {
2518 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
2519 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
2520 wasChanged = true;
2521 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002522 }
2523 }
2524
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002525 if (!permissionsState.hasRuntimePermission(bp.name, userId)
2526 && permissionsState.grantRuntimePermission(bp, userId)
2527 != PERMISSION_OPERATION_FAILURE) {
2528 wasChanged = true;
2529 }
2530
2531 // If legacy app always grant the permission but if restricted
2532 // and not exempt take a note a restriction should be applied.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002533 if (permissionPolicyInitialized
2534 && (hardRestricted || softRestricted)
2535 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002536 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2537 wasChanged = true;
2538 }
2539 }
2540
2541 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002542 if (permissionPolicyInitialized) {
2543 if (!(hardRestricted || softRestricted) || restrictionExempt) {
2544 if (restrictionApplied) {
2545 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2546 // Dropping restriction on a legacy app implies a review
2547 if (!appSupportsRuntimePermissions) {
2548 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2549 }
2550 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002551 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002552 }
2553 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002554
2555 if (wasChanged) {
2556 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2557 }
2558
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08002559 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002560 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002561 }
2562 } break;
2563
2564 case GRANT_UPGRADE: {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002565 // Upgrade from Pre-Q to Q permission model. Make all permissions
2566 // runtime
2567 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002568 .getInstallPermissionState(perm);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002569 int flags = (permState != null) ? permState.getFlags() : 0;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002570
Zimuzoe6411402019-05-13 16:32:57 +01002571 BasePermission bpToRevoke =
2572 upgradedActivityRecognitionPermission == null
2573 ? bp : mSettings.getPermissionLocked(
2574 upgradedActivityRecognitionPermission);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002575 // Remove install permission
Zimuzoe6411402019-05-13 16:32:57 +01002576 if (origPermissions.revokeInstallPermission(bpToRevoke)
Philip P. Moltmann48456672019-01-20 13:14:03 -08002577 != PERMISSION_OPERATION_FAILURE) {
Zimuzoe6411402019-05-13 16:32:57 +01002578 origPermissions.updatePermissionFlags(bpToRevoke,
2579 UserHandle.USER_ALL,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002580 (MASK_PERMISSION_FLAGS_ALL
2581 & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002582 changedInstallPermission = true;
2583 }
2584
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002585 boolean hardRestricted = bp.isHardRestricted();
2586 boolean softRestricted = bp.isSoftRestricted();
2587
Philip P. Moltmann48456672019-01-20 13:14:03 -08002588 for (int userId : currentUserIds) {
Svet Ganov3c499ea2019-07-26 17:45:56 -07002589 // If permission policy is not ready we don't deal with restricted
2590 // permissions as the policy may whitelist some permissions. Once
2591 // the policy is initialized we would re-evaluate permissions.
2592 final boolean permissionPolicyInitialized =
2593 mPermissionPolicyInternal != null
2594 && mPermissionPolicyInternal.isInitialized(userId);
2595
Philip P. Moltmann48456672019-01-20 13:14:03 -08002596 boolean wasChanged = false;
2597
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002598 boolean restrictionExempt =
2599 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002600 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2601 boolean restrictionApplied = (origPermissions.getPermissionFlags(
2602 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2603
Philip P. Moltmann48456672019-01-20 13:14:03 -08002604 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002605 // If hard restricted we don't allow holding it
Svet Ganov3c499ea2019-07-26 17:45:56 -07002606 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002607 if (!restrictionExempt) {
2608 if (permState != null && permState.isGranted()
2609 && permissionsState.revokeRuntimePermission(
2610 bp, userId) != PERMISSION_OPERATION_FAILURE) {
2611 wasChanged = true;
2612 }
2613 if (!restrictionApplied) {
2614 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2615 wasChanged = true;
2616 }
2617 }
2618 // If soft restricted we allow holding in a restricted form
Svet Ganov3c499ea2019-07-26 17:45:56 -07002619 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002620 // Regardless if granted set the restriction flag as it
2621 // may affect app treatment based on this permission.
2622 if (!restrictionExempt && !restrictionApplied) {
2623 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2624 wasChanged = true;
2625 }
2626 }
2627
Philip P. Moltmann48456672019-01-20 13:14:03 -08002628 // Remove review flag as it is not necessary anymore
2629 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2630 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2631 wasChanged = true;
2632 }
2633
2634 if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
2635 flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
2636 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002637 // Hard restricted permissions cannot be held.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002638 } else if (!permissionPolicyInitialized ||
2639 (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002640 if (permissionsState.grantRuntimePermission(bp, userId) !=
2641 PERMISSION_OPERATION_FAILURE) {
2642 wasChanged = true;
2643 }
2644 }
2645 } else {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002646 if (!permissionsState.hasRuntimePermission(bp.name, userId)
2647 && permissionsState.grantRuntimePermission(bp,
2648 userId) != PERMISSION_OPERATION_FAILURE) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002649 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2650 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002651 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002652
2653 // If legacy app always grant the permission but if restricted
2654 // and not exempt take a note a restriction should be applied.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002655 if (permissionPolicyInitialized
2656 && (hardRestricted || softRestricted)
2657 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002658 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2659 wasChanged = true;
2660 }
2661 }
2662
2663 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002664 if (permissionPolicyInitialized) {
2665 if (!(hardRestricted || softRestricted) || restrictionExempt) {
2666 if (restrictionApplied) {
2667 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2668 // Dropping restriction on a legacy app implies a review
2669 if (!appSupportsRuntimePermissions) {
2670 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2671 }
2672 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002673 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002674 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002675 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002676
2677 if (wasChanged) {
2678 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2679 }
2680
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08002681 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002682 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002683 }
2684 } break;
2685
2686 default: {
2687 if (packageOfInterest == null
2688 || packageOfInterest.equals(pkg.packageName)) {
2689 if (DEBUG_PERMISSIONS) {
2690 Slog.i(TAG, "Not granting permission " + perm
2691 + " to package " + pkg.packageName
2692 + " because it was previously installed without");
2693 }
2694 }
2695 } break;
2696 }
2697 } else {
2698 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002699 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002700 // Also drop the permission flags.
2701 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002702 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002703 changedInstallPermission = true;
Nate Myrened67bdd2019-05-07 10:32:22 -07002704 if (DEBUG_PERMISSIONS) {
2705 Slog.i(TAG, "Un-granting permission " + perm
2706 + " from package " + pkg.packageName
2707 + " (protectionLevel=" + bp.getProtectionLevel()
2708 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
2709 + ")");
2710 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002711 } else if (bp.isAppOp()) {
2712 // Don't print warning for app op permissions, since it is fine for them
2713 // not to be granted, there is a UI for the user to decide.
2714 if (DEBUG_PERMISSIONS
2715 && (packageOfInterest == null
2716 || packageOfInterest.equals(pkg.packageName))) {
2717 Slog.i(TAG, "Not granting permission " + perm
2718 + " to package " + pkg.packageName
2719 + " (protectionLevel=" + bp.getProtectionLevel()
2720 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
2721 + ")");
2722 }
2723 }
2724 }
2725 }
2726
2727 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
2728 !ps.isSystem() || ps.isUpdatedSystem()) {
2729 // This is the first that we have heard about this package, so the
2730 // permissions we have now selected are fixed until explicitly
2731 // changed.
2732 ps.setInstallPermissionsFixed(true);
2733 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002734
2735 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
2736 updatedUserIds);
2737 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002738 permissionsState, pkg, newImplicitPermissions, updatedUserIds);
Philip P. Moltmann74065c82019-05-15 10:46:32 -07002739 updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002740 }
2741
2742 // Persist the runtime permissions state for users with changes. If permissions
2743 // were revoked because no app in the shared user declares them we have to
2744 // write synchronously to avoid losing runtime permissions state.
2745 if (callback != null) {
2746 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
2747 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002748
2749 for (int userId : updatedUserIds) {
2750 notifyRuntimePermissionStateChanged(pkg.packageName, userId);
2751 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002752 }
2753
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002754 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002755 * Revoke permissions that are not implicit anymore and that have
2756 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
2757 *
2758 * @param ps The state of the permissions of the package
2759 * @param pkg The package that is currently looked at
2760 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
2761 * for a user is changed.
2762 *
2763 * @return The updated value of the {@code updatedUserIds} parameter
2764 */
2765 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
2766 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
2767 @NonNull int[] updatedUserIds) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002768 String pkgName = pkg.packageName;
Philip P. Moltmannd030ce22019-02-18 21:05:48 -08002769 boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2770 >= Build.VERSION_CODES.M;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002771
2772 int[] users = UserManagerService.getInstance().getUserIds();
2773 int numUsers = users.length;
2774 for (int i = 0; i < numUsers; i++) {
2775 int userId = users[i];
2776
2777 for (String permission : ps.getPermissions(userId)) {
2778 if (!pkg.implicitPermissions.contains(permission)) {
2779 if (!ps.hasInstallPermission(permission)) {
2780 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
2781
2782 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
2783 BasePermission bp = mSettings.getPermissionLocked(permission);
2784
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08002785 int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002786
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08002787 if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
2788 && supportsRuntimePermissions) {
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08002789 int revokeResult = ps.revokeRuntimePermission(bp, userId);
2790 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
2791 if (DEBUG_PERMISSIONS) {
2792 Slog.i(TAG, "Revoking runtime permission "
2793 + permission + " for " + pkgName
2794 + " as it is now requested");
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002795 }
2796 }
2797
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08002798 flagsToRemove |= USER_PERMISSION_FLAGS;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002799 }
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08002800
2801 ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
2802 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002803 }
2804 }
2805 }
2806 }
2807 }
2808
2809 return updatedUserIds;
2810 }
2811
2812 /**
2813 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
2814 *
2815 * <p>A single new permission can be split off from several source permissions. In this case
2816 * the most leniant state is inherited.
2817 *
2818 * <p>Warning: This does not handle foreground / background permissions
2819 *
2820 * @param sourcePerms The permissions to inherit from
2821 * @param newPerm The permission to inherit to
2822 * @param ps The permission state of the package
2823 * @param pkg The package requesting the permissions
2824 * @param userId The user the permission belongs to
2825 */
2826 private void inheritPermissionStateToNewImplicitPermissionLocked(
2827 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
2828 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
2829 @UserIdInt int userId) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002830 String pkgName = pkg.packageName;
Philip P. Moltmann9408f582019-04-10 16:58:24 -07002831 boolean isGranted = false;
2832 int flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002833
Philip P. Moltmann9408f582019-04-10 16:58:24 -07002834 int numSourcePerm = sourcePerms.size();
2835 for (int i = 0; i < numSourcePerm; i++) {
2836 String sourcePerm = sourcePerms.valueAt(i);
2837 if ((ps.hasRuntimePermission(sourcePerm, userId))
2838 || ps.hasInstallPermission(sourcePerm)) {
2839 if (!isGranted) {
2840 flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002841 }
2842
Philip P. Moltmann9408f582019-04-10 16:58:24 -07002843 isGranted = true;
2844 flags |= ps.getPermissionFlags(sourcePerm, userId);
2845 } else {
2846 if (!isGranted) {
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08002847 flags |= ps.getPermissionFlags(sourcePerm, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002848 }
2849 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002850 }
Philip P. Moltmann9408f582019-04-10 16:58:24 -07002851
2852 if (isGranted) {
2853 if (DEBUG_PERMISSIONS) {
2854 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
2855 + " for " + pkgName);
2856 }
2857
2858 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
2859 }
2860
2861 // Add permission flags
2862 ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002863 }
2864
2865 /**
Philip P. Moltmann74065c82019-05-15 10:46:32 -07002866 * When the app has requested legacy storage we might need to update
2867 * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
2868 * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
2869 *
2870 * @param pkg The package for which the permissions are updated
2871 * @param replace If the app is being replaced
2872 * @param updatedUserIds The ids of the users that already changed.
2873 *
2874 * @return The ids of the users that are changed
2875 */
2876 private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
2877 @NonNull PackageParser.Package pkg, boolean replace, @NonNull int[] updatedUserIds) {
2878 if (replace && pkg.applicationInfo.hasRequestedLegacyExternalStorage() && (
2879 pkg.requestedPermissions.contains(READ_EXTERNAL_STORAGE)
2880 || pkg.requestedPermissions.contains(WRITE_EXTERNAL_STORAGE))) {
2881 return UserManagerService.getInstance().getUserIds();
2882 }
2883
2884 return updatedUserIds;
2885 }
2886
2887 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002888 * Set the state of a implicit permission that is seen for the first time.
2889 *
2890 * @param origPs The permission state of the package before the split
2891 * @param ps The new permission state
2892 * @param pkg The package the permission belongs to
2893 * @param updatedUserIds List of users for which the permission state has already been changed
2894 *
2895 * @return List of users for which the permission state has been changed
2896 */
2897 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
2898 @NonNull PermissionsState origPs,
2899 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002900 @NonNull ArraySet<String> newImplicitPermissions,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002901 @NonNull int[] updatedUserIds) {
2902 String pkgName = pkg.packageName;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002903 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
2904
2905 int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
2906 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
2907 PermissionManager.SplitPermissionInfo spi =
2908 PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
2909
2910 List<String> newPerms = spi.getNewPermissions();
2911 int numNewPerms = newPerms.size();
2912 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
2913 String newPerm = newPerms.get(newPermNum);
2914
2915 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
2916 if (splitPerms == null) {
2917 splitPerms = new ArraySet<>();
2918 newToSplitPerms.put(newPerm, splitPerms);
2919 }
2920
2921 splitPerms.add(spi.getSplitPermission());
2922 }
2923 }
2924
2925 int numNewImplicitPerms = newImplicitPermissions.size();
2926 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
2927 newImplicitPermNum++) {
2928 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
2929 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
2930
2931 if (sourcePerms != null) {
2932 if (!ps.hasInstallPermission(newPerm)) {
2933 BasePermission bp = mSettings.getPermissionLocked(newPerm);
2934
2935 int[] users = UserManagerService.getInstance().getUserIds();
2936 int numUsers = users.length;
2937 for (int userNum = 0; userNum < numUsers; userNum++) {
2938 int userId = users[userNum];
2939
Zimuzoe6411402019-05-13 16:32:57 +01002940 if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
2941 ps.updatePermissionFlags(bp, userId,
2942 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
2943 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
2944 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002945 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2946
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08002947 boolean inheritsFromInstallPerm = false;
2948 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
2949 sourcePermNum++) {
2950 if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
2951 inheritsFromInstallPerm = true;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07002952 break;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07002953 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002954 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08002955
2956 if (!origPs.hasRequestedPermission(sourcePerms)
2957 && !inheritsFromInstallPerm) {
2958 // Both permissions are new so nothing to inherit.
2959 if (DEBUG_PERMISSIONS) {
2960 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
2961 + " for " + pkgName + " as split permission is also new");
2962 }
2963
2964 break;
2965 } else {
2966 // Inherit from new install or existing runtime permissions
2967 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
2968 newPerm, ps, pkg, userId);
2969 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002970 }
2971 }
2972 }
2973 }
2974
2975 return updatedUserIds;
2976 }
2977
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002978 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
2979 boolean allowed = false;
2980 final int NP = PackageParser.NEW_PERMISSIONS.length;
2981 for (int ip=0; ip<NP; ip++) {
2982 final PackageParser.NewPermissionInfo npi
2983 = PackageParser.NEW_PERMISSIONS[ip];
2984 if (npi.name.equals(perm)
2985 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
2986 allowed = true;
2987 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
2988 + pkg.packageName);
2989 break;
2990 }
2991 }
2992 return allowed;
2993 }
2994
2995 /**
2996 * Determines whether a package is whitelisted for a particular privapp permission.
2997 *
2998 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
2999 *
3000 * <p>This handles parent/child apps.
3001 */
3002 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003003 ArraySet<String> wlPermissions = null;
3004 if (pkg.isVendor()) {
3005 wlPermissions =
3006 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
3007 } else if (pkg.isProduct()) {
3008 wlPermissions =
3009 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003010 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01003011 wlPermissions =
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003012 SystemConfig.getInstance().getSystemExtPrivAppPermissions(
Dario Freni2bef1762018-06-01 14:02:08 +01003013 pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003014 } else {
3015 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
3016 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003017 // Let's check if this package is whitelisted...
3018 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
3019 // If it's not, we'll also tail-recurse to the parent.
3020 return whitelisted ||
3021 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
3022 }
3023
3024 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
3025 BasePermission bp, PermissionsState origPermissions) {
3026 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09003027 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
3028 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003029 boolean privappPermissionsDisable =
3030 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
3031 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
3032 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
3033 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
3034 && !platformPackage && platformPermission) {
3035 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003036 // Only report violations for apps on system image
3037 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
3038 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003039 ArraySet<String> deniedPermissions = null;
3040 if (pkg.isVendor()) {
3041 deniedPermissions = SystemConfig.getInstance()
3042 .getVendorPrivAppDenyPermissions(pkg.packageName);
3043 } else if (pkg.isProduct()) {
3044 deniedPermissions = SystemConfig.getInstance()
3045 .getProductPrivAppDenyPermissions(pkg.packageName);
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003046 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01003047 deniedPermissions = SystemConfig.getInstance()
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003048 .getSystemExtPrivAppDenyPermissions(pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003049 } else {
3050 deniedPermissions = SystemConfig.getInstance()
3051 .getPrivAppDenyPermissions(pkg.packageName);
3052 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003053 final boolean permissionViolation =
3054 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07003055 if (permissionViolation) {
3056 Slog.w(TAG, "Privileged permission " + perm + " for package "
Philip P. Moltmann384db3f2019-07-12 09:00:05 -07003057 + pkg.packageName + " (" + pkg.codePath
3058 + ") not in privapp-permissions whitelist");
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07003059
3060 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3061 if (mPrivappPermissionsViolations == null) {
3062 mPrivappPermissionsViolations = new ArraySet<>();
3063 }
Philip P. Moltmann384db3f2019-07-12 09:00:05 -07003064 mPrivappPermissionsViolations.add(
3065 pkg.packageName + " (" + pkg.codePath + "): " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003066 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003067 } else {
3068 return false;
3069 }
3070 }
3071 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3072 return false;
3073 }
3074 }
3075 }
3076 final String systemPackageName = mPackageManagerInt.getKnownPackageName(
3077 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
3078 final PackageParser.Package systemPackage =
3079 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003080
3081 // check if the package is allow to use this signature permission. A package is allowed to
3082 // use a signature permission if:
3083 // - it has the same set of signing certificates as the source package
3084 // - or its signing certificate was rotated from the source package's certificate
3085 // - or its signing certificate is a previous signing certificate of the defining
3086 // package, and the defining package still trusts the old certificate for permissions
3087 // - or it shares the above relationships with the system package
3088 boolean allowed =
3089 pkg.mSigningDetails.hasAncestorOrSelf(
3090 bp.getSourcePackageSetting().getSigningDetails())
3091 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
3092 pkg.mSigningDetails,
3093 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
3094 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
3095 || systemPackage.mSigningDetails.checkCapability(
3096 pkg.mSigningDetails,
3097 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003098 if (!allowed && (privilegedPermission || oemPermission)) {
3099 if (pkg.isSystem()) {
3100 // For updated system applications, a privileged/oem permission
3101 // is granted only if it had been defined by the original application.
3102 if (pkg.isUpdatedSystemApp()) {
3103 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00003104 mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003105 final PackageSetting disabledPs =
3106 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
3107 if (disabledPs != null
3108 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
3109 // If the original was granted this permission, we take
3110 // that grant decision as read and propagate it to the
3111 // update.
3112 if ((privilegedPermission && disabledPs.isPrivileged())
3113 || (oemPermission && disabledPs.isOem()
3114 && canGrantOemPermission(disabledPs, perm))) {
3115 allowed = true;
3116 }
3117 } else {
3118 // The system apk may have been updated with an older
3119 // version of the one on the data partition, but which
3120 // granted a new system permission that it didn't have
3121 // before. In this case we do want to allow the app to
3122 // now get the new permission if the ancestral apk is
3123 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07003124 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003125 && isPackageRequestingPermission(disabledPkg, perm)
3126 && ((privilegedPermission && disabledPs.isPrivileged())
3127 || (oemPermission && disabledPs.isOem()
3128 && canGrantOemPermission(disabledPs, perm)))) {
3129 allowed = true;
3130 }
3131 // Also if a privileged parent package on the system image or any of
3132 // its children requested a privileged/oem permission, the updated child
3133 // packages can also get the permission.
3134 if (pkg.parentPackage != null) {
3135 final PackageParser.Package disabledParentPkg = mPackageManagerInt
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00003136 .getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003137 final PackageSetting disabledParentPs = (disabledParentPkg != null)
3138 ? (PackageSetting) disabledParentPkg.mExtras : null;
3139 if (disabledParentPkg != null
3140 && ((privilegedPermission && disabledParentPs.isPrivileged())
3141 || (oemPermission && disabledParentPs.isOem()))) {
3142 if (isPackageRequestingPermission(disabledParentPkg, perm)
3143 && canGrantOemPermission(disabledParentPs, perm)) {
3144 allowed = true;
3145 } else if (disabledParentPkg.childPackages != null) {
3146 for (PackageParser.Package disabledChildPkg
3147 : disabledParentPkg.childPackages) {
3148 final PackageSetting disabledChildPs =
3149 (disabledChildPkg != null)
3150 ? (PackageSetting) disabledChildPkg.mExtras
3151 : null;
3152 if (isPackageRequestingPermission(disabledChildPkg, perm)
3153 && canGrantOemPermission(
3154 disabledChildPs, perm)) {
3155 allowed = true;
3156 break;
3157 }
3158 }
3159 }
3160 }
3161 }
3162 }
3163 } else {
3164 final PackageSetting ps = (PackageSetting) pkg.mExtras;
3165 allowed = (privilegedPermission && pkg.isPrivileged())
3166 || (oemPermission && pkg.isOem()
3167 && canGrantOemPermission(ps, perm));
3168 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09003169 // In any case, don't grant a privileged permission to privileged vendor apps, if
3170 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
3171 // flag.
3172 if (allowed && privilegedPermission &&
3173 !vendorPrivilegedPermission && pkg.isVendor()) {
3174 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
3175 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
3176 allowed = false;
3177 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003178 }
3179 }
3180 if (!allowed) {
3181 if (!allowed
3182 && bp.isPre23()
3183 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
3184 // If this was a previously normal/dangerous permission that got moved
3185 // to a system permission as part of the runtime permission redesign, then
3186 // we still want to blindly grant it to old apps.
3187 allowed = true;
3188 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07003189 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
3190 // need a separate flag anymore. Hence we need to check which
3191 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003192 if (!allowed && bp.isInstaller()
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07003193 && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
3194 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
3195 || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
3196 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
3197 UserHandle.USER_SYSTEM)))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003198 // If this permission is to be granted to the system installer and
3199 // this app is an installer, then it gets the permission.
3200 allowed = true;
3201 }
3202 if (!allowed && bp.isVerifier()
3203 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
3204 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
3205 // If this permission is to be granted to the system verifier and
3206 // this app is a verifier, then it gets the permission.
3207 allowed = true;
3208 }
3209 if (!allowed && bp.isPreInstalled()
3210 && pkg.isSystem()) {
3211 // Any pre-installed system app is allowed to get this permission.
3212 allowed = true;
3213 }
3214 if (!allowed && bp.isDevelopment()) {
3215 // For development permissions, a development permission
3216 // is granted only if it was already granted.
3217 allowed = origPermissions.hasInstallPermission(perm);
3218 }
3219 if (!allowed && bp.isSetup()
3220 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
3221 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
3222 // If this permission is to be granted to the system setup wizard and
3223 // this app is a setup wizard, then it gets the permission.
3224 allowed = true;
3225 }
Makoto Onuki700feef2018-02-15 10:59:41 -08003226 if (!allowed && bp.isSystemTextClassifier()
3227 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
3228 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
3229 UserHandle.USER_SYSTEM))) {
3230 // Special permissions for the system default text classifier.
3231 allowed = true;
3232 }
Stanislav Zholnin596437f2018-12-28 15:34:23 +00003233 if (!allowed && bp.isConfigurator()
3234 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
3235 PackageManagerInternal.PACKAGE_CONFIGURATOR,
3236 UserHandle.USER_SYSTEM))) {
3237 // Special permissions for the device configurator.
3238 allowed = true;
3239 }
Varun Shah5f303652018-11-16 18:11:19 -08003240 if (!allowed && bp.isWellbeing()
3241 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
3242 PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM))) {
3243 // Special permission granted only to the OEM specified wellbeing app
3244 allowed = true;
3245 }
Jeff Sharkey15707b32018-12-10 12:08:41 -07003246 if (!allowed && bp.isDocumenter()
3247 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
3248 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM))) {
3249 // If this permission is to be granted to the documenter and
3250 // this app is the documenter, then it gets the permission.
3251 allowed = true;
3252 }
Joe Onorato5a15b552018-12-18 10:40:04 -08003253 if (!allowed && bp.isIncidentReportApprover()
3254 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
3255 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
3256 UserHandle.USER_SYSTEM))) {
3257 // If this permission is to be granted to the incident report approver and
3258 // this app is the incident report approver, then it gets the permission.
3259 allowed = true;
3260 }
George Hodulikcd7695d2019-01-29 18:17:05 -08003261 if (!allowed && bp.isAppPredictor()
3262 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
3263 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM))) {
3264 // Special permissions for the system app predictor.
3265 allowed = true;
3266 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003267 }
3268 return allowed;
3269 }
3270
3271 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
3272 if (!ps.isOem()) {
3273 return false;
3274 }
3275 // all oem permissions must explicitly be granted or denied
3276 final Boolean granted =
3277 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
3278 if (granted == null) {
3279 throw new IllegalStateException("OEM permission" + permission + " requested by package "
3280 + ps.name + " must be explicitly declared granted or not");
3281 }
3282 return Boolean.TRUE == granted;
3283 }
3284
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07003285 private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
3286 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003287 // Permission review applies only to apps not supporting the new permission model.
3288 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
3289 return false;
3290 }
3291
3292 // Legacy apps have the permission and get user consent on launch.
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07003293 if (pkg.mExtras == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003294 return false;
3295 }
3296 final PackageSetting ps = (PackageSetting) pkg.mExtras;
3297 final PermissionsState permissionsState = ps.getPermissionsState();
3298 return permissionsState.isPermissionReviewRequired(userId);
3299 }
3300
3301 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
3302 final int permCount = pkg.requestedPermissions.size();
3303 for (int j = 0; j < permCount; j++) {
3304 String requestedPermission = pkg.requestedPermissions.get(j);
3305 if (permission.equals(requestedPermission)) {
3306 return true;
3307 }
3308 }
3309 return false;
3310 }
3311
Andreas Gampea36dc622018-02-05 17:19:22 -08003312 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07003313 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
3314 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
3315 if (pkg.parentPackage == null) {
3316 return;
3317 }
3318 if (pkg.requestedPermissions == null) {
3319 return;
3320 }
3321 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00003322 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003323 if (disabledPkg == null || disabledPkg.mExtras == null) {
3324 return;
3325 }
3326 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
3327 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
3328 return;
3329 }
3330 final int permCount = pkg.requestedPermissions.size();
3331 for (int i = 0; i < permCount; i++) {
3332 String permission = pkg.requestedPermissions.get(i);
3333 BasePermission bp = mSettings.getPermissionLocked(permission);
3334 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
3335 continue;
3336 }
3337 for (int userId : mUserManagerInt.getUserIds()) {
3338 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
Todd Kennedyc971a452019-07-08 16:04:52 -07003339 grantRuntimePermissionInternal(
Todd Kennedy0eb97382017-10-03 16:57:22 -07003340 permission, pkg.packageName, false, callingUid, userId, callback);
3341 }
3342 }
3343 }
3344 }
3345
3346 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
3347 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3348 for (int userId : userIds) {
3349 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
3350 callback);
3351 }
3352 }
3353
3354 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
3355 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3356 PackageSetting ps = (PackageSetting) pkg.mExtras;
3357 if (ps == null) {
3358 return;
3359 }
3360
3361 PermissionsState permissionsState = ps.getPermissionsState();
3362
3363 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
3364 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3365
3366 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
3367 >= Build.VERSION_CODES.M;
3368
3369 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
3370
3371 for (String permission : pkg.requestedPermissions) {
3372 final BasePermission bp;
3373 synchronized (mLock) {
3374 bp = mSettings.getPermissionLocked(permission);
3375 }
3376 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
3377 && (!instantApp || bp.isInstant())
3378 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
3379 && (grantedPermissions == null
3380 || ArrayUtils.contains(grantedPermissions, permission))) {
3381 final int flags = permissionsState.getPermissionFlags(permission, userId);
3382 if (supportsRuntimePermissions) {
3383 // Installer cannot change immutable permissions.
3384 if ((flags & immutableFlags) == 0) {
Todd Kennedyc971a452019-07-08 16:04:52 -07003385 grantRuntimePermissionInternal(permission, pkg.packageName, false,
3386 callingUid, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003387 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07003388 } else {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003389 // In permission review mode we clear the review flag when we
3390 // are asked to install the app with all permissions granted.
3391 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
Todd Kennedy230c0a72019-07-03 13:06:35 -07003392 updatePermissionFlagsInternal(permission, pkg.packageName,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003393 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08003394 userId, false, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003395 }
3396 }
3397 }
3398 }
3399 }
3400
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003401 private void setWhitelistedRestrictedPermissionsForUser(@NonNull PackageParser.Package pkg,
3402 @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
3403 @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003404 final PermissionsState permissionsState =
3405 PackageManagerServiceUtils.getPermissionsState(pkg);
3406 if (permissionsState == null) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003407 return;
3408 }
3409
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003410 ArraySet<String> oldGrantedRestrictedPermissions = null;
3411 boolean updatePermissions = false;
3412
3413 final int permissionCount = pkg.requestedPermissions.size();
3414 for (int i = 0; i < permissionCount; i++) {
3415 final String permissionName = pkg.requestedPermissions.get(i);
3416
3417 final BasePermission bp = mSettings.getPermissionLocked(permissionName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003418
Evan Seversoncdcaaaa2019-07-02 10:29:25 -07003419 if (bp == null || !bp.isHardOrSoftRestricted()) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003420 continue;
3421 }
3422
3423 if (permissionsState.hasPermission(permissionName, userId)) {
3424 if (oldGrantedRestrictedPermissions == null) {
3425 oldGrantedRestrictedPermissions = new ArraySet<>();
3426 }
3427 oldGrantedRestrictedPermissions.add(permissionName);
3428 }
3429
3430 final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
3431
3432 int newFlags = oldFlags;
3433 int mask = 0;
3434 int whitelistFlagsCopy = whitelistFlags;
3435 while (whitelistFlagsCopy != 0) {
3436 final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
3437 whitelistFlagsCopy &= ~flag;
3438 switch (flag) {
3439 case FLAG_PERMISSION_WHITELIST_SYSTEM: {
3440 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3441 if (permissions != null && permissions.contains(permissionName)) {
3442 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3443 } else {
3444 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3445 }
3446 } break;
3447 case FLAG_PERMISSION_WHITELIST_UPGRADE: {
3448 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3449 if (permissions != null && permissions.contains(permissionName)) {
3450 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3451 } else {
3452 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3453 }
3454 } break;
3455 case FLAG_PERMISSION_WHITELIST_INSTALLER: {
3456 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3457 if (permissions != null && permissions.contains(permissionName)) {
3458 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3459 } else {
3460 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3461 }
3462 } break;
3463 }
3464 }
3465
3466 if (oldFlags == newFlags) {
3467 continue;
3468 }
3469
3470 updatePermissions = true;
3471
Svet Ganovd563e932019-04-14 13:07:41 -07003472 final boolean wasWhitelisted = (oldFlags
3473 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3474 final boolean isWhitelisted = (newFlags
3475 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3476
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003477 // If the permission is policy fixed as granted but it is no longer
3478 // on any of the whitelists we need to clear the policy fixed flag
3479 // as whitelisting trumps policy i.e. policy cannot grant a non
3480 // grantable permission.
3481 if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003482 final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
3483 if (!isWhitelisted && isGranted) {
3484 mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3485 newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3486 }
3487 }
3488
Svet Ganovd563e932019-04-14 13:07:41 -07003489 // If we are whitelisting an app that does not support runtime permissions
3490 // we need to make sure it goes through the permission review UI at launch.
3491 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
3492 && !wasWhitelisted && isWhitelisted) {
3493 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3494 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3495 }
3496
Todd Kennedy230c0a72019-07-03 13:06:35 -07003497 updatePermissionFlagsInternal(permissionName, pkg.packageName, mask, newFlags,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003498 callingUid, userId, false, null /*callback*/);
3499 }
3500
3501 if (updatePermissions) {
Philip P. Moltmannba742062019-04-08 13:22:44 -07003502 // Update permission of this app to take into account the new whitelist state.
3503 restorePermissionState(pkg, false, pkg.packageName, callback);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003504
3505 // If this resulted in losing a permission we need to kill the app.
3506 if (oldGrantedRestrictedPermissions != null) {
3507 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
3508 for (int i = 0; i < oldGrantedCount; i++) {
3509 final String permission = oldGrantedRestrictedPermissions.valueAt(i);
3510 // Sometimes we create a new permission state instance during update.
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003511 final PermissionsState newPermissionsState =
3512 PackageManagerServiceUtils.getPermissionsState(pkg);
3513 if (!newPermissionsState.hasPermission(permission, userId)) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003514 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
3515 break;
3516 }
3517 }
3518 }
3519 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07003520 }
3521
Andreas Gampea36dc622018-02-05 17:19:22 -08003522 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003523 private int[] revokeUnusedSharedUserPermissionsLocked(
3524 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003525 // Collect all used permissions in the UID
3526 final ArraySet<String> usedPermissions = new ArraySet<>();
3527 final List<PackageParser.Package> pkgList = suSetting.getPackages();
3528 if (pkgList == null || pkgList.size() == 0) {
3529 return EmptyArray.INT;
3530 }
3531 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07003532 if (pkg.requestedPermissions == null) {
3533 continue;
3534 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07003535 final int requestedPermCount = pkg.requestedPermissions.size();
3536 for (int j = 0; j < requestedPermCount; j++) {
3537 String permission = pkg.requestedPermissions.get(j);
3538 BasePermission bp = mSettings.getPermissionLocked(permission);
3539 if (bp != null) {
3540 usedPermissions.add(permission);
3541 }
3542 }
3543 }
3544
3545 PermissionsState permissionsState = suSetting.getPermissionsState();
3546 // Prune install permissions
3547 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
3548 final int installPermCount = installPermStates.size();
3549 for (int i = installPermCount - 1; i >= 0; i--) {
3550 PermissionState permissionState = installPermStates.get(i);
3551 if (!usedPermissions.contains(permissionState.getName())) {
3552 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
3553 if (bp != null) {
3554 permissionsState.revokeInstallPermission(bp);
3555 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08003556 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003557 }
3558 }
3559 }
3560
3561 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
3562
3563 // Prune runtime permissions
3564 for (int userId : allUserIds) {
3565 List<PermissionState> runtimePermStates = permissionsState
3566 .getRuntimePermissionStates(userId);
3567 final int runtimePermCount = runtimePermStates.size();
3568 for (int i = runtimePermCount - 1; i >= 0; i--) {
3569 PermissionState permissionState = runtimePermStates.get(i);
3570 if (!usedPermissions.contains(permissionState.getName())) {
3571 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
3572 if (bp != null) {
3573 permissionsState.revokeRuntimePermission(bp, userId);
3574 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08003575 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003576 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
3577 runtimePermissionChangedUserIds, userId);
3578 }
3579 }
3580 }
3581 }
3582
3583 return runtimePermissionChangedUserIds;
3584 }
3585
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003586 /**
3587 * Update permissions when a package changed.
3588 *
3589 * <p><ol>
3590 * <li>Reconsider the ownership of permission</li>
3591 * <li>Update the state (grant, flags) of the permissions</li>
3592 * </ol>
3593 *
3594 * @param packageName The package that is updated
3595 * @param pkg The package that is updated, or {@code null} if package is deleted
3596 * @param allPackages All currently known packages
3597 * @param callback Callback to call after permission changes
3598 */
3599 private void updatePermissions(@NonNull String packageName, @Nullable PackageParser.Package pkg,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003600 @NonNull PermissionCallback callback) {
3601 final int flags =
3602 (pkg != null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG : 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003603 updatePermissions(
Todd Kennedyc971a452019-07-08 16:04:52 -07003604 packageName, pkg, getVolumeUuidForPackage(pkg), flags, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003605 if (pkg != null && pkg.childPackages != null) {
3606 for (PackageParser.Package childPkg : pkg.childPackages) {
3607 updatePermissions(childPkg.packageName, childPkg,
Todd Kennedyc971a452019-07-08 16:04:52 -07003608 getVolumeUuidForPackage(childPkg), flags, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003609 }
3610 }
3611 }
3612
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003613 /**
3614 * Update all permissions for all apps.
3615 *
3616 * <p><ol>
3617 * <li>Reconsider the ownership of permission</li>
3618 * <li>Update the state (grant, flags) of the permissions</li>
3619 * </ol>
3620 *
3621 * @param volumeUuid The volume of the packages to be updated, {@code null} for all volumes
3622 * @param allPackages All currently known packages
3623 * @param callback Callback to call after permission changes
3624 */
3625 private void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003626 @NonNull PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003627 final int flags = UPDATE_PERMISSIONS_ALL |
3628 (sdkUpdated
3629 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
3630 : 0);
Todd Kennedyc971a452019-07-08 16:04:52 -07003631 updatePermissions(null, null, volumeUuid, flags, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003632 }
3633
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003634 /**
3635 * Cache background->foreground permission mapping.
3636 *
3637 * <p>This is only run once.
3638 */
3639 private void cacheBackgroundToForegoundPermissionMapping() {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003640 synchronized (mLock) {
3641 if (mBackgroundPermissions == null) {
3642 // Cache background -> foreground permission mapping.
3643 // Only system declares background permissions, hence mapping does never change.
3644 mBackgroundPermissions = new ArrayMap<>();
3645 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Philip P. Moltmann798bf9a2018-11-08 17:07:19 -08003646 if (bp.perm != null && bp.perm.info != null
3647 && bp.perm.info.backgroundPermission != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003648 String fgPerm = bp.name;
3649 String bgPerm = bp.perm.info.backgroundPermission;
3650
3651 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
3652 if (fgPerms == null) {
3653 fgPerms = new ArrayList<>();
3654 mBackgroundPermissions.put(bgPerm, fgPerms);
3655 }
3656
3657 fgPerms.add(fgPerm);
3658 }
3659 }
3660 }
3661 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003662 }
3663
3664 /**
3665 * Update all packages on the volume, <u>beside</u> the changing package. If the changing
3666 * package is set too, all packages are updated.
3667 */
3668 private static final int UPDATE_PERMISSIONS_ALL = 1 << 0;
3669 /** The changing package is replaced. Requires the changing package to be set */
3670 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1 << 1;
3671 /**
3672 * Schedule all packages <u>beside</u> the changing package for replacement. Requires
3673 * UPDATE_PERMISSIONS_ALL to be set
3674 */
3675 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1 << 2;
3676
3677 @IntDef(flag = true, prefix = { "UPDATE_PERMISSIONS_" }, value = {
3678 UPDATE_PERMISSIONS_ALL, UPDATE_PERMISSIONS_REPLACE_PKG,
3679 UPDATE_PERMISSIONS_REPLACE_ALL })
3680 @Retention(RetentionPolicy.SOURCE)
3681 private @interface UpdatePermissionFlags {}
3682
3683 /**
3684 * Update permissions when packages changed.
3685 *
3686 * <p><ol>
3687 * <li>Reconsider the ownership of permission</li>
3688 * <li>Update the state (grant, flags) of the permissions</li>
3689 * </ol>
3690 *
3691 * <p>Meaning of combination of package parameters:
3692 * <table>
3693 * <tr><th></th><th>changingPkgName != null</th><th>changingPkgName == null</th></tr>
3694 * <tr><th>changingPkg != null</th><td>package is updated</td><td>invalid</td></tr>
3695 * <tr><th>changingPkg == null</th><td>package is deleted</td><td>all packages are
3696 * updated</td></tr>
3697 * </table>
3698 *
3699 * @param changingPkgName The package that is updated, or {@code null} if all packages should be
3700 * updated
3701 * @param changingPkg The package that is updated, or {@code null} if all packages should be
3702 * updated or package is deleted
3703 * @param replaceVolumeUuid The volume of the packages to be updated are on, {@code null} for
3704 * all volumes
3705 * @param flags Control permission for which apps should be updated
3706 * @param allPackages All currently known packages
3707 * @param callback Callback to call after permission changes
3708 */
Todd Kennedyc971a452019-07-08 16:04:52 -07003709 private void updatePermissions(final @Nullable String changingPkgName,
3710 final @Nullable PackageParser.Package changingPkg,
3711 final @Nullable String replaceVolumeUuid,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003712 @UpdatePermissionFlags int flags,
Todd Kennedyc971a452019-07-08 16:04:52 -07003713 final @Nullable PermissionCallback callback) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003714 // TODO: Most of the methods exposing BasePermission internals [source package name,
3715 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
3716 // have package settings, we should make note of it elsewhere [map between
3717 // source package name and BasePermission] and cycle through that here. Then we
3718 // define a single method on BasePermission that takes a PackageSetting, changing
3719 // package name and a package.
3720 // NOTE: With this approach, we also don't need to tree trees differently than
3721 // normal permissions. Today, we need two separate loops because these BasePermission
3722 // objects are stored separately.
3723 // Make sure there are no dangling permission trees.
3724 boolean permissionTreesSourcePackageChanged = updatePermissionTreeSourcePackage(
3725 changingPkgName, changingPkg);
3726 // Make sure all dynamic permissions have been assigned to a package,
3727 // and make sure there are no dangling permissions.
3728 boolean permissionSourcePackageChanged = updatePermissionSourcePackage(changingPkgName,
3729 changingPkg);
3730
3731 if (permissionTreesSourcePackageChanged | permissionSourcePackageChanged) {
3732 // Permission ownership has changed. This e.g. changes which packages can get signature
3733 // permissions
3734 flags |= UPDATE_PERMISSIONS_ALL;
3735 }
3736
3737 cacheBackgroundToForegoundPermissionMapping();
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003738
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07003739 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003740 // Now update the permissions for all packages.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003741 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
Todd Kennedyc971a452019-07-08 16:04:52 -07003742 final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
3743 mPackageManagerInt.forEachPackage((Package pkg) -> {
3744 if (pkg == changingPkg) {
3745 return;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003746 }
Todd Kennedyc971a452019-07-08 16:04:52 -07003747 // Only replace for packages on requested volume
3748 final String volumeUuid = getVolumeUuidForPackage(pkg);
3749 final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid);
3750 restorePermissionState(pkg, replace, changingPkgName, callback);
3751 });
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003752 }
3753
3754 if (changingPkg != null) {
3755 // Only replace for packages on requested volume
3756 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
3757 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
3758 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07003759 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003760 }
3761 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3762 }
3763
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003764 /**
3765 * Update which app declares a permission.
3766 *
3767 * <p>Possible parameter combinations
3768 * <table>
3769 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
3770 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
3771 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
3772 * </table>
3773 *
3774 * @param packageName The package that is updated, or {@code null} if all packages should be
3775 * updated
3776 * @param pkg The package that is updated, or {@code null} if all packages should be updated or
3777 * package is deleted
3778 *
3779 * @return {@code true} if a permission source package might have changed
3780 */
3781 private boolean updatePermissionSourcePackage(@Nullable String packageName,
3782 @Nullable PackageParser.Package pkg) {
3783 boolean changed = false;
3784
Todd Kennedyc8423932017-10-05 08:58:36 -07003785 Set<BasePermission> needsUpdate = null;
3786 synchronized (mLock) {
3787 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
3788 while (it.hasNext()) {
3789 final BasePermission bp = it.next();
3790 if (bp.isDynamic()) {
3791 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
3792 }
3793 if (bp.getSourcePackageSetting() != null) {
3794 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003795 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003796 Slog.i(TAG, "Removing permission " + bp.getName()
3797 + " that used to be declared by " + bp.getSourcePackageName());
3798 changed = true;
Todd Kennedyc8423932017-10-05 08:58:36 -07003799 it.remove();
3800 }
3801 continue;
3802 }
3803 if (needsUpdate == null) {
3804 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
3805 }
3806 needsUpdate.add(bp);
3807 }
3808 }
3809 if (needsUpdate != null) {
3810 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003811 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07003812 mPackageManagerInt.getPackage(bp.getSourcePackageName());
3813 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003814 if (sourcePkg != null && sourcePkg.mExtras != null) {
3815 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07003816 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003817 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07003818 }
3819 continue;
3820 }
3821 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
3822 + " from package " + bp.getSourcePackageName());
3823 mSettings.removePermissionLocked(bp.getName());
3824 }
3825 }
3826 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003827 return changed;
Todd Kennedyc8423932017-10-05 08:58:36 -07003828 }
3829
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003830 /**
3831 * Update which app owns a permission trees.
3832 *
3833 * <p>Possible parameter combinations
3834 * <table>
3835 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
3836 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
3837 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
3838 * </table>
3839 *
3840 * @param packageName The package that is updated, or {@code null} if all packages should be
3841 * updated
3842 * @param pkg The package that is updated, or {@code null} if all packages should be updated or
3843 * package is deleted
3844 *
3845 * @return {@code true} if a permission tree ownership might have changed
3846 */
3847 private boolean updatePermissionTreeSourcePackage(@Nullable String packageName,
3848 @Nullable PackageParser.Package pkg) {
3849 boolean changed = false;
3850
Todd Kennedyc8423932017-10-05 08:58:36 -07003851 Set<BasePermission> needsUpdate = null;
3852 synchronized (mLock) {
3853 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
3854 while (it.hasNext()) {
3855 final BasePermission bp = it.next();
3856 if (bp.getSourcePackageSetting() != null) {
3857 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003858 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003859 Slog.i(TAG, "Removing permission tree " + bp.getName()
3860 + " that used to be declared by " + bp.getSourcePackageName());
3861 changed = true;
Todd Kennedyc8423932017-10-05 08:58:36 -07003862 it.remove();
3863 }
3864 continue;
3865 }
3866 if (needsUpdate == null) {
3867 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
3868 }
3869 needsUpdate.add(bp);
3870 }
3871 }
3872 if (needsUpdate != null) {
3873 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003874 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07003875 mPackageManagerInt.getPackage(bp.getSourcePackageName());
3876 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003877 if (sourcePkg != null && sourcePkg.mExtras != null) {
3878 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07003879 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003880 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07003881 }
3882 continue;
3883 }
3884 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
3885 + " from package " + bp.getSourcePackageName());
3886 mSettings.removePermissionLocked(bp.getName());
3887 }
3888 }
3889 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003890 return changed;
Todd Kennedyc8423932017-10-05 08:58:36 -07003891 }
3892
Todd Kennedy0eb97382017-10-03 16:57:22 -07003893 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
3894 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
3895 != PackageManager.PERMISSION_GRANTED
3896 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
3897 != PackageManager.PERMISSION_GRANTED) {
3898 throw new SecurityException(message + " requires "
3899 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
3900 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
3901 }
3902 }
3903
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08003904 private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
3905 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
3906 != PackageManager.PERMISSION_GRANTED
3907 && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
3908 != PackageManager.PERMISSION_GRANTED
3909 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
3910 != PackageManager.PERMISSION_GRANTED) {
3911 throw new SecurityException(message + " requires "
3912 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
3913 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
3914 + Manifest.permission.GET_RUNTIME_PERMISSIONS);
3915 }
3916 }
3917
Todd Kennedy0eb97382017-10-03 16:57:22 -07003918 /**
3919 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3920 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3921 * @param checkShell whether to prevent shell from access if there's a debugging restriction
3922 * @param message the message to log on security exception
3923 */
3924 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07003925 boolean requireFullPermission, boolean checkShell,
3926 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003927 if (userId < 0) {
3928 throw new IllegalArgumentException("Invalid userId " + userId);
3929 }
3930 if (checkShell) {
Patrick Baumann2f2fd712019-07-31 15:18:53 -07003931 PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003932 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3933 }
Todd Kennedyef9acb62018-05-29 15:18:06 -07003934 if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07003935 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003936 if (requireFullPermission) {
3937 mContext.enforceCallingOrSelfPermission(
3938 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3939 } else {
3940 try {
3941 mContext.enforceCallingOrSelfPermission(
3942 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3943 } catch (SecurityException se) {
3944 mContext.enforceCallingOrSelfPermission(
3945 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3946 }
3947 }
3948 }
3949 }
3950
Andreas Gampea71bee82018-07-20 12:55:36 -07003951 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07003952 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3953 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07003954 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003955 size += tree.calculateFootprint(perm);
3956 }
3957 return size;
3958 }
3959
Andreas Gampea71bee82018-07-20 12:55:36 -07003960 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07003961 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3962 // We calculate the max size of permissions defined by this uid and throw
3963 // if that plus the size of 'info' would exceed our stated maximum.
3964 if (tree.getUid() != Process.SYSTEM_UID) {
3965 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3966 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
3967 throw new SecurityException("Permission tree size cap exceeded");
3968 }
3969 }
3970 }
3971
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003972 private void systemReady() {
3973 mSystemReady = true;
3974 if (mPrivappPermissionsViolations != null) {
3975 throw new IllegalStateException("Signature|privileged permissions not in "
3976 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
3977 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08003978
3979 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
Svet Ganov3c499ea2019-07-26 17:45:56 -07003980 mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
Todd Kennedy583378d2019-07-12 06:50:30 -07003981
3982 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
3983 for (int userId : UserManagerService.getInstance().getUserIds()) {
3984 if (!mPackageManagerInt.areDefaultRuntimePermissionsGranted(userId)) {
3985 grantPermissionsUserIds = ArrayUtils.appendInt(
3986 grantPermissionsUserIds, userId);
3987 }
3988 }
3989 // If we upgraded grant all default permissions before kicking off.
3990 for (int userId : grantPermissionsUserIds) {
3991 mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
3992 }
3993 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
3994 // If we did not grant default permissions, we preload from this the
3995 // default permission exceptions lazily to ensure we don't hit the
3996 // disk on a new user creation.
3997 mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
3998 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003999 }
4000
4001 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
4002 if (pkg == null) {
4003 return StorageManager.UUID_PRIVATE_INTERNAL;
4004 }
4005 if (pkg.isExternal()) {
4006 if (TextUtils.isEmpty(pkg.volumeUuid)) {
4007 return StorageManager.UUID_PRIMARY_PHYSICAL;
4008 } else {
4009 return pkg.volumeUuid;
4010 }
4011 } else {
4012 return StorageManager.UUID_PRIVATE_INTERNAL;
4013 }
4014 }
4015
Todd Kennedyc8423932017-10-05 08:58:36 -07004016 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
4017 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
4018 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
4019 return true;
4020 }
4021 }
4022 return false;
4023 }
4024
Todd Kennedy0eb97382017-10-03 16:57:22 -07004025 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004026 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07004027 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004028 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07004029 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004030 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07004031 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004032 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
4033 final LogMaker log = new LogMaker(action);
4034 log.setPackageName(packageName);
4035 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004036
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004037 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004038 }
4039
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07004040 /**
4041 * Get the mapping of background permissions to their foreground permissions.
4042 *
4043 * <p>Only initialized in the system server.
4044 *
4045 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
4046 */
4047 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
4048 return mBackgroundPermissions;
4049 }
4050
Philip P. Moltmann48456672019-01-20 13:14:03 -08004051 private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004052 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004053 public void systemReady() {
4054 PermissionManagerService.this.systemReady();
4055 }
4056 @Override
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07004057 public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004058 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
4059 }
4060 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004061 public void revokeRuntimePermissionsIfGroupChanged(
4062 @NonNull PackageParser.Package newPackage,
4063 @NonNull PackageParser.Package oldPackage,
Todd Kennedyc971a452019-07-08 16:04:52 -07004064 @NonNull ArrayList<String> allPackageNames) {
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004065 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
Todd Kennedyc971a452019-07-08 16:04:52 -07004066 oldPackage, allPackageNames, mDefaultPermissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004067 }
4068 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07004069 public void addAllPermissions(Package pkg, boolean chatty) {
4070 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004071 }
4072 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07004073 public void addAllPermissionGroups(Package pkg, boolean chatty) {
4074 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
4075 }
4076 @Override
Hongming Jinae750fb2018-09-27 23:00:20 +00004077 public void removeAllPermissions(Package pkg, boolean chatty) {
4078 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07004079 }
4080 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004081 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
Todd Kennedyc971a452019-07-08 16:04:52 -07004082 String[] grantedPermissions, int callingUid) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004083 PermissionManagerService.this.grantRequestedRuntimePermissions(
Todd Kennedyc971a452019-07-08 16:04:52 -07004084 pkg, userIds, grantedPermissions, callingUid, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004085 }
4086 @Override
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004087 public void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
4088 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
Todd Kennedyc971a452019-07-08 16:04:52 -07004089 @PackageManager.PermissionWhitelistFlags int flags) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004090 for (int userId : userIds) {
4091 setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
Todd Kennedyc971a452019-07-08 16:04:52 -07004092 callingUid, flags, mDefaultPermissionCallback);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004093 }
4094 }
4095 @Override
4096 public void setWhitelistedRestrictedPermissions(String packageName,
4097 List<String> permissions, int flags, int userId) {
4098 PermissionManagerService.this.setWhitelistedRestrictedPermissionsInternal(
4099 packageName, permissions, flags, userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004100 }
4101 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004102 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
Todd Kennedyc971a452019-07-08 16:04:52 -07004103 int callingUid) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004104 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
Todd Kennedyc971a452019-07-08 16:04:52 -07004105 pkg, callingUid, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004106 }
4107 @Override
Todd Kennedyc971a452019-07-08 16:04:52 -07004108 public void updatePermissions(@NonNull String packageName, @Nullable Package pkg) {
4109 PermissionManagerService.this
4110 .updatePermissions(packageName, pkg, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004111 }
4112 @Override
Todd Kennedyc971a452019-07-08 16:04:52 -07004113 public void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated) {
4114 PermissionManagerService.this
4115 .updateAllPermissions(volumeUuid, sdkUpdated, mDefaultPermissionCallback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004116 }
4117 @Override
Todd Kennedyc971a452019-07-08 16:04:52 -07004118 public void resetRuntimePermissions(Package pkg, int userId) {
4119 PermissionManagerService.this.resetRuntimePermissionsInternal(pkg, userId);
4120 }
4121 @Override
4122 public void resetAllRuntimePermissions(final int userId) {
4123 mPackageManagerInt.forEachPackage(
4124 (PackageParser.Package pkg) -> resetRuntimePermissionsInternal(pkg, userId));
Todd Kennedy0eb97382017-10-03 16:57:22 -07004125 }
4126 @Override
Todd Kennedy8f135982019-07-02 07:35:15 -07004127 public String[] getAppOpPermissionPackages(String permName, int callingUid) {
4128 return PermissionManagerService.this
4129 .getAppOpPermissionPackagesInternal(permName, callingUid);
Todd Kennedyc8423932017-10-05 08:58:36 -07004130 }
4131 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004132 public void enforceCrossUserPermission(int callingUid, int userId,
4133 boolean requireFullPermission, boolean checkShell, String message) {
4134 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07004135 requireFullPermission, checkShell, false, message);
4136 }
4137 @Override
4138 public void enforceCrossUserPermission(int callingUid, int userId,
4139 boolean requireFullPermission, boolean checkShell,
4140 boolean requirePermissionWhenSameUser, String message) {
4141 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
4142 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004143 }
4144 @Override
4145 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4146 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
4147 }
4148 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004149 public PermissionSettings getPermissionSettings() {
4150 return mSettings;
4151 }
4152 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004153 public BasePermission getPermissionTEMP(String permName) {
4154 synchronized (PermissionManagerService.this.mLock) {
4155 return mSettings.getPermissionLocked(permName);
4156 }
4157 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08004158
4159 @Override
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07004160 public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
4161 @PermissionInfo.Protection int protectionLevel) {
4162 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
4163
4164 synchronized (PermissionManagerService.this.mLock) {
4165 int numTotalPermissions = mSettings.mPermissions.size();
4166
4167 for (int i = 0; i < numTotalPermissions; i++) {
4168 BasePermission bp = mSettings.mPermissions.valueAt(i);
4169
4170 if (bp.perm != null && bp.perm.info != null
4171 && bp.protectionLevel == protectionLevel) {
4172 matchingPermissions.add(bp.perm.info);
4173 }
4174 }
4175 }
4176
4177 return matchingPermissions;
4178 }
4179
4180 @Override
Philip P. Moltmann48456672019-01-20 13:14:03 -08004181 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
4182 return PermissionManagerService.this.backupRuntimePermissions(user);
4183 }
4184
4185 @Override
4186 public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
4187 PermissionManagerService.this.restoreRuntimePermissions(backup, user);
4188 }
4189
4190 @Override
4191 public void restoreDelayedRuntimePermissions(@NonNull String packageName,
4192 @NonNull UserHandle user) {
4193 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
4194 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004195
4196 @Override
4197 public void addOnRuntimePermissionStateChangedListener(
4198 OnRuntimePermissionStateChangedListener listener) {
4199 PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
4200 listener);
4201 }
4202
4203 @Override
4204 public void removeOnRuntimePermissionStateChangedListener(
4205 OnRuntimePermissionStateChangedListener listener) {
4206 PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
4207 listener);
4208 }
Todd Kennedyca1ea172019-07-03 15:02:28 -07004209
4210 @Override
4211 public CheckPermissionDelegate getCheckPermissionDelegate() {
4212 synchronized (mLock) {
4213 return mCheckPermissionDelegate;
4214 }
4215 }
4216
4217 @Override
4218 public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
4219 synchronized (mLock) {
4220 mCheckPermissionDelegate = delegate;
4221 }
4222 }
Todd Kennedy583378d2019-07-12 06:50:30 -07004223
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004224 @Override
Todd Kennedy583378d2019-07-12 06:50:30 -07004225 public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
4226 synchronized (mLock) {
4227 mDefaultBrowserProvider = provider;
4228 }
4229 }
4230
4231 @Override
4232 public void setDefaultBrowser(String packageName, boolean async, boolean doGrant,
4233 int userId) {
4234 setDefaultBrowserInternal(packageName, async, doGrant, userId);
4235 }
4236
4237 @Override
4238 public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
4239 synchronized (mLock) {
4240 mDefaultDialerProvider = provider;
4241 }
4242 }
4243
4244 @Override
4245 public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
4246 synchronized (mLock) {
4247 mDefaultHomeProvider = provider;
4248 }
4249 }
4250
4251 @Override
4252 public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) {
4253 synchronized (mLock) {
4254 if (userId == UserHandle.USER_ALL) {
4255 return;
4256 }
4257 if (mDefaultHomeProvider == null) {
4258 return;
4259 }
4260 mDefaultHomeProvider.setDefaultHomeAsync(packageName, userId, callback);
4261 }
4262 }
4263
4264 @Override
4265 public void setDialerAppPackagesProvider(PackagesProvider provider) {
4266 synchronized (mLock) {
4267 mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
4268 }
4269 }
4270
4271 @Override
4272 public void setLocationExtraPackagesProvider(PackagesProvider provider) {
4273 synchronized (mLock) {
4274 mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
4275 }
4276 }
4277
4278 @Override
4279 public void setLocationPackagesProvider(PackagesProvider provider) {
4280 synchronized (mLock) {
4281 mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
4282 }
4283 }
4284
4285 @Override
4286 public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
4287 synchronized (mLock) {
4288 mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
4289 }
4290 }
4291
4292 @Override
4293 public void setSmsAppPackagesProvider(PackagesProvider provider) {
4294 synchronized (mLock) {
4295 mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
4296 }
4297 }
4298
4299 @Override
4300 public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
4301 synchronized (mLock) {
4302 mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
4303 }
4304 }
4305
4306 @Override
4307 public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
4308 synchronized (mLock) {
4309 mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
4310 }
4311 }
4312
4313 @Override
4314 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
4315 synchronized (mLock) {
4316 mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
4317 }
4318 }
4319
4320 @Override
4321 public String getDefaultBrowser(int userId) {
4322 synchronized (mLock) {
4323 return mDefaultBrowserProvider == null
4324 ? null : mDefaultBrowserProvider.getDefaultBrowser(userId);
4325 }
4326 }
4327
4328 @Override
4329 public String getDefaultDialer(int userId) {
4330 synchronized (mLock) {
4331 return mDefaultDialerProvider == null
4332 ? null : mDefaultDialerProvider.getDefaultDialer(userId);
4333 }
4334 }
4335
4336 @Override
4337 public String getDefaultHome(int userId) {
4338 synchronized (mLock) {
4339 return mDefaultHomeProvider == null
4340 ? null : mDefaultHomeProvider.getDefaultHome(userId);
4341 }
4342 }
4343
4344 @Override
4345 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
4346 synchronized (mLock) {
4347 mDefaultPermissionGrantPolicy
4348 .grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
4349 }
4350 }
4351
4352 @Override
4353 public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
4354 synchronized (mLock) {
4355 mDefaultPermissionGrantPolicy
4356 .grantDefaultPermissionsToDefaultUseOpenWifiApp(packageName, userId);
4357 }
4358 }
4359
4360 @Override
4361 public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
4362 synchronized (mLock) {
4363 mDefaultPermissionGrantPolicy
4364 .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
4365 }
4366 }
4367
4368 @Override
4369 public boolean wereDefaultPermissionsGrantedSinceBoot(int userId) {
4370 synchronized (mLock) {
4371 return mDefaultPermissionGrantPolicy.wereDefaultPermissionsGrantedSinceBoot(userId);
4372 }
4373 }
4374
4375 @Override
4376 public void onNewUserCreated(int userId) {
4377 synchronized (mLock) {
4378 mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
4379 // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
4380 PermissionManagerService.this.updateAllPermissions(
4381 StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
4382 }
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004383 }
4384 }
4385
4386 private static final class OnPermissionChangeListeners extends Handler {
4387 private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
4388
4389 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
4390 new RemoteCallbackList<>();
4391
4392 OnPermissionChangeListeners(Looper looper) {
4393 super(looper);
4394 }
4395
4396 @Override
4397 public void handleMessage(Message msg) {
4398 switch (msg.what) {
4399 case MSG_ON_PERMISSIONS_CHANGED: {
4400 final int uid = msg.arg1;
4401 handleOnPermissionsChanged(uid);
4402 } break;
4403 }
4404 }
4405
4406 public void addListenerLocked(IOnPermissionsChangeListener listener) {
4407 mPermissionListeners.register(listener);
4408
4409 }
4410
4411 public void removeListenerLocked(IOnPermissionsChangeListener listener) {
4412 mPermissionListeners.unregister(listener);
4413 }
4414
4415 public void onPermissionsChanged(int uid) {
4416 if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
4417 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
4418 }
4419 }
4420
4421 private void handleOnPermissionsChanged(int uid) {
4422 final int count = mPermissionListeners.beginBroadcast();
4423 try {
4424 for (int i = 0; i < count; i++) {
4425 IOnPermissionsChangeListener callback = mPermissionListeners
4426 .getBroadcastItem(i);
4427 try {
4428 callback.onPermissionsChanged(uid);
4429 } catch (RemoteException e) {
4430 Log.e(TAG, "Permission listener is dead", e);
4431 }
4432 }
4433 } finally {
4434 mPermissionListeners.finishBroadcast();
4435 }
4436 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07004437 }
4438}