blob: ccc749232dc3d602946a7419b2460ed5aab98e33 [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;
Eugene Susla922cd082020-03-11 12:38:17 -070022import static android.app.AppOpsManager.MODE_ALLOWED;
23import static android.app.AppOpsManager.MODE_IGNORED;
Eugene Susla49b84c32020-03-23 15:19:29 -070024import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISALLOWED;
25import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISCOURAGED;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070026import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
27import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070028import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
29import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
Todd Kennedy3bc94722017-10-10 09:55:53 -070030import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Hai Zhang50a5a9b2019-09-19 13:57:45 -070031import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070032import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070036import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
Philip P. Moltmannba742062019-04-08 13:22:44 -070039import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
Todd Kennedyc5b0e862019-07-16 09:47:58 -070040import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
Hongwei Wangf391b552018-04-06 13:52:46 -070041import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Todd Kennedyc971a452019-07-08 16:04:52 -070042import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070043import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
Hongwei Wangf391b552018-04-06 13:52:46 -070044
Philip P. Moltmannbd278012020-03-10 14:46:27 -070045import static com.android.server.pm.ApexManager.MATCH_ACTIVE_PACKAGE;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070046import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
47import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
48import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
49import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
50import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Philip P. Moltmann48456672019-01-20 13:14:03 -080051import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
52
53import static java.util.concurrent.TimeUnit.SECONDS;
Todd Kennedy0eb97382017-10-03 16:57:22 -070054
55import android.Manifest;
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -070056import android.annotation.IntDef;
Todd Kennedy0eb97382017-10-03 16:57:22 -070057import android.annotation.NonNull;
58import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070059import android.annotation.UserIdInt;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070060import android.app.ActivityManager;
Eugene Susla922cd082020-03-11 12:38:17 -070061import android.app.AppOpsManager;
Eugene Suslad516bee2019-05-01 09:48:43 -070062import android.app.ApplicationPackageManager;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070063import android.app.IActivityManager;
wayneyang8126b1f2020-01-09 14:10:31 +080064import android.app.admin.DeviceAdminInfo;
Michael Groover56a84b22020-03-04 20:41:36 -080065import android.app.admin.DevicePolicyManager;
wayneyang8126b1f2020-01-09 14:10:31 +080066import android.app.admin.DevicePolicyManagerInternal;
Evan Severson50a77742020-01-06 10:38:19 -080067import android.compat.annotation.ChangeId;
68import android.compat.annotation.EnabledAfter;
Todd Kennedy0eb97382017-10-03 16:57:22 -070069import android.content.Context;
kholoud mohamed79a89f02020-01-15 15:30:07 +000070import android.content.PermissionChecker;
Hongming Jinbc4d0102019-08-16 14:28:30 -070071import android.content.pm.ApplicationInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070072import android.content.pm.PackageManager;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070073import android.content.pm.PackageManager.PermissionGroupInfoFlags;
74import android.content.pm.PackageManager.PermissionInfoFlags;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070075import android.content.pm.PackageManager.PermissionWhitelistFlags;
Todd Kennedy0eb97382017-10-03 16:57:22 -070076import android.content.pm.PackageManagerInternal;
77import android.content.pm.PackageParser;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070078import android.content.pm.ParceledListSlice;
Todd Kennedy460f28c2017-10-06 13:46:22 -070079import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070080import android.content.pm.PermissionInfo;
Winsonf00c7552020-01-28 12:52:01 -080081import android.content.pm.parsing.component.ParsedPermission;
82import android.content.pm.parsing.component.ParsedPermissionGroup;
Anthony Hughde787d42019-08-22 15:35:48 -070083import android.content.pm.permission.SplitPermissionInfoParcelable;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070084import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070085import android.os.Binder;
86import android.os.Build;
87import android.os.Handler;
88import android.os.HandlerThread;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070089import android.os.Looper;
90import android.os.Message;
Todd Kennedy0eb97382017-10-03 16:57:22 -070091import android.os.Process;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070092import android.os.RemoteCallbackList;
93import android.os.RemoteException;
Todd Kennedy8f135982019-07-02 07:35:15 -070094import android.os.ServiceManager;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070095import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070096import android.os.UserHandle;
97import android.os.UserManager;
98import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070099import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700100import android.os.storage.StorageManagerInternal;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700101import android.permission.IOnPermissionsChangeListener;
Todd Kennedy8f135982019-07-02 07:35:15 -0700102import android.permission.IPermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800103import android.permission.PermissionControllerManager;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -0700104import android.permission.PermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800105import android.permission.PermissionManagerInternal;
Todd Kennedyca1ea172019-07-03 15:02:28 -0700106import android.permission.PermissionManagerInternal.CheckPermissionDelegate;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700107import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700108import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700109import android.util.ArrayMap;
110import android.util.ArraySet;
Eugene Suslad516bee2019-05-01 09:48:43 -0700111import android.util.DebugUtils;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700112import android.util.EventLog;
Todd Kennedyc971a452019-07-08 16:04:52 -0700113import android.util.IntArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700114import android.util.Log;
115import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700116import android.util.SparseArray;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800117import android.util.SparseBooleanArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700118
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700119import com.android.internal.annotations.GuardedBy;
Michael Groover56a84b22020-03-04 20:41:36 -0800120import com.android.internal.annotations.VisibleForTesting;
Evan Severson50a77742020-01-06 10:38:19 -0800121import com.android.internal.compat.IPlatformCompat;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700122import com.android.internal.logging.MetricsLogger;
123import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700124import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700125import com.android.internal.util.ArrayUtils;
Todd Kennedyc971a452019-07-08 16:04:52 -0700126import com.android.internal.util.IntPair;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700127import com.android.internal.util.Preconditions;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700128import com.android.internal.util.function.pooled.PooledLambda;
129import com.android.server.FgThread;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700130import com.android.server.LocalServices;
131import com.android.server.ServiceThread;
132import com.android.server.SystemConfig;
133import com.android.server.Watchdog;
Philip P. Moltmannbd278012020-03-10 14:46:27 -0700134import com.android.server.pm.ApexManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700135import com.android.server.pm.PackageManagerServiceUtils;
136import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700137import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700138import com.android.server.pm.UserManagerService;
Winson5e0a1d52020-01-24 12:00:33 -0800139import com.android.server.pm.parsing.PackageInfoUtils;
Winsonf00c7552020-01-28 12:52:01 -0800140import com.android.server.pm.parsing.pkg.AndroidPackage;
Todd Kennedy583378d2019-07-12 06:50:30 -0700141import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider;
142import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider;
143import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800144import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700145import com.android.server.pm.permission.PermissionsState.PermissionState;
Svet Ganov3c499ea2019-07-26 17:45:56 -0700146import com.android.server.policy.PermissionPolicyInternal;
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -0700147import com.android.server.policy.SoftRestrictedPermissionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700148
149import libcore.util.EmptyArray;
150
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -0700151import java.lang.annotation.Retention;
152import java.lang.annotation.RetentionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700153import java.util.ArrayList;
Hongwei Wangf391b552018-04-06 13:52:46 -0700154import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700155import java.util.Iterator;
156import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700157import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700158import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700159import java.util.Set;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800160import java.util.concurrent.CompletableFuture;
161import java.util.concurrent.ExecutionException;
162import java.util.concurrent.TimeUnit;
163import java.util.concurrent.TimeoutException;
Todd Kennedy230c0a72019-07-03 13:06:35 -0700164import java.util.function.Consumer;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700165
166/**
167 * Manages all permissions and handles permissions related tasks.
168 */
Todd Kennedy8f135982019-07-02 07:35:15 -0700169public class PermissionManagerService extends IPermissionManager.Stub {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700170 private static final String TAG = "PackageManager";
171
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700172 /** Permission grant: not grant the permission. */
173 private static final int GRANT_DENIED = 1;
174 /** Permission grant: grant the permission as an install permission. */
175 private static final int GRANT_INSTALL = 2;
176 /** Permission grant: grant the permission as a runtime one. */
177 private static final int GRANT_RUNTIME = 3;
178 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
179 private static final int GRANT_UPGRADE = 4;
180
Philip P. Moltmann48456672019-01-20 13:14:03 -0800181 private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
182
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700183 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
184 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
185 /** Empty array to avoid allocations */
186 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700187
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -0800188 /**
189 * When these flags are set, the system should not automatically modify the permission grant
190 * state.
191 */
192 private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
193 | FLAG_PERMISSION_POLICY_FIXED
194 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
195
196 /** Permission flags set by the user */
197 private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
198 | FLAG_PERMISSION_USER_FIXED;
199
Hongwei Wangf391b552018-04-06 13:52:46 -0700200 /** If the permission of the value is granted, so is the key */
201 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
202
203 static {
204 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
205 Manifest.permission.ACCESS_FINE_LOCATION);
206 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
207 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
208 }
209
Todd Kennedy0eb97382017-10-03 16:57:22 -0700210 /** Lock to protect internal data access */
211 private final Object mLock;
212
213 /** Internal connection to the package manager */
214 private final PackageManagerInternal mPackageManagerInt;
215
216 /** Internal connection to the user manager */
217 private final UserManagerInternal mUserManagerInt;
218
Philip P. Moltmann48456672019-01-20 13:14:03 -0800219 /** Permission controller: User space permission management */
220 private PermissionControllerManager mPermissionControllerManager;
221
Evan Seversonb252d8b2019-11-20 08:41:33 -0800222 /** Map of OneTimePermissionUserManagers keyed by userId */
223 private final SparseArray<OneTimePermissionUserManager> mOneTimePermissionUserManagers =
224 new SparseArray<>();
225
Todd Kennedy0eb97382017-10-03 16:57:22 -0700226 /** Default permission policy to provide proper behaviour out-of-the-box */
227 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
228
Eugene Susla922cd082020-03-11 12:38:17 -0700229 /** App ops manager */
230 private final AppOpsManager mAppOpsManager;
231
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700232 /**
233 * Built-in permissions. Read from system configuration files. Mapping is from
234 * UID to permission name.
235 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700236 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700237
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700238 /** Built-in group IDs given to all packages. Read from system configuration files. */
239 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700240
241 private final HandlerThread mHandlerThread;
242 private final Handler mHandler;
243 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700244 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Evan Severson50a77742020-01-06 10:38:19 -0800245 private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
246 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
Todd Kennedy0eb97382017-10-03 16:57:22 -0700247
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700248 /** Internal storage for permissions and related settings */
249 @GuardedBy("mLock")
250 private final PermissionSettings mSettings;
251
Michael Groover56a84b22020-03-04 20:41:36 -0800252 /** Injector that can be used to facilitate testing. */
253 private final Injector mInjector;
254
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700255 @GuardedBy("mLock")
256 private ArraySet<String> mPrivappPermissionsViolations;
257
258 @GuardedBy("mLock")
259 private boolean mSystemReady;
260
Svet Ganov3c499ea2019-07-26 17:45:56 -0700261 @GuardedBy("mLock")
262 private PermissionPolicyInternal mPermissionPolicyInternal;
263
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700264 /**
265 * For each foreground/background permission the mapping:
266 * Background permission -> foreground permissions
267 */
268 @GuardedBy("mLock")
269 private ArrayMap<String, List<String>> mBackgroundPermissions;
270
Philip P. Moltmann48456672019-01-20 13:14:03 -0800271 /**
272 * A permission backup might contain apps that are not installed. In this case we delay the
273 * restoration until the app is installed.
274 *
275 * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
276 * there is <u>no more</u> delayed backup left.
277 */
278 @GuardedBy("mLock")
279 private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
280
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700281 /** Listeners for permission state (granting and flags) changes */
282 @GuardedBy("mLock")
283 final private ArrayList<OnRuntimePermissionStateChangedListener>
284 mRuntimePermissionStateChangedListeners = new ArrayList<>();
285
Todd Kennedyca1ea172019-07-03 15:02:28 -0700286 @GuardedBy("mLock")
287 private CheckPermissionDelegate mCheckPermissionDelegate;
288
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700289 @GuardedBy("mLock")
290 private final OnPermissionChangeListeners mOnPermissionChangeListeners;
291
Todd Kennedy583378d2019-07-12 06:50:30 -0700292 @GuardedBy("mLock")
293 private DefaultBrowserProvider mDefaultBrowserProvider;
294
295 @GuardedBy("mLock")
296 private DefaultDialerProvider mDefaultDialerProvider;
297
298 @GuardedBy("mLock")
299 private DefaultHomeProvider mDefaultHomeProvider;
300
Todd Kennedy230c0a72019-07-03 13:06:35 -0700301 // TODO: Take a look at the methods defined in the callback.
302 // The callback was initially created to support the split between permission
303 // manager and the package manager. However, it's started to be used for other
304 // purposes. It may make sense to keep as an abstraction, but, the methods
305 // necessary to be overridden may be different than what was initially needed
306 // for the split.
307 private PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
308 @Override
309 public void onGidsChanged(int appId, int userId) {
Todd Kennedyc971a452019-07-08 16:04:52 -0700310 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
Todd Kennedy230c0a72019-07-03 13:06:35 -0700311 }
312 @Override
313 public void onPermissionGranted(int uid, int userId) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700314 mOnPermissionChangeListeners.onPermissionsChanged(uid);
315
316 // Not critical; if this is lost, the application has to request again.
317 mPackageManagerInt.writeSettings(true);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700318 }
319 @Override
320 public void onInstallPermissionGranted() {
321 mPackageManagerInt.writeSettings(true);
322 }
323 @Override
324 public void onPermissionRevoked(int uid, int userId) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700325 mOnPermissionChangeListeners.onPermissionsChanged(uid);
326
327 // Critical; after this call the application should never have the permission
328 mPackageManagerInt.writeSettings(false);
329 final int appId = UserHandle.getAppId(uid);
Philip P. Moltmannd3c37422019-10-11 14:59:33 -0700330 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED));
Todd Kennedy230c0a72019-07-03 13:06:35 -0700331 }
332 @Override
333 public void onInstallPermissionRevoked() {
334 mPackageManagerInt.writeSettings(true);
335 }
336 @Override
337 public void onPermissionUpdated(int[] userIds, boolean sync) {
338 mPackageManagerInt.writePermissionSettings(userIds, !sync);
339 }
340 @Override
341 public void onInstallPermissionUpdated() {
342 mPackageManagerInt.writeSettings(true);
343 }
344 @Override
345 public void onPermissionRemoved() {
346 mPackageManagerInt.writeSettings(false);
347 }
348 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync,
349 int uid) {
350 onPermissionUpdated(updatedUserIds, sync);
Nate Myren3fb13a12019-12-11 12:30:39 -0800351 for (int i = 0; i < updatedUserIds.length; i++) {
352 int userUid = UserHandle.getUid(updatedUserIds[i], UserHandle.getAppId(uid));
353 mOnPermissionChangeListeners.onPermissionsChanged(userUid);
354 }
Todd Kennedy230c0a72019-07-03 13:06:35 -0700355 }
356 public void onInstallPermissionUpdatedNotifyListener(int uid) {
357 onInstallPermissionUpdated();
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700358 mOnPermissionChangeListeners.onPermissionsChanged(uid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700359 }
360 };
361
Todd Kennedy0eb97382017-10-03 16:57:22 -0700362 PermissionManagerService(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700363 @NonNull Object externalLock) {
Michael Groover56a84b22020-03-04 20:41:36 -0800364 this(context, externalLock, new Injector(context));
365 }
366
367 @VisibleForTesting
368 PermissionManagerService(Context context, @NonNull Object externalLock,
369 @NonNull Injector injector) {
370 mInjector = injector;
Daniel Colascionea46b7b32020-01-24 13:30:25 -0800371 // The package info cache is the cache for package and permission information.
Michael Groover56a84b22020-03-04 20:41:36 -0800372 mInjector.invalidatePackageInfoCache();
373 mInjector.disablePermissionCache();
374 mInjector.disablePackageNamePermissionCache();
Daniel Colascionea46b7b32020-01-24 13:30:25 -0800375
Todd Kennedy0eb97382017-10-03 16:57:22 -0700376 mContext = context;
377 mLock = externalLock;
378 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
379 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700380 mSettings = new PermissionSettings(mLock);
Eugene Susla922cd082020-03-11 12:38:17 -0700381 mAppOpsManager = context.getSystemService(AppOpsManager.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700382
383 mHandlerThread = new ServiceThread(TAG,
384 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
385 mHandlerThread.start();
386 mHandler = new Handler(mHandlerThread.getLooper());
387 Watchdog.getInstance().addThread(mHandler);
388
389 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700390 context, mHandlerThread.getLooper(), this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700391 SystemConfig systemConfig = SystemConfig.getInstance();
392 mSystemPermissions = systemConfig.getSystemPermissions();
393 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700394 mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());
Todd Kennedy0eb97382017-10-03 16:57:22 -0700395
396 // propagate permission configuration
397 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
398 SystemConfig.getInstance().getPermissions();
399 synchronized (mLock) {
400 for (int i=0; i<permConfig.size(); i++) {
401 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
402 BasePermission bp = mSettings.getPermissionLocked(perm.name);
403 if (bp == null) {
404 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
405 mSettings.putPermissionLocked(perm.name, bp);
406 }
407 if (perm.gids != null) {
408 bp.setGids(perm.gids, perm.perUser);
409 }
410 }
411 }
412
Philip P. Moltmann48456672019-01-20 13:14:03 -0800413 PermissionManagerServiceInternalImpl localService =
414 new PermissionManagerServiceInternalImpl();
415 LocalServices.addService(PermissionManagerServiceInternal.class, localService);
416 LocalServices.addService(PermissionManagerInternal.class, localService);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700417 }
418
419 /**
420 * Creates and returns an initialized, internal service for use by other components.
421 * <p>
422 * The object returned is identical to the one returned by the LocalServices class using:
Philip P. Moltmann48456672019-01-20 13:14:03 -0800423 * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
Todd Kennedy0eb97382017-10-03 16:57:22 -0700424 * <p>
425 * NOTE: The external lock is temporary and should be removed. This needs to be a
426 * lock created by the permission manager itself.
427 */
Philip P. Moltmann48456672019-01-20 13:14:03 -0800428 public static PermissionManagerServiceInternal create(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700429 @NonNull Object externalLock) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800430 final PermissionManagerServiceInternal permMgrInt =
431 LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700432 if (permMgrInt != null) {
433 return permMgrInt;
434 }
Todd Kennedy8f135982019-07-02 07:35:15 -0700435 PermissionManagerService permissionService =
436 (PermissionManagerService) ServiceManager.getService("permissionmgr");
437 if (permissionService == null) {
438 permissionService =
439 new PermissionManagerService(context, externalLock);
440 ServiceManager.addService("permissionmgr", permissionService);
441 }
Philip P. Moltmann48456672019-01-20 13:14:03 -0800442 return LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700443 }
444
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700445 /**
446 * This method should typically only be used when granting or revoking
447 * permissions, since the app may immediately restart after this call.
448 * <p>
449 * If you're doing surgery on app code/data, use {@link PackageFreezer} to
450 * guard your work against the app being relaunched.
451 */
452 public static void killUid(int appId, int userId, String reason) {
453 final long identity = Binder.clearCallingIdentity();
454 try {
455 IActivityManager am = ActivityManager.getService();
456 if (am != null) {
457 try {
458 am.killUid(appId, userId, reason);
459 } catch (RemoteException e) {
460 /* ignore - same process */
461 }
462 }
463 } finally {
464 Binder.restoreCallingIdentity(identity);
465 }
466 }
467
Winson14ff7172019-10-23 10:42:27 -0700468 @Nullable
469 BasePermission getPermission(String permName) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700470 synchronized (mLock) {
471 return mSettings.getPermissionLocked(permName);
472 }
473 }
474
Todd Kennedy8f135982019-07-02 07:35:15 -0700475 @Override
476 public String[] getAppOpPermissionPackages(String permName) {
477 return getAppOpPermissionPackagesInternal(permName, getCallingUid());
478 }
479
480 private String[] getAppOpPermissionPackagesInternal(String permName, int callingUid) {
481 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
482 return null;
483 }
484 synchronized (mLock) {
485 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
486 if (pkgs == null) {
487 return null;
488 }
489 return pkgs.toArray(new String[pkgs.size()]);
490 }
491 }
492
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700493 @Override
494 @NonNull
495 public ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(
496 @PermissionGroupInfoFlags int flags) {
497 final int callingUid = getCallingUid();
498 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
499 return ParceledListSlice.emptyList();
500 }
501 synchronized (mLock) {
502 final int n = mSettings.mPermissionGroups.size();
Winson14ff7172019-10-23 10:42:27 -0700503 final ArrayList<PermissionGroupInfo> out = new ArrayList<>(n);
504 for (ParsedPermissionGroup pg : mSettings.mPermissionGroups.values()) {
505 out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags));
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700506 }
507 return new ParceledListSlice<>(out);
508 }
509 }
510
511
512 @Override
513 @Nullable
514 public PermissionGroupInfo getPermissionGroupInfo(String groupName,
515 @PermissionGroupInfoFlags int flags) {
516 final int callingUid = getCallingUid();
517 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
518 return null;
519 }
520 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -0700521 return PackageInfoUtils.generatePermissionGroupInfo(
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700522 mSettings.mPermissionGroups.get(groupName), flags);
523 }
524 }
525
526
527 @Override
528 @Nullable
529 public PermissionInfo getPermissionInfo(String permName, String packageName,
530 @PermissionInfoFlags int flags) {
531 final int callingUid = getCallingUid();
532 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
533 return null;
534 }
535 synchronized (mLock) {
536 final BasePermission bp = mSettings.getPermissionLocked(permName);
537 if (bp == null) {
538 return null;
539 }
540 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
541 bp.getProtectionLevel(), packageName, callingUid);
542 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
543 }
544 }
545
546 @Override
547 @Nullable
548 public ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
549 @PermissionInfoFlags int flags) {
550 final int callingUid = getCallingUid();
551 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
552 return null;
553 }
554 synchronized (mLock) {
555 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
556 return null;
557 }
558 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
559 for (BasePermission bp : mSettings.mPermissions.values()) {
560 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
561 if (pi != null) {
562 out.add(pi);
563 }
564 }
565 return new ParceledListSlice<>(out);
566 }
567 }
568
Todd Kennedy6ffc5a62019-07-03 09:35:31 -0700569 @Override
570 public boolean addPermission(PermissionInfo info, boolean async) {
571 final int callingUid = getCallingUid();
572 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
573 throw new SecurityException("Instant apps can't add permissions");
574 }
575 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
576 throw new SecurityException("Label must be specified in permission");
577 }
578 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
579 final boolean added;
580 final boolean changed;
581 synchronized (mLock) {
582 BasePermission bp = mSettings.getPermissionLocked(info.name);
583 added = bp == null;
584 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
585 if (added) {
586 enforcePermissionCapLocked(info, tree);
587 bp = new BasePermission(info.name, tree.getSourcePackageName(),
588 BasePermission.TYPE_DYNAMIC);
589 } else if (!bp.isDynamic()) {
590 throw new SecurityException("Not allowed to modify non-dynamic permission "
591 + info.name);
592 }
593 changed = bp.addToTree(fixedLevel, info, tree);
594 if (added) {
595 mSettings.putPermissionLocked(info.name, bp);
596 }
597 }
598 if (changed) {
599 mPackageManagerInt.writeSettings(async);
600 }
601 return added;
602 }
603
604 @Override
605 public void removePermission(String permName) {
606 final int callingUid = getCallingUid();
607 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
608 throw new SecurityException("Instant applications don't have access to this method");
609 }
610 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
611 synchronized (mLock) {
612 final BasePermission bp = mSettings.getPermissionLocked(permName);
613 if (bp == null) {
614 return;
615 }
616 if (bp.isDynamic()) {
617 // TODO: switch this back to SecurityException
618 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
619 + permName);
620 }
621 mSettings.removePermissionLocked(permName);
622 mPackageManagerInt.writeSettings(false);
623 }
624 }
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700625
Todd Kennedy230c0a72019-07-03 13:06:35 -0700626 @Override
627 public int getPermissionFlags(String permName, String packageName, int userId) {
628 final int callingUid = getCallingUid();
629 return getPermissionFlagsInternal(permName, packageName, callingUid, userId);
630 }
631
632 private int getPermissionFlagsInternal(
633 String permName, String packageName, int callingUid, int userId) {
634 if (!mUserManagerInt.exists(userId)) {
635 return 0;
636 }
637
638 enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
639 enforceCrossUserPermission(callingUid, userId,
640 true, // requireFullPermission
641 false, // checkShell
642 false, // requirePermissionWhenSameUser
643 "getPermissionFlags");
644
Winson14ff7172019-10-23 10:42:27 -0700645 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
646 if (pkg == null) {
647 return 0;
648 }
649 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
650 pkg.getPackageName());
651 if (ps == null) {
Todd Kennedy230c0a72019-07-03 13:06:35 -0700652 return 0;
653 }
654 synchronized (mLock) {
655 if (mSettings.getPermissionLocked(permName) == null) {
656 return 0;
657 }
658 }
659 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
660 return 0;
661 }
Todd Kennedy230c0a72019-07-03 13:06:35 -0700662 PermissionsState permissionsState = ps.getPermissionsState();
663 return permissionsState.getPermissionFlags(permName, userId);
664 }
665
666 @Override
667 public void updatePermissionFlags(String permName, String packageName, int flagMask,
668 int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) {
669 final int callingUid = getCallingUid();
670 boolean overridePolicy = false;
671
672 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
673 long callingIdentity = Binder.clearCallingIdentity();
674 try {
675 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
676 if (checkAdjustPolicyFlagPermission) {
677 mContext.enforceCallingOrSelfPermission(
678 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
679 "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
680 + " to change policy flags");
Hai Zhang053c3a22019-08-23 15:08:03 -0700681 } else if (mPackageManagerInt.getUidTargetSdkVersion(callingUid)
Todd Kennedy230c0a72019-07-03 13:06:35 -0700682 >= Build.VERSION_CODES.Q) {
683 throw new IllegalArgumentException(
684 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
685 + " to be checked for packages targeting "
686 + Build.VERSION_CODES.Q + " or later when changing policy "
687 + "flags");
688 }
689 overridePolicy = true;
690 }
691 } finally {
692 Binder.restoreCallingIdentity(callingIdentity);
693 }
694 }
695
696 updatePermissionFlagsInternal(
697 permName, packageName, flagMask, flagValues, callingUid, userId,
698 overridePolicy, mDefaultPermissionCallback);
699 }
700
701 private void updatePermissionFlagsInternal(String permName, String packageName, int flagMask,
702 int flagValues, int callingUid, int userId, boolean overridePolicy,
703 PermissionCallback callback) {
Eugene Suslacb923e32019-08-20 16:48:55 -0700704 if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
Todd Kennedy230c0a72019-07-03 13:06:35 -0700705 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -0700706 Log.i(TAG, "System is updating flags for " + packageName + " "
Todd Kennedy230c0a72019-07-03 13:06:35 -0700707 + permName + " for user " + userId + " "
708 + DebugUtils.flagsToString(
709 PackageManager.class, "FLAG_PERMISSION_", flagMask)
710 + " := "
711 + DebugUtils.flagsToString(
712 PackageManager.class, "FLAG_PERMISSION_", flagValues)
713 + " on behalf of uid " + callingUid
714 + " " + mPackageManagerInt.getNameForUid(callingUid),
715 new RuntimeException());
716 }
717
718 if (!mUserManagerInt.exists(userId)) {
719 return;
720 }
721
722 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
723
724 enforceCrossUserPermission(callingUid, userId,
725 true, // requireFullPermission
726 true, // checkShell
727 false, // requirePermissionWhenSameUser
728 "updatePermissionFlags");
729
730 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
731 throw new SecurityException("updatePermissionFlags requires "
732 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
733 }
734
735 // Only the system can change these flags and nothing else.
736 if (callingUid != Process.SYSTEM_UID) {
737 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
738 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
739 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
740 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
741 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
742 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
743 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
744 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
745 flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
746 }
747
Winson14ff7172019-10-23 10:42:27 -0700748 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
749 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
750 packageName);
751 if (pkg == null || ps == null) {
Todd Kennedy230c0a72019-07-03 13:06:35 -0700752 Log.e(TAG, "Unknown package: " + packageName);
753 return;
754 }
755 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
756 throw new IllegalArgumentException("Unknown package: " + packageName);
757 }
758
759 final BasePermission bp;
760 synchronized (mLock) {
761 bp = mSettings.getPermissionLocked(permName);
762 }
763 if (bp == null) {
764 throw new IllegalArgumentException("Unknown permission: " + permName);
765 }
766
Todd Kennedy230c0a72019-07-03 13:06:35 -0700767 final PermissionsState permissionsState = ps.getPermissionsState();
768 final boolean hadState =
769 permissionsState.getRuntimePermissionState(permName, userId) != null;
770 final boolean permissionUpdated =
771 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
772 if (permissionUpdated && bp.isRuntime()) {
773 notifyRuntimePermissionStateChanged(packageName, userId);
774 }
775 if (permissionUpdated && callback != null) {
776 // Install and runtime permissions are stored in different places,
777 // so figure out what permission changed and persist the change.
778 if (permissionsState.getInstallPermissionState(permName) != null) {
Nate Myren3fb13a12019-12-11 12:30:39 -0800779 int userUid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
780 callback.onInstallPermissionUpdatedNotifyListener(userUid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700781 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
782 || hadState) {
Winson14ff7172019-10-23 10:42:27 -0700783 callback.onPermissionUpdatedNotifyListener(new int[]{userId}, false,
784 pkg.getUid());
Todd Kennedy230c0a72019-07-03 13:06:35 -0700785 }
786 }
787 }
788
789 /**
790 * Update the permission flags for all packages and runtime permissions of a user in order
791 * to allow device or profile owner to remove POLICY_FIXED.
792 */
793 @Override
794 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues,
795 final int userId) {
796 final int callingUid = getCallingUid();
797 if (!mUserManagerInt.exists(userId)) {
798 return;
799 }
800
801 enforceGrantRevokeRuntimePermissionPermissions(
802 "updatePermissionFlagsForAllApps");
803 enforceCrossUserPermission(callingUid, userId,
804 true, // requireFullPermission
805 true, // checkShell
806 false, // requirePermissionWhenSameUser
807 "updatePermissionFlagsForAllApps");
808
809 // Only the system can change system fixed flags.
810 final int effectiveFlagMask = (callingUid != Process.SYSTEM_UID)
811 ? flagMask : flagMask & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
812 final int effectiveFlagValues = (callingUid != Process.SYSTEM_UID)
813 ? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
814
815 final boolean[] changed = new boolean[1];
Winson14ff7172019-10-23 10:42:27 -0700816 mPackageManagerInt.forEachPackage(pkg -> {
817 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
818 pkg.getPackageName());
819 if (ps == null) {
820 return;
Todd Kennedy230c0a72019-07-03 13:06:35 -0700821 }
Winson14ff7172019-10-23 10:42:27 -0700822 final PermissionsState permissionsState = ps.getPermissionsState();
823 changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions(
824 userId, effectiveFlagMask, effectiveFlagValues);
825 mOnPermissionChangeListeners.onPermissionsChanged(pkg.getUid());
Todd Kennedy230c0a72019-07-03 13:06:35 -0700826 });
827
828 if (changed[0]) {
829 mPackageManagerInt.writePermissionSettings(new int[] { userId }, true);
830 }
831 }
832
Todd Kennedyca1ea172019-07-03 15:02:28 -0700833 @Override
834 public int checkPermission(String permName, String pkgName, int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000835 // Not using Objects.requireNonNull() here for compatibility reasons.
Hai Zhang3b049a52019-08-16 15:37:46 -0700836 if (permName == null || pkgName == null) {
837 return PackageManager.PERMISSION_DENIED;
838 }
839 if (!mUserManagerInt.exists(userId)) {
840 return PackageManager.PERMISSION_DENIED;
841 }
842
Todd Kennedyca1ea172019-07-03 15:02:28 -0700843 final CheckPermissionDelegate checkPermissionDelegate;
844 synchronized (mLock) {
Todd Kennedyca1ea172019-07-03 15:02:28 -0700845 checkPermissionDelegate = mCheckPermissionDelegate;
846 }
Hai Zhang61b4d352019-10-07 13:45:26 -0700847 if (checkPermissionDelegate == null) {
848 return checkPermissionImpl(permName, pkgName, userId);
849 }
Todd Kennedyca1ea172019-07-03 15:02:28 -0700850 return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
Hai Zhang61b4d352019-10-07 13:45:26 -0700851 this::checkPermissionImpl);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700852 }
853
Hai Zhang4fef76a2019-09-28 00:03:50 +0000854 private int checkPermissionImpl(String permName, String pkgName, int userId) {
Winson655a5b92019-10-23 10:49:32 -0700855 final AndroidPackage pkg = mPackageManagerInt.getPackage(pkgName);
Hai Zhang3b049a52019-08-16 15:37:46 -0700856 if (pkg == null) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700857 return PackageManager.PERMISSION_DENIED;
858 }
Hai Zhang4fef76a2019-09-28 00:03:50 +0000859 return checkPermissionInternal(pkg, true, permName, userId);
Hai Zhang3b049a52019-08-16 15:37:46 -0700860 }
861
Winson655a5b92019-10-23 10:49:32 -0700862 private int checkPermissionInternal(@NonNull AndroidPackage pkg, boolean isPackageExplicit,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000863 @NonNull String permissionName, @UserIdInt int userId) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700864 final int callingUid = getCallingUid();
Winson14ff7172019-10-23 10:42:27 -0700865 if (isPackageExplicit || pkg.getSharedUserId() == null) {
Patrick Baumann97b9b532018-04-11 14:51:30 +0000866 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000867 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700868 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700869 } else {
870 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000871 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700872 }
873 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700874
Winson14ff7172019-10-23 10:42:27 -0700875 final int uid = UserHandle.getUid(userId, pkg.getUid());
876 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
877 pkg.getPackageName());
Hai Zhang3b049a52019-08-16 15:37:46 -0700878 if (ps == null) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000879 return PackageManager.PERMISSION_DENIED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700880 }
881 final PermissionsState permissionsState = ps.getPermissionsState();
882
Hai Zhang4fef76a2019-09-28 00:03:50 +0000883 if (checkSinglePermissionInternal(uid, permissionsState, permissionName)) {
884 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700885 }
886
887 final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000888 if (fullerPermissionName != null
889 && checkSinglePermissionInternal(uid, permissionsState, fullerPermissionName)) {
890 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700891 }
892
Hai Zhang4fef76a2019-09-28 00:03:50 +0000893 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700894 }
895
Hai Zhang3b049a52019-08-16 15:37:46 -0700896 private boolean checkSinglePermissionInternal(int uid,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000897 @NonNull PermissionsState permissionsState, @NonNull String permissionName) {
Hai Zhang61b4d352019-10-07 13:45:26 -0700898 if (!permissionsState.hasPermission(permissionName, UserHandle.getUserId(uid))) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700899 return false;
900 }
901
902 if (mPackageManagerInt.getInstantAppPackageName(uid) != null) {
903 return mSettings.isPermissionInstant(permissionName);
904 }
905
906 return true;
907 }
908
Todd Kennedyca1ea172019-07-03 15:02:28 -0700909 @Override
910 public int checkUidPermission(String permName, int uid) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000911 // Not using Objects.requireNonNull() here for compatibility reasons.
Hai Zhang3b049a52019-08-16 15:37:46 -0700912 if (permName == null) {
913 return PackageManager.PERMISSION_DENIED;
914 }
915 final int userId = UserHandle.getUserId(uid);
916 if (!mUserManagerInt.exists(userId)) {
917 return PackageManager.PERMISSION_DENIED;
918 }
919
Todd Kennedyca1ea172019-07-03 15:02:28 -0700920 final CheckPermissionDelegate checkPermissionDelegate;
921 synchronized (mLock) {
Todd Kennedyca1ea172019-07-03 15:02:28 -0700922 checkPermissionDelegate = mCheckPermissionDelegate;
923 }
Hai Zhang61b4d352019-10-07 13:45:26 -0700924 if (checkPermissionDelegate == null) {
925 return checkUidPermissionImpl(permName, uid);
926 }
Todd Kennedyca1ea172019-07-03 15:02:28 -0700927 return checkPermissionDelegate.checkUidPermission(permName, uid,
Hai Zhang61b4d352019-10-07 13:45:26 -0700928 this::checkUidPermissionImpl);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700929 }
930
Hai Zhang4fef76a2019-09-28 00:03:50 +0000931 private int checkUidPermissionImpl(String permName, int uid) {
Winson655a5b92019-10-23 10:49:32 -0700932 final AndroidPackage pkg = mPackageManagerInt.getPackage(uid);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000933 return checkUidPermissionInternal(pkg, uid, permName);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700934 }
935
936 /**
937 * Checks whether or not the given package has been granted the specified
938 * permission. If the given package is {@code null}, we instead check the
939 * system permissions for the given UID.
940 *
941 * @see SystemConfig#getSystemPermissions()
942 */
Winson655a5b92019-10-23 10:49:32 -0700943 private int checkUidPermissionInternal(@Nullable AndroidPackage pkg, int uid,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000944 @NonNull String permissionName) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700945 if (pkg != null) {
946 final int userId = UserHandle.getUserId(uid);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000947 return checkPermissionInternal(pkg, false, permissionName, userId);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700948 }
949
Hai Zhang3b049a52019-08-16 15:37:46 -0700950 if (checkSingleUidPermissionInternal(uid, permissionName)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000951 return PackageManager.PERMISSION_GRANTED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700952 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700953
954 final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
955 if (fullerPermissionName != null
956 && checkSingleUidPermissionInternal(uid, fullerPermissionName)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000957 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700958 }
959
Hai Zhang4fef76a2019-09-28 00:03:50 +0000960 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700961 }
962
Hai Zhang3b049a52019-08-16 15:37:46 -0700963 private boolean checkSingleUidPermissionInternal(int uid, @NonNull String permissionName) {
964 synchronized (mLock) {
965 ArraySet<String> permissions = mSystemPermissions.get(uid);
966 return permissions != null && permissions.contains(permissionName);
967 }
968 }
969
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700970 @Override
Michael Groover56a84b22020-03-04 20:41:36 -0800971 public int checkDeviceIdentifierAccess(@Nullable String packageName, @Nullable String message,
972 @Nullable String callingFeatureId, int pid, int uid) {
973 // If the check is being requested by an app then only allow the app to query its own
974 // access status.
975 int callingUid = mInjector.getCallingUid();
976 int callingPid = mInjector.getCallingPid();
977 if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID && (callingUid != uid
978 || callingPid != pid)) {
979 String response = String.format(
980 "Calling uid %d, pid %d cannot check device identifier access for package %s "
981 + "(uid=%d, pid=%d)",
982 callingUid, callingPid, packageName, uid, pid);
983 Log.w(TAG, response);
984 throw new SecurityException(response);
985 }
986 // Allow system and root access to the device identifiers.
987 final int appId = UserHandle.getAppId(uid);
988 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
989 return PackageManager.PERMISSION_GRANTED;
990 }
991 // Allow access to packages that have the READ_PRIVILEGED_PHONE_STATE permission.
992 if (mInjector.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid,
993 uid) == PackageManager.PERMISSION_GRANTED) {
994 return PackageManager.PERMISSION_GRANTED;
995 }
996 // If the calling package is not null then perform the appop and device / profile owner
997 // check.
998 if (packageName != null) {
999 // Allow access to a package that has been granted the READ_DEVICE_IDENTIFIERS appop.
1000 long token = mInjector.clearCallingIdentity();
1001 AppOpsManager appOpsManager = (AppOpsManager) mInjector.getSystemService(
1002 Context.APP_OPS_SERVICE);
1003 try {
1004 if (appOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, uid,
1005 packageName, callingFeatureId, message) == AppOpsManager.MODE_ALLOWED) {
1006 return PackageManager.PERMISSION_GRANTED;
1007 }
1008 } finally {
1009 mInjector.restoreCallingIdentity(token);
1010 }
1011 // Check if the calling packages meets the device / profile owner requirements for
1012 // identifier access.
1013 DevicePolicyManager devicePolicyManager =
1014 (DevicePolicyManager) mInjector.getSystemService(Context.DEVICE_POLICY_SERVICE);
1015 if (devicePolicyManager != null && devicePolicyManager.hasDeviceIdentifierAccess(
1016 packageName, pid, uid)) {
1017 return PackageManager.PERMISSION_GRANTED;
1018 }
1019 }
1020 return PackageManager.PERMISSION_DENIED;
1021 }
1022
1023 @Override
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001024 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
1025 mContext.enforceCallingOrSelfPermission(
1026 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
1027 "addOnPermissionsChangeListener");
1028
1029 synchronized (mLock) {
1030 mOnPermissionChangeListeners.addListenerLocked(listener);
1031 }
1032 }
1033
1034 @Override
1035 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
1036 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
1037 throw new SecurityException("Instant applications don't have access to this method");
1038 }
1039 synchronized (mLock) {
1040 mOnPermissionChangeListeners.removeListenerLocked(listener);
1041 }
1042 }
1043
1044 @Override
1045 @Nullable public List<String> getWhitelistedRestrictedPermissions(@NonNull String packageName,
1046 @PermissionWhitelistFlags int flags, @UserIdInt int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001047 Objects.requireNonNull(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001048 Preconditions.checkFlagsArgument(flags,
1049 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1050 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
1051 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
1052 Preconditions.checkArgumentNonNegative(userId, null);
1053
1054 if (UserHandle.getCallingUserId() != userId) {
1055 mContext.enforceCallingOrSelfPermission(
1056 android.Manifest.permission.INTERACT_ACROSS_USERS,
1057 "getWhitelistedRestrictedPermissions for user " + userId);
1058 }
1059
Winson14ff7172019-10-23 10:42:27 -07001060 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001061 if (pkg == null) {
1062 return null;
1063 }
1064
1065 final int callingUid = Binder.getCallingUid();
1066 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
1067 return null;
1068 }
1069 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1070 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1071 == PackageManager.PERMISSION_GRANTED;
1072 final boolean isCallerInstallerOnRecord =
1073 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1074
1075 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
1076 && !isCallerPrivileged) {
1077 throw new SecurityException("Querying system whitelist requires "
1078 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1079 }
1080
1081 if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1082 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) {
1083 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1084 throw new SecurityException("Querying upgrade or installer whitelist"
1085 + " requires being installer on record or "
1086 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1087 }
1088 }
1089
1090 final long identity = Binder.clearCallingIdentity();
1091 try {
1092 final PermissionsState permissionsState =
Winson14ff7172019-10-23 10:42:27 -07001093 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001094 if (permissionsState == null) {
1095 return null;
1096 }
1097
1098 int queryFlags = 0;
1099 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
1100 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
1101 }
1102 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1103 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
1104 }
1105 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1106 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
1107 }
1108
1109 ArrayList<String> whitelistedPermissions = null;
1110
Winson14ff7172019-10-23 10:42:27 -07001111 final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001112 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07001113 final String permissionName = pkg.getRequestedPermissions().get(i);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001114 final int currentFlags =
1115 permissionsState.getPermissionFlags(permissionName, userId);
1116 if ((currentFlags & queryFlags) != 0) {
1117 if (whitelistedPermissions == null) {
1118 whitelistedPermissions = new ArrayList<>();
1119 }
1120 whitelistedPermissions.add(permissionName);
1121 }
1122 }
1123
1124 return whitelistedPermissions;
1125 } finally {
1126 Binder.restoreCallingIdentity(identity);
1127 }
1128 }
1129
1130 @Override
1131 public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
1132 @NonNull String permName, @PermissionWhitelistFlags int flags,
1133 @UserIdInt int userId) {
1134 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001135 Objects.requireNonNull(permName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001136
1137 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1138 return false;
1139 }
1140
1141 List<String> permissions =
1142 getWhitelistedRestrictedPermissions(packageName, flags, userId);
1143 if (permissions == null) {
1144 permissions = new ArrayList<>(1);
1145 }
1146 if (permissions.indexOf(permName) < 0) {
1147 permissions.add(permName);
1148 return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
1149 flags, userId);
1150 }
1151 return false;
1152 }
1153
1154 private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
1155 @NonNull String permName) {
1156 synchronized (mLock) {
1157 final BasePermission bp = mSettings.getPermissionLocked(permName);
1158 if (bp == null) {
1159 Slog.w(TAG, "No such permissions: " + permName);
1160 return false;
1161 }
1162 if (bp.isHardOrSoftRestricted() && bp.isImmutablyRestricted()
1163 && mContext.checkCallingOrSelfPermission(
1164 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1165 != PackageManager.PERMISSION_GRANTED) {
1166 throw new SecurityException("Cannot modify whitelisting of an immutably "
1167 + "restricted permission: " + permName);
1168 }
1169 return true;
1170 }
1171 }
1172
1173 @Override
1174 public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
1175 @NonNull String permName, @PermissionWhitelistFlags int flags,
1176 @UserIdInt int userId) {
1177 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001178 Objects.requireNonNull(permName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001179
1180 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1181 return false;
1182 }
1183
1184 final List<String> permissions =
1185 getWhitelistedRestrictedPermissions(packageName, flags, userId);
1186 if (permissions != null && permissions.remove(permName)) {
1187 return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
1188 flags, userId);
1189 }
1190 return false;
1191 }
1192
1193 private boolean setWhitelistedRestrictedPermissionsInternal(@NonNull String packageName,
1194 @Nullable List<String> permissions, @PermissionWhitelistFlags int flags,
1195 @UserIdInt int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001196 Objects.requireNonNull(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001197 Preconditions.checkFlagsArgument(flags,
1198 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1199 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
1200 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
1201 Preconditions.checkArgument(Integer.bitCount(flags) == 1);
1202 Preconditions.checkArgumentNonNegative(userId, null);
1203
1204 if (UserHandle.getCallingUserId() != userId) {
1205 mContext.enforceCallingOrSelfPermission(
1206 Manifest.permission.INTERACT_ACROSS_USERS,
1207 "setWhitelistedRestrictedPermissions for user " + userId);
1208 }
1209
Winson14ff7172019-10-23 10:42:27 -07001210 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001211 if (pkg == null) {
1212 return false;
1213 }
1214
1215 final int callingUid = Binder.getCallingUid();
1216 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
1217 return false;
1218 }
1219
1220 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1221 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1222 == PackageManager.PERMISSION_GRANTED;
1223 final boolean isCallerInstallerOnRecord =
1224 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1225
1226 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
1227 && !isCallerPrivileged) {
1228 throw new SecurityException("Modifying system whitelist requires "
1229 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1230 }
1231
1232 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1233 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1234 throw new SecurityException("Modifying upgrade whitelist requires"
1235 + " being installer on record or "
1236 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1237 }
1238 final List<String> whitelistedPermissions =
Winson14ff7172019-10-23 10:42:27 -07001239 getWhitelistedRestrictedPermissions(pkg.getPackageName(), flags, userId);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001240 if (permissions == null || permissions.isEmpty()) {
1241 if (whitelistedPermissions == null || whitelistedPermissions.isEmpty()) {
1242 return true;
1243 }
1244 } else {
1245 // Only the system can add and remove while the installer can only remove.
1246 final int permissionCount = permissions.size();
1247 for (int i = 0; i < permissionCount; i++) {
1248 if ((whitelistedPermissions == null
1249 || !whitelistedPermissions.contains(permissions.get(i)))
1250 && !isCallerPrivileged) {
1251 throw new SecurityException("Adding to upgrade whitelist requires"
1252 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1253 }
1254 }
1255 }
1256
1257 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1258 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1259 throw new SecurityException("Modifying installer whitelist requires"
1260 + " being installer on record or "
1261 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1262 }
1263 }
1264 }
1265
1266 final long identity = Binder.clearCallingIdentity();
1267 try {
1268 setWhitelistedRestrictedPermissionsForUser(
1269 pkg, userId, permissions, Process.myUid(), flags, mDefaultPermissionCallback);
1270 } finally {
1271 Binder.restoreCallingIdentity(identity);
1272 }
1273
1274 return true;
1275 }
1276
Todd Kennedyc971a452019-07-08 16:04:52 -07001277 @Override
Eugene Susla922cd082020-03-11 12:38:17 -07001278 public boolean setAutoRevokeWhitelisted(
1279 @NonNull String packageName, boolean whitelisted, int userId) {
1280 Objects.requireNonNull(packageName);
1281
1282 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1283 final int callingUid = Binder.getCallingUid();
1284
1285 if (!checkAutoRevokeAccess(pkg, callingUid)) {
1286 return false;
1287 }
1288
1289 if (mAppOpsManager
1290 .checkOpNoThrow(AppOpsManager.OP_AUTO_REVOKE_MANAGED_BY_INSTALLER,
1291 callingUid, packageName)
1292 != MODE_ALLOWED) {
1293 // Whitelist user set - don't override
1294 return false;
1295 }
1296
1297 final long identity = Binder.clearCallingIdentity();
1298 try {
1299 mAppOpsManager.setMode(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
1300 callingUid, packageName,
1301 whitelisted ? MODE_IGNORED : MODE_ALLOWED);
1302 } finally {
1303 Binder.restoreCallingIdentity(identity);
1304 }
1305 return true;
1306 }
1307
1308 private boolean checkAutoRevokeAccess(AndroidPackage pkg, int callingUid) {
1309 if (pkg == null) {
1310 return false;
1311 }
1312
1313 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1314 Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS)
1315 == PackageManager.PERMISSION_GRANTED;
1316 final boolean isCallerInstallerOnRecord =
1317 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1318
1319 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1320 throw new SecurityException("Caller must either hold "
1321 + Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS
1322 + " or be the installer on record");
1323 }
1324 return true;
1325 }
1326
1327 @Override
1328 public boolean isAutoRevokeWhitelisted(@NonNull String packageName, int userId) {
1329 Objects.requireNonNull(packageName);
1330
1331 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1332 final int callingUid = Binder.getCallingUid();
1333
1334 if (!checkAutoRevokeAccess(pkg, callingUid)) {
1335 return false;
1336 }
1337
1338 final long identity = Binder.clearCallingIdentity();
1339 try {
1340 return mAppOpsManager.checkOpNoThrow(
1341 AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, callingUid, packageName)
1342 == MODE_IGNORED;
1343 } finally {
1344 Binder.restoreCallingIdentity(identity);
1345 }
1346 }
1347
1348 @Override
Todd Kennedyc971a452019-07-08 16:04:52 -07001349 public void grantRuntimePermission(String packageName, String permName, final int userId) {
1350 final int callingUid = Binder.getCallingUid();
1351 final boolean overridePolicy =
1352 checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
1353 == PackageManager.PERMISSION_GRANTED;
1354
1355 grantRuntimePermissionInternal(permName, packageName, overridePolicy,
1356 callingUid, userId, mDefaultPermissionCallback);
1357 }
1358
1359 // TODO swap permission name and package name
1360 private void grantRuntimePermissionInternal(String permName, String packageName,
1361 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
1362 if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
1363 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001364 Log.i(TAG, "System is granting " + packageName + " "
Todd Kennedyc971a452019-07-08 16:04:52 -07001365 + permName + " for user " + userId + " on behalf of uid " + callingUid
1366 + " " + mPackageManagerInt.getNameForUid(callingUid),
1367 new RuntimeException());
1368 }
1369 if (!mUserManagerInt.exists(userId)) {
1370 Log.e(TAG, "No such user:" + userId);
1371 return;
1372 }
1373
1374 mContext.enforceCallingOrSelfPermission(
1375 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1376 "grantRuntimePermission");
1377
1378 enforceCrossUserPermission(callingUid, userId,
1379 true, // requireFullPermission
1380 true, // checkShell
1381 false, // requirePermissionWhenSameUser
1382 "grantRuntimePermission");
1383
Winson14ff7172019-10-23 10:42:27 -07001384 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1385 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
1386 packageName);
1387 if (pkg == null || ps == null) {
Hai Zhangb94491c2019-07-31 14:07:17 -07001388 Log.e(TAG, "Unknown package: " + packageName);
1389 return;
Todd Kennedyc971a452019-07-08 16:04:52 -07001390 }
1391 final BasePermission bp;
1392 synchronized (mLock) {
1393 bp = mSettings.getPermissionLocked(permName);
1394 }
1395 if (bp == null) {
1396 throw new IllegalArgumentException("Unknown permission: " + permName);
1397 }
1398 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1399 throw new IllegalArgumentException("Unknown package: " + packageName);
1400 }
1401
Winson14ff7172019-10-23 10:42:27 -07001402 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
Todd Kennedyc971a452019-07-08 16:04:52 -07001403
1404 // If a permission review is required for legacy apps we represent
1405 // their permissions as always granted runtime ones since we need
1406 // to keep the review required permission flag per user while an
1407 // install permission's state is shared across all users.
Winson14ff7172019-10-23 10:42:27 -07001408 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Todd Kennedyc971a452019-07-08 16:04:52 -07001409 && bp.isRuntime()) {
1410 return;
1411 }
1412
Winson14ff7172019-10-23 10:42:27 -07001413 final int uid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
Todd Kennedyc971a452019-07-08 16:04:52 -07001414
Todd Kennedyc971a452019-07-08 16:04:52 -07001415 final PermissionsState permissionsState = ps.getPermissionsState();
1416
1417 final int flags = permissionsState.getPermissionFlags(permName, userId);
1418 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1419 Log.e(TAG, "Cannot grant system fixed permission "
1420 + permName + " for package " + packageName);
1421 return;
1422 }
1423 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1424 Log.e(TAG, "Cannot grant policy fixed permission "
1425 + permName + " for package " + packageName);
1426 return;
1427 }
1428
1429 if (bp.isHardRestricted()
1430 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
1431 Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
1432 + permName + " for package " + packageName);
1433 return;
1434 }
1435
1436 if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
Winson33eacc62020-01-24 12:02:58 -08001437 pkg.toAppInfoWithoutState(), pkg, UserHandle.of(userId), permName)
Winson6571c8a2019-10-23 17:00:42 -07001438 .mayGrantPermission()) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001439 Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
1440 + packageName);
1441 return;
1442 }
1443
1444 if (bp.isDevelopment()) {
1445 // Development permissions must be handled specially, since they are not
1446 // normal runtime permissions. For now they apply to all users.
1447 if (permissionsState.grantInstallPermission(bp)
1448 != PERMISSION_OPERATION_FAILURE) {
1449 if (callback != null) {
1450 callback.onInstallPermissionGranted();
1451 }
1452 }
1453 return;
1454 }
1455
1456 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1457 throw new SecurityException("Cannot grant non-ephemeral permission"
1458 + permName + " for package " + packageName);
1459 }
1460
Winson14ff7172019-10-23 10:42:27 -07001461 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001462 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1463 return;
1464 }
1465
1466 final int result = permissionsState.grantRuntimePermission(bp, userId);
1467 switch (result) {
1468 case PERMISSION_OPERATION_FAILURE: {
1469 return;
1470 }
1471
1472 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1473 if (callback != null) {
Winson14ff7172019-10-23 10:42:27 -07001474 callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId);
Todd Kennedyc971a452019-07-08 16:04:52 -07001475 }
1476 }
1477 break;
1478 }
1479
1480 if (bp.isRuntime()) {
1481 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
1482 }
1483
1484 if (callback != null) {
1485 callback.onPermissionGranted(uid, userId);
1486 }
1487
1488 if (bp.isRuntime()) {
1489 notifyRuntimePermissionStateChanged(packageName, userId);
1490 }
1491
1492 // Only need to do this if user is initialized. Otherwise it's a new user
1493 // and there are no processes running as the user yet and there's no need
1494 // to make an expensive call to remount processes for the changed permissions.
1495 if (READ_EXTERNAL_STORAGE.equals(permName)
1496 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1497 final long token = Binder.clearCallingIdentity();
1498 try {
1499 if (mUserManagerInt.isUserInitialized(userId)) {
1500 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1501 StorageManagerInternal.class);
1502 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1503 }
1504 } finally {
1505 Binder.restoreCallingIdentity(token);
1506 }
1507 }
1508
1509 }
1510
1511 @Override
1512 public void revokeRuntimePermission(String packageName, String permName, int userId) {
1513 final int callingUid = Binder.getCallingUid();
1514 final boolean overridePolicy =
1515 checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
1516 == PackageManager.PERMISSION_GRANTED;
1517
1518 revokeRuntimePermissionInternal(permName, packageName, overridePolicy, callingUid, userId,
1519 mDefaultPermissionCallback);
1520 }
1521
1522 // TODO swap permission name and package name
1523 private void revokeRuntimePermissionInternal(String permName, String packageName,
1524 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001525 if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
Todd Kennedyc971a452019-07-08 16:04:52 -07001526 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001527 Log.i(TAG, "System is revoking " + packageName + " "
Todd Kennedyc971a452019-07-08 16:04:52 -07001528 + permName + " for user " + userId + " on behalf of uid " + callingUid
1529 + " " + mPackageManagerInt.getNameForUid(callingUid),
1530 new RuntimeException());
1531 }
1532 if (!mUserManagerInt.exists(userId)) {
1533 Log.e(TAG, "No such user:" + userId);
1534 return;
1535 }
1536
1537 mContext.enforceCallingOrSelfPermission(
1538 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1539 "revokeRuntimePermission");
1540
1541 enforceCrossUserPermission(callingUid, userId,
1542 true, // requireFullPermission
1543 true, // checkShell
1544 false, // requirePermissionWhenSameUser
1545 "revokeRuntimePermission");
1546
Winson14ff7172019-10-23 10:42:27 -07001547 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1548 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
1549 packageName);
1550 if (pkg == null || ps == null) {
Hai Zhangb94491c2019-07-31 14:07:17 -07001551 Log.e(TAG, "Unknown package: " + packageName);
1552 return;
Todd Kennedyc971a452019-07-08 16:04:52 -07001553 }
1554 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1555 throw new IllegalArgumentException("Unknown package: " + packageName);
1556 }
1557 final BasePermission bp = mSettings.getPermissionLocked(permName);
1558 if (bp == null) {
1559 throw new IllegalArgumentException("Unknown permission: " + permName);
1560 }
1561
Winson14ff7172019-10-23 10:42:27 -07001562 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
Todd Kennedyc971a452019-07-08 16:04:52 -07001563
1564 // If a permission review is required for legacy apps we represent
1565 // their permissions as always granted runtime ones since we need
1566 // to keep the review required permission flag per user while an
1567 // install permission's state is shared across all users.
Winson14ff7172019-10-23 10:42:27 -07001568 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Todd Kennedyc971a452019-07-08 16:04:52 -07001569 && bp.isRuntime()) {
1570 return;
1571 }
1572
Todd Kennedyc971a452019-07-08 16:04:52 -07001573 final PermissionsState permissionsState = ps.getPermissionsState();
1574
1575 final int flags = permissionsState.getPermissionFlags(permName, userId);
1576 // Only the system may revoke SYSTEM_FIXED permissions.
1577 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1578 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1579 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
1580 + permName + " for package " + packageName);
1581 }
1582 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1583 throw new SecurityException("Cannot revoke policy fixed permission "
1584 + permName + " for package " + packageName);
1585 }
1586
1587 if (bp.isDevelopment()) {
1588 // Development permissions must be handled specially, since they are not
1589 // normal runtime permissions. For now they apply to all users.
1590 if (permissionsState.revokeInstallPermission(bp)
1591 != PERMISSION_OPERATION_FAILURE) {
1592 if (callback != null) {
1593 mDefaultPermissionCallback.onInstallPermissionRevoked();
1594 }
1595 }
1596 return;
1597 }
1598
1599 // Permission is already revoked, no need to do anything.
1600 if (!permissionsState.hasRuntimePermission(permName, userId)) {
1601 return;
1602 }
1603
1604 if (permissionsState.revokeRuntimePermission(bp, userId)
1605 == PERMISSION_OPERATION_FAILURE) {
1606 return;
1607 }
1608
1609 if (bp.isRuntime()) {
1610 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
1611 }
1612
1613 if (callback != null) {
Nate Myren8f6a9092019-08-27 15:50:03 -07001614 callback.onPermissionRevoked(UserHandle.getUid(userId,
Winson14ff7172019-10-23 10:42:27 -07001615 UserHandle.getAppId(pkg.getUid())), userId);
Todd Kennedyc971a452019-07-08 16:04:52 -07001616 }
1617
1618 if (bp.isRuntime()) {
1619 notifyRuntimePermissionStateChanged(packageName, userId);
1620 }
1621 }
1622
1623 @Override
1624 public void resetRuntimePermissions() {
1625 mContext.enforceCallingOrSelfPermission(
1626 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1627 "revokeRuntimePermission");
1628
1629 final int callingUid = Binder.getCallingUid();
1630 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
1631 mContext.enforceCallingOrSelfPermission(
1632 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1633 "resetRuntimePermissions");
1634 }
1635
1636 updateAllPermissions(
1637 StorageManager.UUID_PRIVATE_INTERNAL, false, mDefaultPermissionCallback);
1638 for (final int userId : UserManagerService.getInstance().getUserIds()) {
1639 mPackageManagerInt.forEachPackage(
Winson14ff7172019-10-23 10:42:27 -07001640 (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
Todd Kennedyc971a452019-07-08 16:04:52 -07001641 }
1642 }
1643
1644 /**
1645 * Reverts user permission state changes (permissions and flags).
1646 *
Hai Zhang4ffebb72019-07-18 14:50:58 -07001647 * @param pkg The package for which to reset.
Todd Kennedyc971a452019-07-08 16:04:52 -07001648 * @param userId The device user for which to do a reset.
1649 */
Patrick Baumann865fd3a2019-07-26 14:53:02 -07001650 @GuardedBy("mLock")
Winson14ff7172019-10-23 10:42:27 -07001651 private void resetRuntimePermissionsInternal(final AndroidPackage pkg,
Todd Kennedyc971a452019-07-08 16:04:52 -07001652 final int userId) {
Winson14ff7172019-10-23 10:42:27 -07001653 final String packageName = pkg.getPackageName();
Todd Kennedyc971a452019-07-08 16:04:52 -07001654
1655 // These are flags that can change base on user actions.
1656 final int userSettableMask = FLAG_PERMISSION_USER_SET
1657 | FLAG_PERMISSION_USER_FIXED
Hai Zhang50a5a9b2019-09-19 13:57:45 -07001658 | FLAG_PERMISSION_REVOKED_COMPAT
Todd Kennedyc971a452019-07-08 16:04:52 -07001659 | FLAG_PERMISSION_REVIEW_REQUIRED;
1660
1661 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
1662 | FLAG_PERMISSION_POLICY_FIXED;
1663
1664 // Delay and combine non-async permission callbacks
Winson14ff7172019-10-23 10:42:27 -07001665 final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
Todd Kennedyc971a452019-07-08 16:04:52 -07001666 final boolean[] permissionRemoved = new boolean[1];
1667 final ArraySet<Long> revokedPermissions = new ArraySet<>();
1668 final IntArray syncUpdatedUsers = new IntArray(permissionCount);
1669 final IntArray asyncUpdatedUsers = new IntArray(permissionCount);
1670
1671 PermissionCallback delayingPermCallback = new PermissionCallback() {
1672 public void onGidsChanged(int appId, int userId) {
1673 mDefaultPermissionCallback.onGidsChanged(appId, userId);
1674 }
1675
1676 public void onPermissionChanged() {
1677 mDefaultPermissionCallback.onPermissionChanged();
1678 }
1679
1680 public void onPermissionGranted(int uid, int userId) {
1681 mDefaultPermissionCallback.onPermissionGranted(uid, userId);
1682 }
1683
1684 public void onInstallPermissionGranted() {
1685 mDefaultPermissionCallback.onInstallPermissionGranted();
1686 }
1687
1688 public void onPermissionRevoked(int uid, int userId) {
1689 revokedPermissions.add(IntPair.of(uid, userId));
1690
1691 syncUpdatedUsers.add(userId);
1692 }
1693
1694 public void onInstallPermissionRevoked() {
1695 mDefaultPermissionCallback.onInstallPermissionRevoked();
1696 }
1697
1698 public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1699 for (int userId : updatedUserIds) {
1700 if (sync) {
1701 syncUpdatedUsers.add(userId);
1702 asyncUpdatedUsers.remove(userId);
1703 } else {
1704 // Don't override sync=true by sync=false
1705 if (syncUpdatedUsers.indexOf(userId) == -1) {
1706 asyncUpdatedUsers.add(userId);
1707 }
1708 }
1709 }
1710 }
1711
1712 public void onPermissionRemoved() {
1713 permissionRemoved[0] = true;
1714 }
1715
1716 public void onInstallPermissionUpdated() {
1717 mDefaultPermissionCallback.onInstallPermissionUpdated();
1718 }
Nate Myrencc9e2c72019-11-08 14:57:15 -08001719
1720 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds,
1721 boolean sync, int uid) {
1722 onPermissionUpdated(updatedUserIds, sync);
1723 mOnPermissionChangeListeners.onPermissionsChanged(uid);
1724 }
1725
1726 public void onInstallPermissionUpdatedNotifyListener(int uid) {
1727 mDefaultPermissionCallback.onInstallPermissionUpdatedNotifyListener(uid);
1728 }
Todd Kennedyc971a452019-07-08 16:04:52 -07001729 };
1730
1731 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07001732 final String permName = pkg.getRequestedPermissions().get(i);
Todd Kennedyc971a452019-07-08 16:04:52 -07001733 final BasePermission bp;
1734 synchronized (mLock) {
1735 bp = mSettings.getPermissionLocked(permName);
1736 }
1737 if (bp == null) {
1738 continue;
1739 }
1740
1741 if (bp.isRemoved()) {
1742 continue;
1743 }
1744
1745 // If shared user we just reset the state to which only this app contributed.
Alan Stokes20fbef22019-12-17 15:33:12 +00001746 final String[] pkgNames = mPackageManagerInt.getSharedUserPackagesForPackage(
1747 pkg.getPackageName(), userId);
1748 if (pkgNames.length > 0) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001749 boolean used = false;
Alan Stokes20fbef22019-12-17 15:33:12 +00001750 for (String sharedPkgName : pkgNames) {
Winson14ff7172019-10-23 10:42:27 -07001751 final AndroidPackage sharedPkg =
Todd Kennedyc971a452019-07-08 16:04:52 -07001752 mPackageManagerInt.getPackage(sharedPkgName);
Winson14ff7172019-10-23 10:42:27 -07001753 if (sharedPkg != null && !sharedPkg.getPackageName().equals(packageName)
1754 && sharedPkg.getRequestedPermissions().contains(permName)) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001755 used = true;
1756 break;
1757 }
1758 }
1759 if (used) {
1760 continue;
1761 }
1762 }
1763
1764 final int oldFlags =
1765 getPermissionFlagsInternal(permName, packageName, Process.SYSTEM_UID, userId);
1766
1767 // Always clear the user settable flags.
1768 // If permission review is enabled and this is a legacy app, mark the
1769 // permission as requiring a review as this is the initial state.
1770 final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
Hai Zhang053c3a22019-08-23 15:08:03 -07001771 final int targetSdk = mPackageManagerInt.getUidTargetSdkVersion(uid);
Todd Kennedyc971a452019-07-08 16:04:52 -07001772 final int flags = (targetSdk < Build.VERSION_CODES.M && bp.isRuntime())
Hai Zhang50a5a9b2019-09-19 13:57:45 -07001773 ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT
Todd Kennedyc971a452019-07-08 16:04:52 -07001774 : 0;
1775
1776 updatePermissionFlagsInternal(
1777 permName, packageName, userSettableMask, flags, Process.SYSTEM_UID, userId,
1778 false, delayingPermCallback);
1779
1780 // Below is only runtime permission handling.
1781 if (!bp.isRuntime()) {
1782 continue;
1783 }
1784
1785 // Never clobber system or policy.
1786 if ((oldFlags & policyOrSystemFlags) != 0) {
1787 continue;
1788 }
1789
1790 // If this permission was granted by default, make sure it is.
1791 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
Hai Zhangab6a6822019-10-18 00:34:06 +00001792 // PermissionPolicyService will handle the app op for runtime permissions later.
Todd Kennedyc971a452019-07-08 16:04:52 -07001793 grantRuntimePermissionInternal(permName, packageName, false,
1794 Process.SYSTEM_UID, userId, delayingPermCallback);
1795 // If permission review is enabled the permissions for a legacy apps
1796 // are represented as constantly granted runtime ones, so don't revoke.
1797 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
1798 // Otherwise, reset the permission.
1799 revokeRuntimePermissionInternal(permName, packageName, false, Process.SYSTEM_UID,
1800 userId, delayingPermCallback);
1801 }
1802 }
1803
1804 // Execute delayed callbacks
1805 if (permissionRemoved[0]) {
1806 mDefaultPermissionCallback.onPermissionRemoved();
1807 }
1808
1809 // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
1810 // kill uid while holding mPackages-lock
1811 if (!revokedPermissions.isEmpty()) {
1812 int numRevokedPermissions = revokedPermissions.size();
1813 for (int i = 0; i < numRevokedPermissions; i++) {
1814 int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
1815 int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));
1816
1817 mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);
1818
1819 // Kill app later as we are holding mPackages
1820 mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
1821 KILL_APP_REASON_PERMISSIONS_REVOKED));
1822 }
1823 }
1824
1825 mPackageManagerInt.writePermissionSettings(syncUpdatedUsers.toArray(), false);
1826 mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true);
1827 }
1828
Todd Kennedy583378d2019-07-12 06:50:30 -07001829 @Override
1830 public String getDefaultBrowser(int userId) {
1831 final int callingUid = Binder.getCallingUid();
1832 if (UserHandle.getUserId(callingUid) != userId) {
1833 mContext.enforceCallingOrSelfPermission(
1834 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
1835 }
1836 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
1837 return null;
1838 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001839 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001840 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001841 provider = mDefaultBrowserProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001842 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001843 return provider != null ? provider.getDefaultBrowser(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07001844 }
1845
1846 @Override
1847 public boolean setDefaultBrowser(String packageName, int userId) {
1848 mContext.enforceCallingOrSelfPermission(
1849 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
1850 if (UserHandle.getCallingUserId() != userId) {
1851 mContext.enforceCallingOrSelfPermission(
1852 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
1853 }
1854 return setDefaultBrowserInternal(packageName, false, true, userId);
1855 }
1856
1857 private boolean setDefaultBrowserInternal(String packageName, boolean async,
1858 boolean doGrant, int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001859 if (userId == UserHandle.USER_ALL) {
1860 return false;
1861 }
1862 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001863 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001864 provider = mDefaultBrowserProvider;
1865 }
1866 if (provider == null) {
1867 return false;
1868 }
1869 if (async) {
1870 provider.setDefaultBrowserAsync(packageName, userId);
1871 } else {
1872 if (!provider.setDefaultBrowser(packageName, userId)) {
Todd Kennedy583378d2019-07-12 06:50:30 -07001873 return false;
1874 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001875 }
1876 if (doGrant && packageName != null) {
1877 synchronized (mLock) {
1878 mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
1879 userId);
Todd Kennedy583378d2019-07-12 06:50:30 -07001880 }
1881 }
1882 return true;
1883 }
1884
1885 @Override
1886 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
1887 final int callingUid = Binder.getCallingUid();
1888 PackageManagerServiceUtils
1889 .enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
1890 synchronized (mLock) {
1891 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1892 .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
1893 }
1894 }
1895
1896 @Override
1897 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
1898 final int callingUid = Binder.getCallingUid();
1899 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1900 "grantDefaultPermissionsToEnabledImsServices", callingUid);
1901 synchronized (mLock) {
1902 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1903 .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
1904 }
1905 }
1906
1907 @Override
1908 public void grantDefaultPermissionsToEnabledTelephonyDataServices(
1909 String[] packageNames, int userId) {
1910 final int callingUid = Binder.getCallingUid();
1911 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1912 "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
1913 synchronized (mLock) {
1914 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1915 .grantDefaultPermissionsToEnabledTelephonyDataServices(
1916 packageNames, userId));
1917 }
1918 }
1919
1920 @Override
1921 public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
1922 String[] packageNames, int userId) {
1923 final int callingUid = Binder.getCallingUid();
1924 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1925 "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
1926 synchronized (mLock) {
1927 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1928 .revokeDefaultPermissionsFromDisabledTelephonyDataServices(
1929 packageNames, userId));
1930 }
1931 }
1932
1933 @Override
1934 public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
1935 final int callingUid = Binder.getCallingUid();
1936 PackageManagerServiceUtils
1937 .enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
1938 synchronized (mLock) {
1939 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1940 .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
1941 }
1942 }
1943
1944 @Override
1945 public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
1946 final int callingUid = Binder.getCallingUid();
1947 PackageManagerServiceUtils
1948 .enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
1949 synchronized (mLock) {
1950 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1951 .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
1952 }
1953 }
1954
Todd Kennedyc5b0e862019-07-16 09:47:58 -07001955 @Override
1956 public void setPermissionEnforced(String permName, boolean enforced) {
1957 // TODO: Now that we no longer change GID for storage, this should to away.
1958 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1959 "setPermissionEnforced");
1960 if (READ_EXTERNAL_STORAGE.equals(permName)) {
1961 mPackageManagerInt.setReadExternalStorageEnforced(enforced);
1962 // kill any non-foreground processes so we restart them and
1963 // grant/revoke the GID.
1964 final IActivityManager am = ActivityManager.getService();
1965 if (am != null) {
1966 final long token = Binder.clearCallingIdentity();
1967 try {
1968 am.killProcessesBelowForeground("setPermissionEnforcement");
1969 } catch (RemoteException e) {
1970 } finally {
1971 Binder.restoreCallingIdentity(token);
1972 }
1973 }
1974 } else {
1975 throw new IllegalArgumentException("No selective enforcement for " + permName);
1976 }
1977 }
1978
1979 /** @deprecated */
1980 @Override
1981 @Deprecated
1982 public boolean isPermissionEnforced(String permName) {
1983 // allow instant applications
1984 return true;
1985 }
1986
Evan Severson50a77742020-01-06 10:38:19 -08001987 /**
1988 * This change makes it so that apps are told to show rationale for asking for background
1989 * location access every time they request.
1990 */
1991 @ChangeId
1992 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
1993 private static final long BACKGROUND_RATIONALE_CHANGE_ID = 147316723L;
1994
Todd Kennedyc5b0e862019-07-16 09:47:58 -07001995 @Override
1996 public boolean shouldShowRequestPermissionRationale(String permName,
1997 String packageName, int userId) {
1998 final int callingUid = Binder.getCallingUid();
1999 if (UserHandle.getCallingUserId() != userId) {
2000 mContext.enforceCallingPermission(
2001 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2002 "canShowRequestPermissionRationale for user " + userId);
2003 }
2004
2005 final int uid =
2006 mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
2007 if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) {
2008 return false;
2009 }
2010
2011 if (checkPermission(permName, packageName, userId)
2012 == PackageManager.PERMISSION_GRANTED) {
2013 return false;
2014 }
2015
2016 final int flags;
2017
2018 final long identity = Binder.clearCallingIdentity();
2019 try {
2020 flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
2021 } finally {
2022 Binder.restoreCallingIdentity(identity);
2023 }
2024
2025 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2026 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
2027 | PackageManager.FLAG_PERMISSION_USER_FIXED;
2028
2029 if ((flags & fixedFlags) != 0) {
2030 return false;
2031 }
2032
atrost24274272020-02-17 19:26:41 +00002033 final long token = Binder.clearCallingIdentity();
Evan Severson50a77742020-01-06 10:38:19 -08002034 try {
2035 if (permName.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
2036 && mPlatformCompat.isChangeEnabledByPackageName(BACKGROUND_RATIONALE_CHANGE_ID,
2037 packageName, userId)) {
2038 return true;
2039 }
2040 } catch (RemoteException e) {
2041 Log.e(TAG, "Unable to check if compatibility change is enabled.", e);
atrost24274272020-02-17 19:26:41 +00002042 } finally {
2043 Binder.restoreCallingIdentity(token);
Evan Severson50a77742020-01-06 10:38:19 -08002044 }
2045
Todd Kennedyc5b0e862019-07-16 09:47:58 -07002046 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
2047 }
2048
2049 @Override
2050 public boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId) {
2051 if (UserHandle.getCallingUserId() != userId) {
2052 mContext.enforceCallingPermission(
2053 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2054 "isPermissionRevokedByPolicy for user " + userId);
2055 }
2056
2057 if (checkPermission(permName, packageName, userId) == PackageManager.PERMISSION_GRANTED) {
2058 return false;
2059 }
2060
2061 final int callingUid = Binder.getCallingUid();
2062 if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) {
2063 return false;
2064 }
2065
2066 final long identity = Binder.clearCallingIdentity();
2067 try {
2068 final int flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
2069 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
2070 } finally {
2071 Binder.restoreCallingIdentity(identity);
2072 }
2073 }
2074
Hongwei Wangf391b552018-04-06 13:52:46 -07002075 /**
Philip P. Moltmann48456672019-01-20 13:14:03 -08002076 * Get the state of the runtime permissions as xml file.
2077 *
2078 * <p>Can not be called on main thread.
2079 *
2080 * @param user The user the data should be extracted for
2081 *
2082 * @return The state as a xml file
2083 */
2084 private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
2085 CompletableFuture<byte[]> backup = new CompletableFuture<>();
2086 mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
2087 backup::complete);
2088
2089 try {
2090 return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
2091 } catch (InterruptedException | ExecutionException | TimeoutException e) {
2092 Slog.e(TAG, "Cannot create permission backup for " + user, e);
2093 return null;
2094 }
2095 }
2096
2097 /**
2098 * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
2099 *
2100 * <p>If not all state can be restored, the un-appliable state will be delayed and can be
2101 * applied via {@link #restoreDelayedRuntimePermissions}.
2102 *
2103 * @param backup The state as an xml file
2104 * @param user The user the data should be restored for
2105 */
2106 private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
2107 synchronized (mLock) {
2108 mHasNoDelayedPermBackup.delete(user.getIdentifier());
Philip P. Moltmann4a6c5de2019-09-13 11:15:44 -07002109 mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup, user);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002110 }
2111 }
2112
2113 /**
2114 * Try to apply permission backup that was previously not applied.
2115 *
2116 * <p>Can not be called on main thread.
2117 *
2118 * @param packageName The package that is newly installed
2119 * @param user The user the package is installed for
2120 *
2121 * @see #restoreRuntimePermissions
2122 */
2123 private void restoreDelayedRuntimePermissions(@NonNull String packageName,
2124 @NonNull UserHandle user) {
2125 synchronized (mLock) {
2126 if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
2127 return;
2128 }
2129
Philip P. Moltmann4a6c5de2019-09-13 11:15:44 -07002130 mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName, user,
Philip P. Moltmann48456672019-01-20 13:14:03 -08002131 mContext.getMainExecutor(), (hasMoreBackup) -> {
2132 if (hasMoreBackup) {
2133 return;
2134 }
2135
2136 synchronized (mLock) {
2137 mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
2138 }
2139 });
2140 }
2141 }
2142
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002143 private void addOnRuntimePermissionStateChangedListener(@NonNull
2144 OnRuntimePermissionStateChangedListener listener) {
2145 synchronized (mLock) {
2146 mRuntimePermissionStateChangedListeners.add(listener);
2147 }
2148 }
2149
2150 private void removeOnRuntimePermissionStateChangedListener(@NonNull
2151 OnRuntimePermissionStateChangedListener listener) {
2152 synchronized (mLock) {
2153 mRuntimePermissionStateChangedListeners.remove(listener);
2154 }
2155 }
2156
2157 private void notifyRuntimePermissionStateChanged(@NonNull String packageName,
2158 @UserIdInt int userId) {
2159 FgThread.getHandler().sendMessage(PooledLambda.obtainMessage
2160 (PermissionManagerService::doNotifyRuntimePermissionStateChanged,
2161 PermissionManagerService.this, packageName, userId));
2162 }
2163
2164 private void doNotifyRuntimePermissionStateChanged(@NonNull String packageName,
2165 @UserIdInt int userId) {
2166 final ArrayList<OnRuntimePermissionStateChangedListener> listeners;
2167 synchronized (mLock) {
2168 if (mRuntimePermissionStateChangedListeners.isEmpty()) {
2169 return;
2170 }
2171 listeners = new ArrayList<>(mRuntimePermissionStateChangedListeners);
2172 }
2173 final int listenerCount = listeners.size();
2174 for (int i = 0; i < listenerCount; i++) {
2175 listeners.get(i).onRuntimePermissionStateChanged(packageName, userId);
2176 }
2177 }
2178
Todd Kennedy0eb97382017-10-03 16:57:22 -07002179 private int adjustPermissionProtectionFlagsLocked(
2180 int protectionLevel, String packageName, int uid) {
2181 // Signature permission flags area always reported
2182 final int protectionLevelMasked = protectionLevel
2183 & (PermissionInfo.PROTECTION_NORMAL
2184 | PermissionInfo.PROTECTION_DANGEROUS
2185 | PermissionInfo.PROTECTION_SIGNATURE);
2186 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
2187 return protectionLevel;
2188 }
2189 // System sees all flags.
2190 final int appId = UserHandle.getAppId(uid);
2191 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
2192 || appId == Process.SHELL_UID) {
2193 return protectionLevel;
2194 }
2195 // Normalize package name to handle renamed packages and static libs
Winson14ff7172019-10-23 10:42:27 -07002196 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002197 if (pkg == null) {
2198 return protectionLevel;
2199 }
Winson14ff7172019-10-23 10:42:27 -07002200 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002201 return protectionLevelMasked;
2202 }
2203 // Apps that target O see flags for all protection levels.
Winson14ff7172019-10-23 10:42:27 -07002204 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
2205 pkg.getPackageName());
Todd Kennedy0eb97382017-10-03 16:57:22 -07002206 if (ps == null) {
2207 return protectionLevel;
2208 }
2209 if (ps.getAppId() != appId) {
2210 return protectionLevel;
2211 }
2212 return protectionLevel;
2213 }
2214
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002215 /**
2216 * We might auto-grant permissions if any permission of the group is already granted. Hence if
2217 * the group of a granted permission changes we need to revoke it to avoid having permissions of
2218 * the new group auto-granted.
2219 *
2220 * @param newPackage The new package that was installed
2221 * @param oldPackage The old package that was updated
2222 * @param allPackageNames All package names
2223 * @param permissionCallback Callback for permission changed
2224 */
2225 private void revokeRuntimePermissionsIfGroupChanged(
Winson14ff7172019-10-23 10:42:27 -07002226 @NonNull AndroidPackage newPackage,
2227 @NonNull AndroidPackage oldPackage,
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002228 @NonNull ArrayList<String> allPackageNames,
2229 @NonNull PermissionCallback permissionCallback) {
Winson14ff7172019-10-23 10:42:27 -07002230 final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002231 final ArrayMap<String, String> oldPermissionNameToGroupName
2232 = new ArrayMap<>(numOldPackagePermissions);
2233
2234 for (int i = 0; i < numOldPackagePermissions; i++) {
Winson14ff7172019-10-23 10:42:27 -07002235 final ParsedPermission permission = oldPackage.getPermissions().get(i);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002236
Winsonf00c7552020-01-28 12:52:01 -08002237 if (permission.getParsedPermissionGroup() != null) {
Winson14ff7172019-10-23 10:42:27 -07002238 oldPermissionNameToGroupName.put(permission.getName(),
Winsonf00c7552020-01-28 12:52:01 -08002239 permission.getParsedPermissionGroup().getName());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002240 }
2241 }
2242
Todd Kennedyc971a452019-07-08 16:04:52 -07002243 final int callingUid = Binder.getCallingUid();
Winson14ff7172019-10-23 10:42:27 -07002244 final int numNewPackagePermissions = ArrayUtils.size(newPackage.getPermissions());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002245 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
2246 newPermissionNum++) {
Winson14ff7172019-10-23 10:42:27 -07002247 final ParsedPermission newPermission =
2248 newPackage.getPermissions().get(newPermissionNum);
2249 final int newProtection = newPermission.getProtection();
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002250
2251 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
Winson14ff7172019-10-23 10:42:27 -07002252 final String permissionName = newPermission.getName();
Winsonf00c7552020-01-28 12:52:01 -08002253 final String newPermissionGroupName =
2254 newPermission.getParsedPermissionGroup() == null
2255 ? null : newPermission.getParsedPermissionGroup().getName();
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002256 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
2257 permissionName);
2258
2259 if (newPermissionGroupName != null
2260 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
2261 final int[] userIds = mUserManagerInt.getUserIds();
2262 final int numUserIds = userIds.length;
2263 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
2264 final int userId = userIds[userIdNum];
2265
2266 final int numPackages = allPackageNames.size();
2267 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
2268 final String packageName = allPackageNames.get(packageNum);
Hai Zhang3b049a52019-08-16 15:37:46 -07002269 final int permissionState = checkPermission(permissionName, packageName,
2270 userId);
Todd Kennedyca1ea172019-07-03 15:02:28 -07002271 if (permissionState == PackageManager.PERMISSION_GRANTED) {
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002272 EventLog.writeEvent(0x534e4554, "72710897",
Winson14ff7172019-10-23 10:42:27 -07002273 newPackage.getUid(),
Koji Fukuiacae3ef2018-05-09 11:38:01 +09002274 "Revoking permission " + permissionName +
2275 " from package " + packageName +
2276 " as the group changed from " + oldPermissionGroupName +
2277 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002278
2279 try {
Todd Kennedyc971a452019-07-08 16:04:52 -07002280 revokeRuntimePermissionInternal(permissionName, packageName,
2281 false, callingUid, userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002282 } catch (IllegalArgumentException e) {
2283 Slog.e(TAG, "Could not revoke " + permissionName + " from "
2284 + packageName, e);
2285 }
2286 }
2287 }
2288 }
2289 }
2290 }
2291 }
2292 }
2293
Winson14ff7172019-10-23 10:42:27 -07002294 private void addAllPermissions(AndroidPackage pkg, boolean chatty) {
2295 final int N = ArrayUtils.size(pkg.getPermissions());
Todd Kennedyc8423932017-10-05 08:58:36 -07002296 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002297 ParsedPermission p = pkg.getPermissions().get(i);
Todd Kennedyc8423932017-10-05 08:58:36 -07002298
2299 // Assume by default that we did not install this permission into the system.
Winsonf00c7552020-01-28 12:52:01 -08002300 p.setFlags(p.getFlags() & ~PermissionInfo.FLAG_INSTALLED);
Todd Kennedyc8423932017-10-05 08:58:36 -07002301
Todd Kennedyc8423932017-10-05 08:58:36 -07002302 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002303 // Now that permission groups have a special meaning, we ignore permission
2304 // groups for legacy apps to prevent unexpected behavior. In particular,
2305 // permissions for one app being granted to someone just because they happen
2306 // to be in a group defined by another app (before this had no implications).
Winson14ff7172019-10-23 10:42:27 -07002307 if (pkg.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) {
Winsonf00c7552020-01-28 12:52:01 -08002308 p.setParsedPermissionGroup(mSettings.mPermissionGroups.get(p.getGroup()));
Todd Kennedy460f28c2017-10-06 13:46:22 -07002309 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002310 if (DEBUG_PERMISSIONS
Winsonf00c7552020-01-28 12:52:01 -08002311 && p.getGroup() != null && p.getParsedPermissionGroup() == null) {
Winson14ff7172019-10-23 10:42:27 -07002312 Slog.i(TAG, "Permission " + p.getName() + " from package "
2313 + p.getPackageName() + " in an unknown group " + p.getGroup());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002314 }
2315 }
2316
Winsonf00c7552020-01-28 12:52:01 -08002317 if (p.isTree()) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002318 final BasePermission bp = BasePermission.createOrUpdate(
Winson14ff7172019-10-23 10:42:27 -07002319 mPackageManagerInt,
2320 mSettings.getPermissionTreeLocked(p.getName()), p, pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002321 mSettings.getAllPermissionTreesLocked(), chatty);
Winson14ff7172019-10-23 10:42:27 -07002322 mSettings.putPermissionTreeLocked(p.getName(), bp);
Todd Kennedyc8423932017-10-05 08:58:36 -07002323 } else {
2324 final BasePermission bp = BasePermission.createOrUpdate(
Winson14ff7172019-10-23 10:42:27 -07002325 mPackageManagerInt,
2326 mSettings.getPermissionLocked(p.getName()),
Todd Kennedyc8423932017-10-05 08:58:36 -07002327 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
Winson14ff7172019-10-23 10:42:27 -07002328 mSettings.putPermissionLocked(p.getName(), bp);
Todd Kennedyc8423932017-10-05 08:58:36 -07002329 }
2330 }
2331 }
2332 }
2333
Winson14ff7172019-10-23 10:42:27 -07002334 private void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
2335 final int N = ArrayUtils.size(pkg.getPermissionGroups());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002336 StringBuilder r = null;
2337 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002338 final ParsedPermissionGroup pg = pkg.getPermissionGroups().get(i);
2339 final ParsedPermissionGroup cur = mSettings.mPermissionGroups.get(pg.getName());
2340 final String curPackageName = (cur == null) ? null : cur.getPackageName();
2341 final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName);
Todd Kennedy460f28c2017-10-06 13:46:22 -07002342 if (cur == null || isPackageUpdate) {
Winson14ff7172019-10-23 10:42:27 -07002343 mSettings.mPermissionGroups.put(pg.getName(), pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002344 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002345 if (r == null) {
2346 r = new StringBuilder(256);
2347 } else {
2348 r.append(' ');
2349 }
2350 if (isPackageUpdate) {
2351 r.append("UPD:");
2352 }
Winson14ff7172019-10-23 10:42:27 -07002353 r.append(pg.getName());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002354 }
2355 } else {
Winson14ff7172019-10-23 10:42:27 -07002356 Slog.w(TAG, "Permission group " + pg.getName() + " from package "
2357 + pg.getPackageName() + " ignored: original from "
2358 + cur.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002359 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002360 if (r == null) {
2361 r = new StringBuilder(256);
2362 } else {
2363 r.append(' ');
2364 }
2365 r.append("DUP:");
Winson14ff7172019-10-23 10:42:27 -07002366 r.append(pg.getName());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002367 }
2368 }
2369 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002370 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002371 Log.d(TAG, " Permission Groups: " + r);
2372 }
2373
2374 }
2375
Winson14ff7172019-10-23 10:42:27 -07002376 private void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002377 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07002378 int N = ArrayUtils.size(pkg.getPermissions());
Todd Kennedyc8423932017-10-05 08:58:36 -07002379 StringBuilder r = null;
2380 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002381 ParsedPermission p = pkg.getPermissions().get(i);
2382 BasePermission bp = mSettings.mPermissions.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002383 if (bp == null) {
Winson14ff7172019-10-23 10:42:27 -07002384 bp = mSettings.mPermissionTrees.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002385 }
2386 if (bp != null && bp.isPermission(p)) {
2387 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002388 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002389 if (r == null) {
2390 r = new StringBuilder(256);
2391 } else {
2392 r.append(' ');
2393 }
Winson14ff7172019-10-23 10:42:27 -07002394 r.append(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002395 }
2396 }
2397 if (p.isAppOp()) {
2398 ArraySet<String> appOpPkgs =
Winson14ff7172019-10-23 10:42:27 -07002399 mSettings.mAppOpPermissionPackages.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002400 if (appOpPkgs != null) {
Winson14ff7172019-10-23 10:42:27 -07002401 appOpPkgs.remove(pkg.getPackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002402 }
2403 }
2404 }
2405 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002406 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -07002407 }
2408
Winson14ff7172019-10-23 10:42:27 -07002409 N = pkg.getRequestedPermissions().size();
Todd Kennedyc8423932017-10-05 08:58:36 -07002410 r = null;
2411 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002412 String perm = pkg.getRequestedPermissions().get(i);
Todd Kennedyc8423932017-10-05 08:58:36 -07002413 if (mSettings.isPermissionAppOp(perm)) {
2414 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
2415 if (appOpPkgs != null) {
Winson14ff7172019-10-23 10:42:27 -07002416 appOpPkgs.remove(pkg.getPackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002417 if (appOpPkgs.isEmpty()) {
2418 mSettings.mAppOpPermissionPackages.remove(perm);
2419 }
2420 }
2421 }
2422 }
2423 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002424 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -07002425 }
2426 }
2427 }
2428
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002429 /**
2430 * Restore the permission state for a package.
2431 *
2432 * <ul>
2433 * <li>During boot the state gets restored from the disk</li>
2434 * <li>During app update the state gets restored from the last version of the app</li>
2435 * </ul>
2436 *
2437 * <p>This restores the permission state for all users.
2438 *
2439 * @param pkg the package the permissions belong to
2440 * @param replace if the package is getting replaced (this might change the requested
2441 * permissions of this package)
2442 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
2443 * @param callback Result call back
2444 */
Winson14ff7172019-10-23 10:42:27 -07002445 private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace,
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002446 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002447 // IMPORTANT: There are two types of permissions: install and runtime.
2448 // Install time permissions are granted when the app is installed to
2449 // all device users and users added in the future. Runtime permissions
2450 // are granted at runtime explicitly to specific users. Normal and signature
2451 // protected permissions are install time permissions. Dangerous permissions
2452 // are install permissions if the app's target SDK is Lollipop MR1 or older,
2453 // otherwise they are runtime permissions. This function does not manage
2454 // runtime permissions except for the case an app targeting Lollipop MR1
2455 // being upgraded to target a newer SDK, in which case dangerous permissions
2456 // are transformed from install time to runtime ones.
2457
Winson14ff7172019-10-23 10:42:27 -07002458 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
2459 pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002460 if (ps == null) {
2461 return;
2462 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002463
2464 final PermissionsState permissionsState = ps.getPermissionsState();
2465 PermissionsState origPermissions = permissionsState;
2466
2467 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2468
2469 boolean runtimePermissionsRevoked = false;
2470 int[] updatedUserIds = EMPTY_INT_ARRAY;
2471
2472 boolean changedInstallPermission = false;
2473
2474 if (replace) {
2475 ps.setInstallPermissionsFixed(false);
2476 if (!ps.isSharedUser()) {
2477 origPermissions = new PermissionsState(permissionsState);
2478 permissionsState.reset();
2479 } else {
2480 // We need to know only about runtime permission changes since the
2481 // calling code always writes the install permissions state but
2482 // the runtime ones are written only if changed. The only cases of
2483 // changed runtime permissions here are promotion of an install to
2484 // runtime and revocation of a runtime from a shared user.
2485 synchronized (mLock) {
2486 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
2487 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
2488 if (!ArrayUtils.isEmpty(updatedUserIds)) {
2489 runtimePermissionsRevoked = true;
2490 }
2491 }
2492 }
2493 }
2494
2495 permissionsState.setGlobalGids(mGlobalGids);
2496
2497 synchronized (mLock) {
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002498 ArraySet<String> newImplicitPermissions = new ArraySet<>();
2499
Nate Myrenc6900622020-03-31 11:54:31 -07002500 // TODO ntmyren: Remove once propagated to droidfood
2501 int flagMask = PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED
2502 | PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED;
2503 int user = UserHandle.getUserId(pkg.getUid());
2504
Winson14ff7172019-10-23 10:42:27 -07002505 final int N = pkg.getRequestedPermissions().size();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002506 for (int i = 0; i < N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002507 final String permName = pkg.getRequestedPermissions().get(i);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002508 final BasePermission bp = mSettings.getPermissionLocked(permName);
Nate Myrenc6900622020-03-31 11:54:31 -07002509
2510 // TODO ntmyren: Remove once propagated to droidfood
2511 if (bp != null && !bp.isRuntime()) {
2512 PermissionState permState = permissionsState.getInstallPermissionState(bp.name);
2513 if (permState == null || (permState.getFlags() & flagMask) != 0) {
2514 permissionsState.updatePermissionFlags(bp, user, flagMask, 0);
2515 }
2516 }
2517
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002518 final boolean appSupportsRuntimePermissions =
Winson14ff7172019-10-23 10:42:27 -07002519 pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;
Zimuzoe6411402019-05-13 16:32:57 +01002520 String upgradedActivityRecognitionPermission = null;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002521
Songchun Fanbcc899e2020-04-06 16:51:45 -07002522 if (DEBUG_INSTALL && bp != null) {
Winson14ff7172019-10-23 10:42:27 -07002523 Log.i(TAG, "Package " + pkg.getPackageName()
2524 + " checking " + permName + ": " + bp);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002525 }
2526
2527 if (bp == null || bp.getSourcePackageSetting() == null) {
Winson14ff7172019-10-23 10:42:27 -07002528 if (packageOfInterest == null || packageOfInterest.equals(
2529 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002530 if (DEBUG_PERMISSIONS) {
2531 Slog.i(TAG, "Unknown permission " + permName
Winson14ff7172019-10-23 10:42:27 -07002532 + " in package " + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002533 }
2534 }
2535 continue;
2536 }
2537
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002538 // Cache newImplicitPermissions before modifing permissionsState as for the shared
2539 // uids the original and new state are the same object
2540 if (!origPermissions.hasRequestedPermission(permName)
Winson14ff7172019-10-23 10:42:27 -07002541 && (pkg.getImplicitPermissions().contains(permName)
Zimuzoe6411402019-05-13 16:32:57 +01002542 || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
Winson14ff7172019-10-23 10:42:27 -07002543 if (pkg.getImplicitPermissions().contains(permName)) {
Zimuzoe6411402019-05-13 16:32:57 +01002544 // If permName is an implicit permission, try to auto-grant
2545 newImplicitPermissions.add(permName);
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002546
Zimuzoe6411402019-05-13 16:32:57 +01002547 if (DEBUG_PERMISSIONS) {
Winson14ff7172019-10-23 10:42:27 -07002548 Slog.i(TAG, permName + " is newly added for " + pkg.getPackageName());
Zimuzoe6411402019-05-13 16:32:57 +01002549 }
2550 } else {
2551 // Special case for Activity Recognition permission. Even if AR permission
2552 // is not an implicit permission we want to add it to the list (try to
2553 // auto-grant it) if the app was installed on a device before AR permission
2554 // was split, regardless of if the app now requests the new AR permission
2555 // or has updated its target SDK and AR is no longer implicit to it.
2556 // This is a compatibility workaround for apps when AR permission was
2557 // split in Q.
Anthony Hughde787d42019-08-22 15:35:48 -07002558 final List<SplitPermissionInfoParcelable> permissionList =
2559 getSplitPermissions();
2560 int numSplitPerms = permissionList.size();
Zimuzoe6411402019-05-13 16:32:57 +01002561 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
Anthony Hughde787d42019-08-22 15:35:48 -07002562 SplitPermissionInfoParcelable sp = permissionList.get(splitPermNum);
Zimuzoe6411402019-05-13 16:32:57 +01002563 String splitPermName = sp.getSplitPermission();
2564 if (sp.getNewPermissions().contains(permName)
2565 && origPermissions.hasInstallPermission(splitPermName)) {
2566 upgradedActivityRecognitionPermission = splitPermName;
2567 newImplicitPermissions.add(permName);
2568
2569 if (DEBUG_PERMISSIONS) {
2570 Slog.i(TAG, permName + " is newly added for "
Winson14ff7172019-10-23 10:42:27 -07002571 + pkg.getPackageName());
Zimuzoe6411402019-05-13 16:32:57 +01002572 }
2573 break;
2574 }
2575 }
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002576 }
2577 }
2578
Winson5e0a1d52020-01-24 12:00:33 -08002579 // TODO(b/140256621): The package instant app method has been removed
2580 // as part of work in b/135203078, so this has been commented out in the meantime
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002581 // Limit ephemeral apps to ephemeral allowed permissions.
Winson5e0a1d52020-01-24 12:00:33 -08002582// if (/*pkg.isInstantApp()*/ false && !bp.isInstant()) {
2583// if (DEBUG_PERMISSIONS) {
2584// Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
2585// + " for package " + pkg.getPackageName());
2586// }
2587// continue;
2588// }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002589
2590 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
2591 if (DEBUG_PERMISSIONS) {
2592 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
Winson14ff7172019-10-23 10:42:27 -07002593 + " for package " + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002594 }
2595 continue;
2596 }
2597
2598 final String perm = bp.getName();
2599 boolean allowedSig = false;
2600 int grant = GRANT_DENIED;
2601
2602 // Keep track of app op permissions.
2603 if (bp.isAppOp()) {
Winson14ff7172019-10-23 10:42:27 -07002604 mSettings.addAppOpPackage(perm, pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002605 }
2606
2607 if (bp.isNormal()) {
2608 // For all apps normal permissions are install time ones.
2609 grant = GRANT_INSTALL;
2610 } else if (bp.isRuntime()) {
Zimuzoe6411402019-05-13 16:32:57 +01002611 if (origPermissions.hasInstallPermission(bp.getName())
2612 || upgradedActivityRecognitionPermission != null) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002613 // Before Q we represented some runtime permissions as install permissions,
2614 // in Q we cannot do this anymore. Hence upgrade them all.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002615 grant = GRANT_UPGRADE;
2616 } else {
2617 // For modern apps keep runtime permissions unchanged.
2618 grant = GRANT_RUNTIME;
2619 }
2620 } else if (bp.isSignature()) {
2621 // For all apps signature permissions are install time ones.
Winsone0756292020-01-31 12:21:54 -08002622 allowedSig = grantSignaturePermission(perm, pkg, ps, bp, origPermissions);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002623 if (allowedSig) {
2624 grant = GRANT_INSTALL;
2625 }
2626 }
2627
2628 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002629 Slog.i(TAG, "Considering granting permission " + perm + " to package "
Winson14ff7172019-10-23 10:42:27 -07002630 + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002631 }
2632
2633 if (grant != GRANT_DENIED) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002634 if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002635 // If this is an existing, non-system package, then
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002636 // we can't add any new permissions to it. Runtime
2637 // permissions can be added any time - they ad dynamic.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002638 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
2639 // Except... if this is a permission that was added
2640 // to the platform (note: need to only do this when
2641 // updating the platform).
2642 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
2643 grant = GRANT_DENIED;
2644 }
2645 }
2646 }
2647
2648 switch (grant) {
2649 case GRANT_INSTALL: {
2650 // Revoke this as runtime permission to handle the case of
2651 // a runtime permission being downgraded to an install one.
2652 // Also in permission review mode we keep dangerous permissions
2653 // for legacy apps
2654 for (int userId : UserManagerService.getInstance().getUserIds()) {
2655 if (origPermissions.getRuntimePermissionState(
2656 perm, userId) != null) {
2657 // Revoke the runtime permission and clear the flags.
2658 origPermissions.revokeRuntimePermission(bp, userId);
2659 origPermissions.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002660 PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002661 // If we revoked a permission permission, we have to write.
2662 updatedUserIds = ArrayUtils.appendInt(
2663 updatedUserIds, userId);
2664 }
2665 }
2666 // Grant an install permission.
2667 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002668 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002669 changedInstallPermission = true;
2670 }
2671 } break;
2672
2673 case GRANT_RUNTIME: {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002674 boolean hardRestricted = bp.isHardRestricted();
2675 boolean softRestricted = bp.isSoftRestricted();
2676
Philip P. Moltmann48456672019-01-20 13:14:03 -08002677 for (int userId : currentUserIds) {
Svet Ganov3c499ea2019-07-26 17:45:56 -07002678 // If permission policy is not ready we don't deal with restricted
2679 // permissions as the policy may whitelist some permissions. Once
2680 // the policy is initialized we would re-evaluate permissions.
2681 final boolean permissionPolicyInitialized =
2682 mPermissionPolicyInternal != null
2683 && mPermissionPolicyInternal.isInitialized(userId);
2684
Philip P. Moltmann48456672019-01-20 13:14:03 -08002685 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002686 .getRuntimePermissionState(perm, userId);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002687 int flags = permState != null ? permState.getFlags() : 0;
2688
2689 boolean wasChanged = false;
2690
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002691 boolean restrictionExempt =
2692 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002693 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2694 boolean restrictionApplied = (origPermissions.getPermissionFlags(
2695 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2696
Philip P. Moltmann48456672019-01-20 13:14:03 -08002697 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002698 // If hard restricted we don't allow holding it
Svet Ganov3c499ea2019-07-26 17:45:56 -07002699 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002700 if (!restrictionExempt) {
2701 if (permState != null && permState.isGranted()
2702 && permissionsState.revokeRuntimePermission(
2703 bp, userId) != PERMISSION_OPERATION_FAILURE) {
2704 wasChanged = true;
2705 }
2706 if (!restrictionApplied) {
2707 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2708 wasChanged = true;
2709 }
2710 }
2711 // If soft restricted we allow holding in a restricted form
Svet Ganov3c499ea2019-07-26 17:45:56 -07002712 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002713 // Regardless if granted set the restriction flag as it
2714 // may affect app treatment based on this permission.
2715 if (!restrictionExempt && !restrictionApplied) {
2716 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2717 wasChanged = true;
2718 }
2719 }
2720
Philip P. Moltmann48456672019-01-20 13:14:03 -08002721 // Remove review flag as it is not necessary anymore
2722 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2723 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2724 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002725 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002726
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002727 if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
2728 flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002729 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002730 // Hard restricted permissions cannot be held.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002731 } else if (!permissionPolicyInitialized
2732 || (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002733 if (permState != null && permState.isGranted()) {
2734 if (permissionsState.grantRuntimePermission(bp, userId)
2735 == PERMISSION_OPERATION_FAILURE) {
2736 wasChanged = true;
2737 }
2738 }
2739 }
2740 } else {
2741 if (permState == null) {
2742 // New permission
2743 if (PLATFORM_PACKAGE_NAME.equals(
2744 bp.getSourcePackageName())) {
2745 if (!bp.isRemoved()) {
2746 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002747 | FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002748 wasChanged = true;
2749 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002750 }
2751 }
2752
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002753 if (!permissionsState.hasRuntimePermission(bp.name, userId)
2754 && permissionsState.grantRuntimePermission(bp, userId)
2755 != PERMISSION_OPERATION_FAILURE) {
2756 wasChanged = true;
2757 }
2758
2759 // If legacy app always grant the permission but if restricted
2760 // and not exempt take a note a restriction should be applied.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002761 if (permissionPolicyInitialized
2762 && (hardRestricted || softRestricted)
2763 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002764 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2765 wasChanged = true;
2766 }
2767 }
2768
2769 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002770 if (permissionPolicyInitialized) {
2771 if (!(hardRestricted || softRestricted) || restrictionExempt) {
2772 if (restrictionApplied) {
2773 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2774 // Dropping restriction on a legacy app implies a review
2775 if (!appSupportsRuntimePermissions) {
2776 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2777 }
2778 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002779 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002780 }
2781 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002782
2783 if (wasChanged) {
2784 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2785 }
2786
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08002787 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002788 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002789 }
2790 } break;
2791
2792 case GRANT_UPGRADE: {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002793 // Upgrade from Pre-Q to Q permission model. Make all permissions
2794 // runtime
2795 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002796 .getInstallPermissionState(perm);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002797 int flags = (permState != null) ? permState.getFlags() : 0;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002798
Zimuzoe6411402019-05-13 16:32:57 +01002799 BasePermission bpToRevoke =
2800 upgradedActivityRecognitionPermission == null
2801 ? bp : mSettings.getPermissionLocked(
2802 upgradedActivityRecognitionPermission);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002803 // Remove install permission
Zimuzoe6411402019-05-13 16:32:57 +01002804 if (origPermissions.revokeInstallPermission(bpToRevoke)
Philip P. Moltmann48456672019-01-20 13:14:03 -08002805 != PERMISSION_OPERATION_FAILURE) {
Zimuzoe6411402019-05-13 16:32:57 +01002806 origPermissions.updatePermissionFlags(bpToRevoke,
2807 UserHandle.USER_ALL,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002808 (MASK_PERMISSION_FLAGS_ALL
2809 & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002810 changedInstallPermission = true;
2811 }
2812
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002813 boolean hardRestricted = bp.isHardRestricted();
2814 boolean softRestricted = bp.isSoftRestricted();
2815
Philip P. Moltmann48456672019-01-20 13:14:03 -08002816 for (int userId : currentUserIds) {
Svet Ganov3c499ea2019-07-26 17:45:56 -07002817 // If permission policy is not ready we don't deal with restricted
2818 // permissions as the policy may whitelist some permissions. Once
2819 // the policy is initialized we would re-evaluate permissions.
2820 final boolean permissionPolicyInitialized =
2821 mPermissionPolicyInternal != null
2822 && mPermissionPolicyInternal.isInitialized(userId);
2823
Philip P. Moltmann48456672019-01-20 13:14:03 -08002824 boolean wasChanged = false;
2825
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002826 boolean restrictionExempt =
2827 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002828 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2829 boolean restrictionApplied = (origPermissions.getPermissionFlags(
2830 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2831
Philip P. Moltmann48456672019-01-20 13:14:03 -08002832 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002833 // If hard restricted we don't allow holding it
Svet Ganov3c499ea2019-07-26 17:45:56 -07002834 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002835 if (!restrictionExempt) {
2836 if (permState != null && permState.isGranted()
2837 && permissionsState.revokeRuntimePermission(
2838 bp, userId) != PERMISSION_OPERATION_FAILURE) {
2839 wasChanged = true;
2840 }
2841 if (!restrictionApplied) {
2842 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2843 wasChanged = true;
2844 }
2845 }
2846 // If soft restricted we allow holding in a restricted form
Svet Ganov3c499ea2019-07-26 17:45:56 -07002847 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002848 // Regardless if granted set the restriction flag as it
2849 // may affect app treatment based on this permission.
2850 if (!restrictionExempt && !restrictionApplied) {
2851 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2852 wasChanged = true;
2853 }
2854 }
2855
Philip P. Moltmann48456672019-01-20 13:14:03 -08002856 // Remove review flag as it is not necessary anymore
2857 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2858 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2859 wasChanged = true;
2860 }
2861
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002862 if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
2863 flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002864 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002865 // Hard restricted permissions cannot be held.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002866 } else if (!permissionPolicyInitialized ||
2867 (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002868 if (permissionsState.grantRuntimePermission(bp, userId) !=
2869 PERMISSION_OPERATION_FAILURE) {
2870 wasChanged = true;
2871 }
2872 }
2873 } else {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002874 if (!permissionsState.hasRuntimePermission(bp.name, userId)
2875 && permissionsState.grantRuntimePermission(bp,
2876 userId) != PERMISSION_OPERATION_FAILURE) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002877 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2878 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002879 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002880
2881 // If legacy app always grant the permission but if restricted
2882 // and not exempt take a note a restriction should be applied.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002883 if (permissionPolicyInitialized
2884 && (hardRestricted || softRestricted)
2885 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002886 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2887 wasChanged = true;
2888 }
2889 }
2890
2891 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002892 if (permissionPolicyInitialized) {
2893 if (!(hardRestricted || softRestricted) || restrictionExempt) {
2894 if (restrictionApplied) {
2895 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2896 // Dropping restriction on a legacy app implies a review
2897 if (!appSupportsRuntimePermissions) {
2898 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2899 }
2900 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002901 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002902 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002903 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002904
2905 if (wasChanged) {
2906 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2907 }
2908
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08002909 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002910 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002911 }
2912 } break;
2913
2914 default: {
2915 if (packageOfInterest == null
Winson14ff7172019-10-23 10:42:27 -07002916 || packageOfInterest.equals(pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002917 if (DEBUG_PERMISSIONS) {
2918 Slog.i(TAG, "Not granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002919 + " to package " + pkg.getPackageName()
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002920 + " because it was previously installed without");
2921 }
2922 }
2923 } break;
2924 }
2925 } else {
2926 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002927 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002928 // Also drop the permission flags.
2929 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002930 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002931 changedInstallPermission = true;
Nate Myrened67bdd2019-05-07 10:32:22 -07002932 if (DEBUG_PERMISSIONS) {
2933 Slog.i(TAG, "Un-granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002934 + " from package " + pkg.getPackageName()
Nate Myrened67bdd2019-05-07 10:32:22 -07002935 + " (protectionLevel=" + bp.getProtectionLevel()
Winsonf00c7552020-01-28 12:52:01 -08002936 + " flags=0x"
2937 + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, ps))
Nate Myrened67bdd2019-05-07 10:32:22 -07002938 + ")");
2939 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002940 } else if (bp.isAppOp()) {
2941 // Don't print warning for app op permissions, since it is fine for them
2942 // not to be granted, there is a UI for the user to decide.
2943 if (DEBUG_PERMISSIONS
2944 && (packageOfInterest == null
Winson14ff7172019-10-23 10:42:27 -07002945 || packageOfInterest.equals(pkg.getPackageName()))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002946 Slog.i(TAG, "Not granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002947 + " to package " + pkg.getPackageName()
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002948 + " (protectionLevel=" + bp.getProtectionLevel()
Winsonf00c7552020-01-28 12:52:01 -08002949 + " flags=0x"
2950 + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, ps))
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002951 + ")");
2952 }
2953 }
2954 }
2955 }
2956
2957 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
Winson8359e402020-02-21 17:32:14 -08002958 !ps.isSystem() || ps.getPkgState().isUpdatedSystemApp()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002959 // This is the first that we have heard about this package, so the
2960 // permissions we have now selected are fixed until explicitly
2961 // changed.
2962 ps.setInstallPermissionsFixed(true);
2963 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002964
2965 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
2966 updatedUserIds);
2967 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002968 permissionsState, pkg, newImplicitPermissions, updatedUserIds);
Philip P. Moltmann74065c82019-05-15 10:46:32 -07002969 updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002970 }
2971
2972 // Persist the runtime permissions state for users with changes. If permissions
2973 // were revoked because no app in the shared user declares them we have to
2974 // write synchronously to avoid losing runtime permissions state.
2975 if (callback != null) {
2976 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
2977 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002978
2979 for (int userId : updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07002980 notifyRuntimePermissionStateChanged(pkg.getPackageName(), userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002981 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002982 }
2983
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002984 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002985 * Revoke permissions that are not implicit anymore and that have
2986 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
2987 *
2988 * @param ps The state of the permissions of the package
2989 * @param pkg The package that is currently looked at
2990 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
2991 * for a user is changed.
2992 *
2993 * @return The updated value of the {@code updatedUserIds} parameter
2994 */
2995 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
Winson14ff7172019-10-23 10:42:27 -07002996 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002997 @NonNull int[] updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07002998 String pkgName = pkg.getPackageName();
2999 boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
Philip P. Moltmannd030ce22019-02-18 21:05:48 -08003000 >= Build.VERSION_CODES.M;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003001
3002 int[] users = UserManagerService.getInstance().getUserIds();
3003 int numUsers = users.length;
3004 for (int i = 0; i < numUsers; i++) {
3005 int userId = users[i];
3006
3007 for (String permission : ps.getPermissions(userId)) {
Winson14ff7172019-10-23 10:42:27 -07003008 if (!pkg.getImplicitPermissions().contains(permission)) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003009 if (!ps.hasInstallPermission(permission)) {
3010 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
3011
3012 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
3013 BasePermission bp = mSettings.getPermissionLocked(permission);
3014
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08003015 int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003016
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08003017 if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
3018 && supportsRuntimePermissions) {
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08003019 int revokeResult = ps.revokeRuntimePermission(bp, userId);
3020 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
3021 if (DEBUG_PERMISSIONS) {
3022 Slog.i(TAG, "Revoking runtime permission "
3023 + permission + " for " + pkgName
3024 + " as it is now requested");
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003025 }
3026 }
3027
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08003028 flagsToRemove |= USER_PERMISSION_FLAGS;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003029 }
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08003030
3031 ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
3032 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003033 }
3034 }
3035 }
3036 }
3037 }
3038
3039 return updatedUserIds;
3040 }
3041
3042 /**
3043 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
3044 *
3045 * <p>A single new permission can be split off from several source permissions. In this case
3046 * the most leniant state is inherited.
3047 *
3048 * <p>Warning: This does not handle foreground / background permissions
3049 *
3050 * @param sourcePerms The permissions to inherit from
3051 * @param newPerm The permission to inherit to
3052 * @param ps The permission state of the package
3053 * @param pkg The package requesting the permissions
3054 * @param userId The user the permission belongs to
3055 */
3056 private void inheritPermissionStateToNewImplicitPermissionLocked(
3057 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
Winson14ff7172019-10-23 10:42:27 -07003058 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003059 @UserIdInt int userId) {
Winson14ff7172019-10-23 10:42:27 -07003060 String pkgName = pkg.getPackageName();
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003061 boolean isGranted = false;
3062 int flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003063
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003064 int numSourcePerm = sourcePerms.size();
3065 for (int i = 0; i < numSourcePerm; i++) {
3066 String sourcePerm = sourcePerms.valueAt(i);
3067 if ((ps.hasRuntimePermission(sourcePerm, userId))
3068 || ps.hasInstallPermission(sourcePerm)) {
3069 if (!isGranted) {
3070 flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003071 }
3072
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003073 isGranted = true;
3074 flags |= ps.getPermissionFlags(sourcePerm, userId);
3075 } else {
3076 if (!isGranted) {
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08003077 flags |= ps.getPermissionFlags(sourcePerm, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003078 }
3079 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003080 }
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003081
3082 if (isGranted) {
3083 if (DEBUG_PERMISSIONS) {
3084 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
3085 + " for " + pkgName);
3086 }
3087
3088 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
3089 }
3090
3091 // Add permission flags
3092 ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003093 }
3094
3095 /**
Philip P. Moltmann74065c82019-05-15 10:46:32 -07003096 * When the app has requested legacy storage we might need to update
3097 * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
3098 * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
3099 *
3100 * @param pkg The package for which the permissions are updated
3101 * @param replace If the app is being replaced
3102 * @param updatedUserIds The ids of the users that already changed.
3103 *
3104 * @return The ids of the users that are changed
3105 */
3106 private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
Winson14ff7172019-10-23 10:42:27 -07003107 @NonNull AndroidPackage pkg, boolean replace, @NonNull int[] updatedUserIds) {
Winson5e0a1d52020-01-24 12:00:33 -08003108 if (replace && pkg.isRequestLegacyExternalStorage() && (
Winson14ff7172019-10-23 10:42:27 -07003109 pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
3110 || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
Philip P. Moltmann74065c82019-05-15 10:46:32 -07003111 return UserManagerService.getInstance().getUserIds();
3112 }
3113
3114 return updatedUserIds;
3115 }
3116
3117 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003118 * Set the state of a implicit permission that is seen for the first time.
3119 *
3120 * @param origPs The permission state of the package before the split
3121 * @param ps The new permission state
3122 * @param pkg The package the permission belongs to
3123 * @param updatedUserIds List of users for which the permission state has already been changed
3124 *
3125 * @return List of users for which the permission state has been changed
3126 */
3127 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
3128 @NonNull PermissionsState origPs,
Winson14ff7172019-10-23 10:42:27 -07003129 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07003130 @NonNull ArraySet<String> newImplicitPermissions,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003131 @NonNull int[] updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07003132 String pkgName = pkg.getPackageName();
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003133 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
3134
Anthony Hughde787d42019-08-22 15:35:48 -07003135 final List<SplitPermissionInfoParcelable> permissionList = getSplitPermissions();
3136 int numSplitPerms = permissionList.size();
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003137 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
Anthony Hughde787d42019-08-22 15:35:48 -07003138 SplitPermissionInfoParcelable spi = permissionList.get(splitPermNum);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003139
3140 List<String> newPerms = spi.getNewPermissions();
3141 int numNewPerms = newPerms.size();
3142 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
3143 String newPerm = newPerms.get(newPermNum);
3144
3145 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
3146 if (splitPerms == null) {
3147 splitPerms = new ArraySet<>();
3148 newToSplitPerms.put(newPerm, splitPerms);
3149 }
3150
3151 splitPerms.add(spi.getSplitPermission());
3152 }
3153 }
3154
3155 int numNewImplicitPerms = newImplicitPermissions.size();
3156 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
3157 newImplicitPermNum++) {
3158 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
3159 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
3160
3161 if (sourcePerms != null) {
3162 if (!ps.hasInstallPermission(newPerm)) {
3163 BasePermission bp = mSettings.getPermissionLocked(newPerm);
3164
3165 int[] users = UserManagerService.getInstance().getUserIds();
3166 int numUsers = users.length;
3167 for (int userNum = 0; userNum < numUsers; userNum++) {
3168 int userId = users[userNum];
3169
Zimuzoe6411402019-05-13 16:32:57 +01003170 if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
3171 ps.updatePermissionFlags(bp, userId,
3172 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
3173 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
3174 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003175 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
3176
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003177 boolean inheritsFromInstallPerm = false;
3178 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
3179 sourcePermNum++) {
3180 if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
3181 inheritsFromInstallPerm = true;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07003182 break;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07003183 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003184 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003185
3186 if (!origPs.hasRequestedPermission(sourcePerms)
3187 && !inheritsFromInstallPerm) {
3188 // Both permissions are new so nothing to inherit.
3189 if (DEBUG_PERMISSIONS) {
3190 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
3191 + " for " + pkgName + " as split permission is also new");
3192 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003193 } else {
3194 // Inherit from new install or existing runtime permissions
3195 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
3196 newPerm, ps, pkg, userId);
3197 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003198 }
3199 }
3200 }
3201 }
3202
3203 return updatedUserIds;
3204 }
3205
Anthony Hughde787d42019-08-22 15:35:48 -07003206 @Override
3207 public List<SplitPermissionInfoParcelable> getSplitPermissions() {
3208 return PermissionManager.splitPermissionInfoListToParcelableList(
3209 SystemConfig.getInstance().getSplitPermissions());
3210 }
3211
Evan Seversonb252d8b2019-11-20 08:41:33 -08003212 private OneTimePermissionUserManager getOneTimePermissionUserManager(@UserIdInt int userId) {
3213 synchronized (mLock) {
3214 OneTimePermissionUserManager oneTimePermissionUserManager =
3215 mOneTimePermissionUserManagers.get(userId);
3216 if (oneTimePermissionUserManager == null) {
3217 oneTimePermissionUserManager = new OneTimePermissionUserManager(
3218 mContext.createContextAsUser(UserHandle.of(userId), /*flags*/ 0));
3219 mOneTimePermissionUserManagers.put(userId, oneTimePermissionUserManager);
3220 }
3221 return oneTimePermissionUserManager;
3222 }
3223 }
3224
3225 @Override
3226 public void startOneTimePermissionSession(String packageName, @UserIdInt int userId,
3227 long timeoutMillis, int importanceToResetTimer, int importanceToKeepSessionAlive) {
Evan Severson43e17e02020-01-03 10:04:38 -08003228 mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
3229 "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
3230 + " to register permissions as one time.");
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00003231 Objects.requireNonNull(packageName);
Evan Seversonb252d8b2019-11-20 08:41:33 -08003232
3233 long token = Binder.clearCallingIdentity();
3234 try {
3235 getOneTimePermissionUserManager(userId).startPackageOneTimeSession(packageName,
3236 timeoutMillis, importanceToResetTimer, importanceToKeepSessionAlive);
3237 } finally {
3238 Binder.restoreCallingIdentity(token);
3239 }
3240 }
3241
3242 @Override
3243 public void stopOneTimePermissionSession(String packageName, @UserIdInt int userId) {
Evan Severson43e17e02020-01-03 10:04:38 -08003244 mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
3245 "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
3246 + " to remove permissions as one time.");
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00003247 Objects.requireNonNull(packageName);
Evan Seversonb252d8b2019-11-20 08:41:33 -08003248
3249 long token = Binder.clearCallingIdentity();
3250 try {
3251 getOneTimePermissionUserManager(userId).stopPackageOneTimeSession(packageName);
3252 } finally {
3253 Binder.restoreCallingIdentity(token);
3254 }
3255 }
3256
Eugene Susladb77bc12020-03-03 12:09:00 -08003257 @Override
3258 public List<String> getAutoRevokeExemptionRequestedPackages(int userId) {
Eugene Susla49b84c32020-03-23 15:19:29 -07003259 return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISCOURAGED, userId);
Eugene Susladb77bc12020-03-03 12:09:00 -08003260 }
3261
3262 @Override
3263 public List<String> getAutoRevokeExemptionGrantedPackages(int userId) {
Eugene Susla49b84c32020-03-23 15:19:29 -07003264 return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISALLOWED, userId);
3265 }
3266
3267 @NonNull
3268 private List<String> getPackagesWithAutoRevokePolicy(int autoRevokePolicy, int userId) {
Eugene Susladb77bc12020-03-03 12:09:00 -08003269 mContext.enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
3270 "Must hold " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
3271
3272 List<String> result = new ArrayList<>();
3273 mPackageManagerInt.forEachInstalledPackage(pkg -> {
Eugene Susla49b84c32020-03-23 15:19:29 -07003274 if (pkg.getAutoRevokePermissions() == autoRevokePolicy) {
Eugene Susladb77bc12020-03-03 12:09:00 -08003275 result.add(pkg.getPackageName());
3276 }
3277 }, userId);
Eugene Susladb77bc12020-03-03 12:09:00 -08003278 return result;
3279 }
3280
Winson14ff7172019-10-23 10:42:27 -07003281 private boolean isNewPlatformPermissionForPackage(String perm, AndroidPackage pkg) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003282 boolean allowed = false;
3283 final int NP = PackageParser.NEW_PERMISSIONS.length;
3284 for (int ip=0; ip<NP; ip++) {
3285 final PackageParser.NewPermissionInfo npi
3286 = PackageParser.NEW_PERMISSIONS[ip];
3287 if (npi.name.equals(perm)
Winson14ff7172019-10-23 10:42:27 -07003288 && pkg.getTargetSdkVersion() < npi.sdkVersion) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003289 allowed = true;
3290 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
Winson14ff7172019-10-23 10:42:27 -07003291 + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003292 break;
3293 }
3294 }
3295 return allowed;
3296 }
3297
3298 /**
3299 * Determines whether a package is whitelisted for a particular privapp permission.
3300 *
3301 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
3302 *
3303 * <p>This handles parent/child apps.
3304 */
Winson14ff7172019-10-23 10:42:27 -07003305 private boolean hasPrivappWhitelistEntry(String perm, AndroidPackage pkg) {
3306 ArraySet<String> wlPermissions;
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003307 if (pkg.isVendor()) {
3308 wlPermissions =
Winson14ff7172019-10-23 10:42:27 -07003309 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003310 } else if (pkg.isProduct()) {
3311 wlPermissions =
Winson14ff7172019-10-23 10:42:27 -07003312 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.getPackageName());
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003313 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01003314 wlPermissions =
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003315 SystemConfig.getInstance().getSystemExtPrivAppPermissions(
Winson14ff7172019-10-23 10:42:27 -07003316 pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003317 } else {
Winson14ff7172019-10-23 10:42:27 -07003318 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003319 }
Winson14ff7172019-10-23 10:42:27 -07003320
3321 return wlPermissions != null && wlPermissions.contains(perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003322 }
3323
Winson14ff7172019-10-23 10:42:27 -07003324 private boolean grantSignaturePermission(String perm, AndroidPackage pkg,
Winsone0756292020-01-31 12:21:54 -08003325 PackageSetting pkgSetting, BasePermission bp, PermissionsState origPermissions) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003326 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09003327 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
3328 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003329 boolean privappPermissionsDisable =
3330 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
3331 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07003332 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003333 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
3334 && !platformPackage && platformPermission) {
3335 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Philip P. Moltmannbd278012020-03-10 14:46:27 -07003336 // Only enforce whitelist this on boot
3337 if (!mSystemReady
3338 // Updated system apps do not need to be whitelisted
Philip P. Moltmann67655a12020-03-26 17:22:40 -07003339 && !pkgSetting.getPkgState().isUpdatedSystemApp()) {
3340 ApexManager apexMgr = ApexManager.getInstance();
3341 String apexContainingPkg = apexMgr.getActiveApexPackageNameContainingPackage(
3342 pkg);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07003343
Philip P. Moltmann67655a12020-03-26 17:22:40 -07003344 // Apps that are in updated apexs' do not need to be whitelisted
3345 if (apexContainingPkg == null || apexMgr.isFactory(
3346 apexMgr.getPackageInfo(apexContainingPkg, MATCH_ACTIVE_PACKAGE))) {
3347 // it's only a reportable violation if the permission isn't explicitly
3348 // denied
3349 ArraySet<String> deniedPermissions = null;
3350 if (pkg.isVendor()) {
3351 deniedPermissions = SystemConfig.getInstance()
3352 .getVendorPrivAppDenyPermissions(pkg.getPackageName());
3353 } else if (pkg.isProduct()) {
3354 deniedPermissions = SystemConfig.getInstance()
3355 .getProductPrivAppDenyPermissions(pkg.getPackageName());
3356 } else if (pkg.isSystemExt()) {
3357 deniedPermissions = SystemConfig.getInstance()
3358 .getSystemExtPrivAppDenyPermissions(pkg.getPackageName());
3359 } else {
3360 deniedPermissions = SystemConfig.getInstance()
3361 .getPrivAppDenyPermissions(pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003362 }
Philip P. Moltmann67655a12020-03-26 17:22:40 -07003363 final boolean permissionViolation =
3364 deniedPermissions == null || !deniedPermissions.contains(perm);
3365 if (permissionViolation) {
3366 Slog.w(TAG, "Privileged permission " + perm + " for package "
3367 + pkg.getPackageName() + " (" + pkg.getCodePath()
3368 + ") not in privapp-permissions whitelist");
3369
3370 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3371 if (mPrivappPermissionsViolations == null) {
3372 mPrivappPermissionsViolations = new ArraySet<>();
3373 }
3374 mPrivappPermissionsViolations.add(
3375 pkg.getPackageName() + " (" + pkg.getCodePath() + "): "
3376 + perm);
3377 }
3378 } else {
3379 return false;
3380 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003381 }
3382 }
3383 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3384 return false;
3385 }
3386 }
3387 }
Chen Xu45c183d2019-10-07 00:24:41 -07003388 // expect single system package
3389 String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
3390 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM));
Winson655a5b92019-10-23 10:49:32 -07003391 final AndroidPackage systemPackage =
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003392 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003393
3394 // check if the package is allow to use this signature permission. A package is allowed to
3395 // use a signature permission if:
3396 // - it has the same set of signing certificates as the source package
3397 // - or its signing certificate was rotated from the source package's certificate
3398 // - or its signing certificate is a previous signing certificate of the defining
3399 // package, and the defining package still trusts the old certificate for permissions
3400 // - or it shares the above relationships with the system package
3401 boolean allowed =
Winson14ff7172019-10-23 10:42:27 -07003402 pkg.getSigningDetails().hasAncestorOrSelf(
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003403 bp.getSourcePackageSetting().getSigningDetails())
3404 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
Winson14ff7172019-10-23 10:42:27 -07003405 pkg.getSigningDetails(),
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003406 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
Winson14ff7172019-10-23 10:42:27 -07003407 || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails())
3408 || systemPackage.getSigningDetails().checkCapability(
3409 pkg.getSigningDetails(),
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003410 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003411 if (!allowed && (privilegedPermission || oemPermission)) {
3412 if (pkg.isSystem()) {
3413 // For updated system applications, a privileged/oem permission
3414 // is granted only if it had been defined by the original application.
Winsone0756292020-01-31 12:21:54 -08003415 if (pkgSetting.getPkgState().isUpdatedSystemApp()) {
3416 final PackageSetting disabledPs = mPackageManagerInt
Winson14ff7172019-10-23 10:42:27 -07003417 .getDisabledSystemPackage(pkg.getPackageName());
3418 final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.pkg;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003419 if (disabledPs != null
3420 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
3421 // If the original was granted this permission, we take
3422 // that grant decision as read and propagate it to the
3423 // update.
3424 if ((privilegedPermission && disabledPs.isPrivileged())
3425 || (oemPermission && disabledPs.isOem()
3426 && canGrantOemPermission(disabledPs, perm))) {
3427 allowed = true;
3428 }
3429 } else {
3430 // The system apk may have been updated with an older
3431 // version of the one on the data partition, but which
3432 // granted a new system permission that it didn't have
3433 // before. In this case we do want to allow the app to
3434 // now get the new permission if the ancestral apk is
3435 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07003436 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003437 && isPackageRequestingPermission(disabledPkg, perm)
3438 && ((privilegedPermission && disabledPs.isPrivileged())
3439 || (oemPermission && disabledPs.isOem()
3440 && canGrantOemPermission(disabledPs, perm)))) {
3441 allowed = true;
3442 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003443 }
3444 } else {
Winson14ff7172019-10-23 10:42:27 -07003445 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3446 pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003447 allowed = (privilegedPermission && pkg.isPrivileged())
3448 || (oemPermission && pkg.isOem()
3449 && canGrantOemPermission(ps, perm));
3450 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09003451 // In any case, don't grant a privileged permission to privileged vendor apps, if
3452 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
3453 // flag.
3454 if (allowed && privilegedPermission &&
3455 !vendorPrivilegedPermission && pkg.isVendor()) {
3456 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
Winson14ff7172019-10-23 10:42:27 -07003457 + pkg.getPackageName()
3458 + " because it isn't a 'vendorPrivileged' permission.");
Jiyong Park002fdbd2017-02-13 20:50:31 +09003459 allowed = false;
3460 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003461 }
3462 }
3463 if (!allowed) {
3464 if (!allowed
3465 && bp.isPre23()
Winson14ff7172019-10-23 10:42:27 -07003466 && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003467 // If this was a previously normal/dangerous permission that got moved
3468 // to a system permission as part of the runtime permission redesign, then
3469 // we still want to blindly grant it to old apps.
3470 allowed = true;
3471 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07003472 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
3473 // need a separate flag anymore. Hence we need to check which
3474 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003475 if (!allowed && bp.isInstaller()
Chen Xu45c183d2019-10-07 00:24:41 -07003476 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3477 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003478 pkg.getPackageName()) || ArrayUtils.contains(
3479 mPackageManagerInt.getKnownPackageNames(
3480 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
3481 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003482 // If this permission is to be granted to the system installer and
3483 // this app is an installer, then it gets the permission.
3484 allowed = true;
3485 }
3486 if (!allowed && bp.isVerifier()
Chen Xu45c183d2019-10-07 00:24:41 -07003487 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3488 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003489 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003490 // If this permission is to be granted to the system verifier and
3491 // this app is a verifier, then it gets the permission.
3492 allowed = true;
3493 }
3494 if (!allowed && bp.isPreInstalled()
3495 && pkg.isSystem()) {
3496 // Any pre-installed system app is allowed to get this permission.
3497 allowed = true;
3498 }
3499 if (!allowed && bp.isDevelopment()) {
3500 // For development permissions, a development permission
3501 // is granted only if it was already granted.
3502 allowed = origPermissions.hasInstallPermission(perm);
3503 }
3504 if (!allowed && bp.isSetup()
Chen Xu45c183d2019-10-07 00:24:41 -07003505 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3506 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003507 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003508 // If this permission is to be granted to the system setup wizard and
3509 // this app is a setup wizard, then it gets the permission.
3510 allowed = true;
3511 }
Makoto Onuki700feef2018-02-15 10:59:41 -08003512 if (!allowed && bp.isSystemTextClassifier()
Chen Xu45c183d2019-10-07 00:24:41 -07003513 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Makoto Onuki700feef2018-02-15 10:59:41 -08003514 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
Winson655a5b92019-10-23 10:49:32 -07003515 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Makoto Onuki700feef2018-02-15 10:59:41 -08003516 // Special permissions for the system default text classifier.
3517 allowed = true;
3518 }
Stanislav Zholnin596437f2018-12-28 15:34:23 +00003519 if (!allowed && bp.isConfigurator()
Chen Xu45c183d2019-10-07 00:24:41 -07003520 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3521 PackageManagerInternal.PACKAGE_CONFIGURATOR,
Winson655a5b92019-10-23 10:49:32 -07003522 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Stanislav Zholnin596437f2018-12-28 15:34:23 +00003523 // Special permissions for the device configurator.
3524 allowed = true;
3525 }
Varun Shah5f303652018-11-16 18:11:19 -08003526 if (!allowed && bp.isWellbeing()
Chen Xu45c183d2019-10-07 00:24:41 -07003527 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3528 PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003529 pkg.getPackageName())) {
Varun Shah5f303652018-11-16 18:11:19 -08003530 // Special permission granted only to the OEM specified wellbeing app
3531 allowed = true;
3532 }
Jeff Sharkey15707b32018-12-10 12:08:41 -07003533 if (!allowed && bp.isDocumenter()
Chen Xu45c183d2019-10-07 00:24:41 -07003534 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3535 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003536 pkg.getPackageName())) {
Jeff Sharkey15707b32018-12-10 12:08:41 -07003537 // If this permission is to be granted to the documenter and
3538 // this app is the documenter, then it gets the permission.
3539 allowed = true;
3540 }
Joe Onorato5a15b552018-12-18 10:40:04 -08003541 if (!allowed && bp.isIncidentReportApprover()
Chen Xu45c183d2019-10-07 00:24:41 -07003542 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Joe Onorato5a15b552018-12-18 10:40:04 -08003543 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
Winson655a5b92019-10-23 10:49:32 -07003544 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Joe Onorato5a15b552018-12-18 10:40:04 -08003545 // If this permission is to be granted to the incident report approver and
3546 // this app is the incident report approver, then it gets the permission.
3547 allowed = true;
3548 }
George Hodulikcd7695d2019-01-29 18:17:05 -08003549 if (!allowed && bp.isAppPredictor()
Chen Xu45c183d2019-10-07 00:24:41 -07003550 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3551 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003552 pkg.getPackageName())) {
George Hodulikcd7695d2019-01-29 18:17:05 -08003553 // Special permissions for the system app predictor.
3554 allowed = true;
3555 }
Eugene Susla1fa23ed02019-07-24 16:30:16 -07003556 if (!allowed && bp.isCompanion()
3557 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3558 PackageManagerInternal.PACKAGE_COMPANION, UserHandle.USER_SYSTEM),
3559 pkg.getPackageName())) {
3560 // Special permissions for the system companion device manager.
3561 allowed = true;
3562 }
wayneyang8126b1f2020-01-09 14:10:31 +08003563 if (!allowed && bp.isRetailDemo()
3564 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3565 PackageManagerInternal.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM),
3566 pkg.getPackageName()) && isProfileOwner(pkg.getUid())) {
3567 // Special permission granted only to the OEM specified retail demo app
3568 allowed = true;
3569 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003570 }
3571 return allowed;
3572 }
3573
wayneyang8126b1f2020-01-09 14:10:31 +08003574 private static boolean isProfileOwner(int uid) {
3575 DevicePolicyManagerInternal dpmInternal =
3576 LocalServices.getService(DevicePolicyManagerInternal.class);
3577 if (dpmInternal != null) {
3578 return dpmInternal
3579 .isActiveAdminWithPolicy(uid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3580 }
3581 return false;
3582 }
3583
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003584 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
3585 if (!ps.isOem()) {
3586 return false;
3587 }
3588 // all oem permissions must explicitly be granted or denied
3589 final Boolean granted =
3590 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
3591 if (granted == null) {
3592 throw new IllegalStateException("OEM permission" + permission + " requested by package "
3593 + ps.name + " must be explicitly declared granted or not");
3594 }
3595 return Boolean.TRUE == granted;
3596 }
3597
Winson14ff7172019-10-23 10:42:27 -07003598 private boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07003599 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003600 // Permission review applies only to apps not supporting the new permission model.
Winson14ff7172019-10-23 10:42:27 -07003601 if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003602 return false;
3603 }
3604
3605 // Legacy apps have the permission and get user consent on launch.
Winson14ff7172019-10-23 10:42:27 -07003606 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3607 pkg.getPackageName());
3608 if (ps == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003609 return false;
3610 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003611 final PermissionsState permissionsState = ps.getPermissionsState();
3612 return permissionsState.isPermissionReviewRequired(userId);
3613 }
3614
Winson14ff7172019-10-23 10:42:27 -07003615 private boolean isPackageRequestingPermission(AndroidPackage pkg, String permission) {
3616 final int permCount = pkg.getRequestedPermissions().size();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003617 for (int j = 0; j < permCount; j++) {
Winson14ff7172019-10-23 10:42:27 -07003618 String requestedPermission = pkg.getRequestedPermissions().get(j);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003619 if (permission.equals(requestedPermission)) {
3620 return true;
3621 }
3622 }
3623 return false;
3624 }
3625
Winson14ff7172019-10-23 10:42:27 -07003626 private void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003627 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3628 for (int userId : userIds) {
3629 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
3630 callback);
3631 }
3632 }
3633
Winson14ff7172019-10-23 10:42:27 -07003634 private void grantRequestedRuntimePermissionsForUser(AndroidPackage pkg, int userId,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003635 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
Winson14ff7172019-10-23 10:42:27 -07003636 PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3637 pkg.getPackageName());
Todd Kennedy0eb97382017-10-03 16:57:22 -07003638 if (ps == null) {
3639 return;
3640 }
3641
3642 PermissionsState permissionsState = ps.getPermissionsState();
3643
3644 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
3645 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3646
Hai Zhangfa291702019-09-19 16:35:44 -07003647 final int compatFlags = PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
3648 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
3649
Winson14ff7172019-10-23 10:42:27 -07003650 final boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
Todd Kennedy0eb97382017-10-03 16:57:22 -07003651 >= Build.VERSION_CODES.M;
3652
Winson14ff7172019-10-23 10:42:27 -07003653 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003654
Winson14ff7172019-10-23 10:42:27 -07003655 for (String permission : pkg.getRequestedPermissions()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003656 final BasePermission bp;
3657 synchronized (mLock) {
3658 bp = mSettings.getPermissionLocked(permission);
3659 }
3660 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
3661 && (!instantApp || bp.isInstant())
3662 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
3663 && (grantedPermissions == null
3664 || ArrayUtils.contains(grantedPermissions, permission))) {
3665 final int flags = permissionsState.getPermissionFlags(permission, userId);
3666 if (supportsRuntimePermissions) {
3667 // Installer cannot change immutable permissions.
3668 if ((flags & immutableFlags) == 0) {
Winson14ff7172019-10-23 10:42:27 -07003669 grantRuntimePermissionInternal(permission, pkg.getPackageName(), false,
Todd Kennedyc971a452019-07-08 16:04:52 -07003670 callingUid, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003671 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07003672 } else {
Hai Zhangfa291702019-09-19 16:35:44 -07003673 // In permission review mode we clear the review flag and the revoked compat
3674 // flag when we are asked to install the app with all permissions granted.
3675 if ((flags & compatFlags) != 0) {
Winson14ff7172019-10-23 10:42:27 -07003676 updatePermissionFlagsInternal(permission, pkg.getPackageName(), compatFlags,
Hai Zhangfa291702019-09-19 16:35:44 -07003677 0, callingUid, userId, false, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003678 }
3679 }
3680 }
3681 }
3682 }
3683
Winson14ff7172019-10-23 10:42:27 -07003684 private void setWhitelistedRestrictedPermissionsForUser(@NonNull AndroidPackage pkg,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003685 @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
3686 @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003687 final PermissionsState permissionsState =
Winson14ff7172019-10-23 10:42:27 -07003688 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003689 if (permissionsState == null) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003690 return;
3691 }
3692
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003693 ArraySet<String> oldGrantedRestrictedPermissions = null;
3694 boolean updatePermissions = false;
3695
Winson14ff7172019-10-23 10:42:27 -07003696 final int permissionCount = pkg.getRequestedPermissions().size();
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003697 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07003698 final String permissionName = pkg.getRequestedPermissions().get(i);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003699
3700 final BasePermission bp = mSettings.getPermissionLocked(permissionName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003701
Evan Seversoncdcaaaa2019-07-02 10:29:25 -07003702 if (bp == null || !bp.isHardOrSoftRestricted()) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003703 continue;
3704 }
3705
3706 if (permissionsState.hasPermission(permissionName, userId)) {
3707 if (oldGrantedRestrictedPermissions == null) {
3708 oldGrantedRestrictedPermissions = new ArraySet<>();
3709 }
3710 oldGrantedRestrictedPermissions.add(permissionName);
3711 }
3712
3713 final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
3714
3715 int newFlags = oldFlags;
3716 int mask = 0;
3717 int whitelistFlagsCopy = whitelistFlags;
3718 while (whitelistFlagsCopy != 0) {
3719 final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
3720 whitelistFlagsCopy &= ~flag;
3721 switch (flag) {
3722 case FLAG_PERMISSION_WHITELIST_SYSTEM: {
3723 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3724 if (permissions != null && permissions.contains(permissionName)) {
3725 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3726 } else {
3727 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3728 }
3729 } break;
3730 case FLAG_PERMISSION_WHITELIST_UPGRADE: {
3731 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3732 if (permissions != null && permissions.contains(permissionName)) {
3733 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3734 } else {
3735 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3736 }
3737 } break;
3738 case FLAG_PERMISSION_WHITELIST_INSTALLER: {
3739 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3740 if (permissions != null && permissions.contains(permissionName)) {
3741 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3742 } else {
3743 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3744 }
3745 } break;
3746 }
3747 }
3748
3749 if (oldFlags == newFlags) {
3750 continue;
3751 }
3752
3753 updatePermissions = true;
3754
Svet Ganovd563e932019-04-14 13:07:41 -07003755 final boolean wasWhitelisted = (oldFlags
3756 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3757 final boolean isWhitelisted = (newFlags
3758 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3759
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003760 // If the permission is policy fixed as granted but it is no longer
3761 // on any of the whitelists we need to clear the policy fixed flag
3762 // as whitelisting trumps policy i.e. policy cannot grant a non
3763 // grantable permission.
3764 if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003765 final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
3766 if (!isWhitelisted && isGranted) {
3767 mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3768 newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3769 }
3770 }
3771
Svet Ganovd563e932019-04-14 13:07:41 -07003772 // If we are whitelisting an app that does not support runtime permissions
3773 // we need to make sure it goes through the permission review UI at launch.
Winson14ff7172019-10-23 10:42:27 -07003774 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Svet Ganovd563e932019-04-14 13:07:41 -07003775 && !wasWhitelisted && isWhitelisted) {
3776 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3777 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3778 }
3779
Winson14ff7172019-10-23 10:42:27 -07003780 updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003781 callingUid, userId, false, null /*callback*/);
3782 }
3783
3784 if (updatePermissions) {
Philip P. Moltmannba742062019-04-08 13:22:44 -07003785 // Update permission of this app to take into account the new whitelist state.
Winson14ff7172019-10-23 10:42:27 -07003786 restorePermissionState(pkg, false, pkg.getPackageName(), callback);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003787
3788 // If this resulted in losing a permission we need to kill the app.
3789 if (oldGrantedRestrictedPermissions != null) {
3790 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
3791 for (int i = 0; i < oldGrantedCount; i++) {
3792 final String permission = oldGrantedRestrictedPermissions.valueAt(i);
3793 // Sometimes we create a new permission state instance during update.
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003794 final PermissionsState newPermissionsState =
Winson14ff7172019-10-23 10:42:27 -07003795 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003796 if (!newPermissionsState.hasPermission(permission, userId)) {
Winson14ff7172019-10-23 10:42:27 -07003797 callback.onPermissionRevoked(pkg.getUid(), userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003798 break;
3799 }
3800 }
3801 }
3802 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07003803 }
3804
Andreas Gampea36dc622018-02-05 17:19:22 -08003805 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003806 private int[] revokeUnusedSharedUserPermissionsLocked(
3807 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003808 // Collect all used permissions in the UID
3809 final ArraySet<String> usedPermissions = new ArraySet<>();
Winson14ff7172019-10-23 10:42:27 -07003810 final List<AndroidPackage> pkgList = suSetting.getPackages();
Todd Kennedy0eb97382017-10-03 16:57:22 -07003811 if (pkgList == null || pkgList.size() == 0) {
3812 return EmptyArray.INT;
3813 }
Winson14ff7172019-10-23 10:42:27 -07003814 for (AndroidPackage pkg : pkgList) {
Winsone23ae202020-01-24 11:56:44 -08003815 if (pkg.getRequestedPermissions().isEmpty()) {
Svet Ganovd8308072018-03-24 00:04:38 -07003816 continue;
3817 }
Winson14ff7172019-10-23 10:42:27 -07003818 final int requestedPermCount = pkg.getRequestedPermissions().size();
Todd Kennedy0eb97382017-10-03 16:57:22 -07003819 for (int j = 0; j < requestedPermCount; j++) {
Winson14ff7172019-10-23 10:42:27 -07003820 String permission = pkg.getRequestedPermissions().get(j);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003821 BasePermission bp = mSettings.getPermissionLocked(permission);
3822 if (bp != null) {
3823 usedPermissions.add(permission);
3824 }
3825 }
3826 }
3827
3828 PermissionsState permissionsState = suSetting.getPermissionsState();
3829 // Prune install permissions
3830 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
3831 final int installPermCount = installPermStates.size();
3832 for (int i = installPermCount - 1; i >= 0; i--) {
3833 PermissionState permissionState = installPermStates.get(i);
3834 if (!usedPermissions.contains(permissionState.getName())) {
3835 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
3836 if (bp != null) {
3837 permissionsState.revokeInstallPermission(bp);
3838 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08003839 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003840 }
3841 }
3842 }
3843
3844 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
3845
3846 // Prune runtime permissions
3847 for (int userId : allUserIds) {
3848 List<PermissionState> runtimePermStates = permissionsState
3849 .getRuntimePermissionStates(userId);
3850 final int runtimePermCount = runtimePermStates.size();
3851 for (int i = runtimePermCount - 1; i >= 0; i--) {
3852 PermissionState permissionState = runtimePermStates.get(i);
3853 if (!usedPermissions.contains(permissionState.getName())) {
3854 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
3855 if (bp != null) {
3856 permissionsState.revokeRuntimePermission(bp, userId);
3857 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08003858 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003859 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
3860 runtimePermissionChangedUserIds, userId);
3861 }
3862 }
3863 }
3864 }
3865
3866 return runtimePermissionChangedUserIds;
3867 }
3868
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003869 /**
3870 * Update permissions when a package changed.
3871 *
3872 * <p><ol>
3873 * <li>Reconsider the ownership of permission</li>
3874 * <li>Update the state (grant, flags) of the permissions</li>
3875 * </ol>
3876 *
3877 * @param packageName The package that is updated
3878 * @param pkg The package that is updated, or {@code null} if package is deleted
3879 * @param allPackages All currently known packages
3880 * @param callback Callback to call after permission changes
3881 */
Winson14ff7172019-10-23 10:42:27 -07003882 private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003883 @NonNull PermissionCallback callback) {
Songchun Fanbcc899e2020-04-06 16:51:45 -07003884 // If the package is being deleted, update the permissions of all the apps
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003885 final int flags =
Songchun Fanbcc899e2020-04-06 16:51:45 -07003886 (pkg == null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG
3887 : UPDATE_PERMISSIONS_REPLACE_PKG);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003888 updatePermissions(
Todd Kennedyc971a452019-07-08 16:04:52 -07003889 packageName, pkg, getVolumeUuidForPackage(pkg), flags, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003890 }
3891
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003892 /**
3893 * Update all permissions for all apps.
3894 *
3895 * <p><ol>
3896 * <li>Reconsider the ownership of permission</li>
3897 * <li>Update the state (grant, flags) of the permissions</li>
3898 * </ol>
3899 *
3900 * @param volumeUuid The volume of the packages to be updated, {@code null} for all volumes
3901 * @param allPackages All currently known packages
3902 * @param callback Callback to call after permission changes
3903 */
3904 private void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003905 @NonNull PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003906 final int flags = UPDATE_PERMISSIONS_ALL |
3907 (sdkUpdated
3908 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
3909 : 0);
Todd Kennedyc971a452019-07-08 16:04:52 -07003910 updatePermissions(null, null, volumeUuid, flags, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003911 }
3912
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003913 /**
3914 * Cache background->foreground permission mapping.
3915 *
3916 * <p>This is only run once.
3917 */
3918 private void cacheBackgroundToForegoundPermissionMapping() {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003919 synchronized (mLock) {
3920 if (mBackgroundPermissions == null) {
3921 // Cache background -> foreground permission mapping.
3922 // Only system declares background permissions, hence mapping does never change.
3923 mBackgroundPermissions = new ArrayMap<>();
3924 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Winsonf00c7552020-01-28 12:52:01 -08003925 if (bp.perm != null && bp.perm.getBackgroundPermission() != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003926 String fgPerm = bp.name;
Winsonf00c7552020-01-28 12:52:01 -08003927 String bgPerm = bp.perm.getBackgroundPermission();
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003928
3929 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
3930 if (fgPerms == null) {
3931 fgPerms = new ArrayList<>();
3932 mBackgroundPermissions.put(bgPerm, fgPerms);
3933 }
3934
3935 fgPerms.add(fgPerm);
3936 }
3937 }
3938 }
3939 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003940 }
3941
3942 /**
3943 * Update all packages on the volume, <u>beside</u> the changing package. If the changing
3944 * package is set too, all packages are updated.
3945 */
3946 private static final int UPDATE_PERMISSIONS_ALL = 1 << 0;
3947 /** The changing package is replaced. Requires the changing package to be set */
3948 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1 << 1;
3949 /**
3950 * Schedule all packages <u>beside</u> the changing package for replacement. Requires
3951 * UPDATE_PERMISSIONS_ALL to be set
3952 */
3953 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1 << 2;
3954
3955 @IntDef(flag = true, prefix = { "UPDATE_PERMISSIONS_" }, value = {
3956 UPDATE_PERMISSIONS_ALL, UPDATE_PERMISSIONS_REPLACE_PKG,
3957 UPDATE_PERMISSIONS_REPLACE_ALL })
3958 @Retention(RetentionPolicy.SOURCE)
3959 private @interface UpdatePermissionFlags {}
3960
3961 /**
3962 * Update permissions when packages changed.
3963 *
3964 * <p><ol>
3965 * <li>Reconsider the ownership of permission</li>
3966 * <li>Update the state (grant, flags) of the permissions</li>
3967 * </ol>
3968 *
3969 * <p>Meaning of combination of package parameters:
3970 * <table>
3971 * <tr><th></th><th>changingPkgName != null</th><th>changingPkgName == null</th></tr>
3972 * <tr><th>changingPkg != null</th><td>package is updated</td><td>invalid</td></tr>
3973 * <tr><th>changingPkg == null</th><td>package is deleted</td><td>all packages are
3974 * updated</td></tr>
3975 * </table>
3976 *
3977 * @param changingPkgName The package that is updated, or {@code null} if all packages should be
3978 * updated
3979 * @param changingPkg The package that is updated, or {@code null} if all packages should be
3980 * updated or package is deleted
3981 * @param replaceVolumeUuid The volume of the packages to be updated are on, {@code null} for
3982 * all volumes
3983 * @param flags Control permission for which apps should be updated
3984 * @param allPackages All currently known packages
3985 * @param callback Callback to call after permission changes
3986 */
Todd Kennedyc971a452019-07-08 16:04:52 -07003987 private void updatePermissions(final @Nullable String changingPkgName,
Winson14ff7172019-10-23 10:42:27 -07003988 final @Nullable AndroidPackage changingPkg,
Todd Kennedyc971a452019-07-08 16:04:52 -07003989 final @Nullable String replaceVolumeUuid,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003990 @UpdatePermissionFlags int flags,
Todd Kennedyc971a452019-07-08 16:04:52 -07003991 final @Nullable PermissionCallback callback) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003992 // TODO: Most of the methods exposing BasePermission internals [source package name,
3993 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
3994 // have package settings, we should make note of it elsewhere [map between
3995 // source package name and BasePermission] and cycle through that here. Then we
3996 // define a single method on BasePermission that takes a PackageSetting, changing
3997 // package name and a package.
3998 // NOTE: With this approach, we also don't need to tree trees differently than
3999 // normal permissions. Today, we need two separate loops because these BasePermission
4000 // objects are stored separately.
4001 // Make sure there are no dangling permission trees.
4002 boolean permissionTreesSourcePackageChanged = updatePermissionTreeSourcePackage(
4003 changingPkgName, changingPkg);
4004 // Make sure all dynamic permissions have been assigned to a package,
4005 // and make sure there are no dangling permissions.
4006 boolean permissionSourcePackageChanged = updatePermissionSourcePackage(changingPkgName,
Hongming Jinbc4d0102019-08-16 14:28:30 -07004007 changingPkg, callback);
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004008
4009 if (permissionTreesSourcePackageChanged | permissionSourcePackageChanged) {
4010 // Permission ownership has changed. This e.g. changes which packages can get signature
4011 // permissions
Songchun Fanbcc899e2020-04-06 16:51:45 -07004012 Slog.i(TAG, "Permission ownership changed. Updating all permissions.");
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004013 flags |= UPDATE_PERMISSIONS_ALL;
4014 }
4015
4016 cacheBackgroundToForegoundPermissionMapping();
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07004017
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07004018 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004019 // Now update the permissions for all packages.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004020 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004021 final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
Winson14ff7172019-10-23 10:42:27 -07004022 mPackageManagerInt.forEachPackage((AndroidPackage pkg) -> {
Todd Kennedyc971a452019-07-08 16:04:52 -07004023 if (pkg == changingPkg) {
4024 return;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004025 }
Todd Kennedyc971a452019-07-08 16:04:52 -07004026 // Only replace for packages on requested volume
4027 final String volumeUuid = getVolumeUuidForPackage(pkg);
4028 final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid);
4029 restorePermissionState(pkg, replace, changingPkgName, callback);
4030 });
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004031 }
4032
4033 if (changingPkg != null) {
4034 // Only replace for packages on requested volume
4035 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
4036 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
4037 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07004038 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004039 }
4040 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4041 }
4042
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004043 /**
4044 * Update which app declares a permission.
4045 *
4046 * <p>Possible parameter combinations
4047 * <table>
4048 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
4049 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
4050 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
4051 * </table>
4052 *
4053 * @param packageName The package that is updated, or {@code null} if all packages should be
4054 * updated
4055 * @param pkg The package that is updated, or {@code null} if all packages should be updated or
4056 * package is deleted
4057 *
4058 * @return {@code true} if a permission source package might have changed
4059 */
4060 private boolean updatePermissionSourcePackage(@Nullable String packageName,
Winson14ff7172019-10-23 10:42:27 -07004061 @Nullable AndroidPackage pkg,
Hongming Jinbc4d0102019-08-16 14:28:30 -07004062 final @Nullable PermissionCallback callback) {
Songchun Fanbcc899e2020-04-06 16:51:45 -07004063 // Always need update if packageName is null
4064 if (packageName == null) {
4065 return true;
4066 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004067
Songchun Fanbcc899e2020-04-06 16:51:45 -07004068 boolean changed = false;
Todd Kennedyc8423932017-10-05 08:58:36 -07004069 Set<BasePermission> needsUpdate = null;
4070 synchronized (mLock) {
4071 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
4072 while (it.hasNext()) {
4073 final BasePermission bp = it.next();
4074 if (bp.isDynamic()) {
4075 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
4076 }
Songchun Fanbcc899e2020-04-06 16:51:45 -07004077 if (bp.getSourcePackageSetting() == null
4078 || !packageName.equals(bp.getSourcePackageName())) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004079 continue;
4080 }
Songchun Fanbcc899e2020-04-06 16:51:45 -07004081 // The target package is the source of the current permission
4082 // Set to changed for either install or uninstall
4083 changed = true;
4084 // If the target package is being uninstalled, we need to revoke this permission
4085 // From all other packages
4086 if (pkg == null || !hasPermission(pkg, bp.getName())) {
4087 Slog.i(TAG, "Removing permission " + bp.getName()
4088 + " that used to be declared by " + bp.getSourcePackageName());
4089 if (bp.isRuntime()) {
4090 final int[] userIds = mUserManagerInt.getUserIds();
4091 final int numUserIds = userIds.length;
4092 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
4093 final int userId = userIds[userIdNum];
4094 mPackageManagerInt.forEachPackage((AndroidPackage p) ->
4095 revokePermissionFromPackageForUser(p.getPackageName(),
4096 bp.getName(), userId, callback));
4097 }
4098 }
4099 it.remove();
4100 }
Todd Kennedyc8423932017-10-05 08:58:36 -07004101 if (needsUpdate == null) {
4102 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
4103 }
4104 needsUpdate.add(bp);
4105 }
4106 }
4107 if (needsUpdate != null) {
4108 for (final BasePermission bp : needsUpdate) {
Winson14ff7172019-10-23 10:42:27 -07004109 final AndroidPackage sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07004110 mPackageManagerInt.getPackage(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07004111 final PackageSetting sourcePs =
4112 (PackageSetting) mPackageManagerInt.getPackageSetting(
4113 bp.getSourcePackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07004114 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07004115 if (sourcePkg != null && sourcePs != null) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004116 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004117 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07004118 }
4119 continue;
4120 }
4121 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
4122 + " from package " + bp.getSourcePackageName());
4123 mSettings.removePermissionLocked(bp.getName());
4124 }
4125 }
4126 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004127 return changed;
Todd Kennedyc8423932017-10-05 08:58:36 -07004128 }
4129
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004130 /**
Songchun Fanbcc899e2020-04-06 16:51:45 -07004131 * Revoke a runtime permission from a package for a given user ID.
4132 */
4133 private void revokePermissionFromPackageForUser(@NonNull String pName,
4134 @NonNull String permissionName, int userId, @Nullable PermissionCallback callback) {
4135 final ApplicationInfo appInfo =
4136 mPackageManagerInt.getApplicationInfo(pName, 0,
4137 Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
4138 if (appInfo != null
4139 && appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4140 return;
4141 }
4142
4143 if (checkPermissionImpl(permissionName, pName, userId)
4144 == PackageManager.PERMISSION_GRANTED) {
4145 try {
4146 revokeRuntimePermissionInternal(
4147 permissionName,
4148 pName,
4149 false,
4150 Process.SYSTEM_UID,
4151 userId,
4152 callback);
4153 } catch (IllegalArgumentException e) {
4154 Slog.e(TAG,
4155 "Failed to revoke "
4156 + permissionName
4157 + " from "
4158 + pName,
4159 e);
4160 }
4161 }
4162 }
4163 /**
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004164 * Update which app owns a permission trees.
4165 *
4166 * <p>Possible parameter combinations
4167 * <table>
4168 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
4169 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
4170 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
4171 * </table>
4172 *
4173 * @param packageName The package that is updated, or {@code null} if all packages should be
4174 * updated
4175 * @param pkg The package that is updated, or {@code null} if all packages should be updated or
4176 * package is deleted
4177 *
4178 * @return {@code true} if a permission tree ownership might have changed
4179 */
4180 private boolean updatePermissionTreeSourcePackage(@Nullable String packageName,
Winson14ff7172019-10-23 10:42:27 -07004181 @Nullable AndroidPackage pkg) {
Songchun Fanbcc899e2020-04-06 16:51:45 -07004182 // Always need update if packageName is null
4183 if (packageName == null) {
4184 return true;
4185 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004186 boolean changed = false;
4187
Todd Kennedyc8423932017-10-05 08:58:36 -07004188 Set<BasePermission> needsUpdate = null;
4189 synchronized (mLock) {
4190 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
4191 while (it.hasNext()) {
4192 final BasePermission bp = it.next();
Songchun Fanbcc899e2020-04-06 16:51:45 -07004193 if (bp.getSourcePackageSetting() == null
4194 || !packageName.equals(bp.getSourcePackageName())) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004195 continue;
4196 }
Songchun Fanbcc899e2020-04-06 16:51:45 -07004197 // The target package is the source of the current permission tree
4198 // Set to changed for either install or uninstall
4199 changed = true;
4200 if (pkg == null || !hasPermission(pkg, bp.getName())) {
4201 Slog.i(TAG, "Removing permission tree " + bp.getName()
4202 + " that used to be declared by " + bp.getSourcePackageName());
4203 it.remove();
4204 }
Todd Kennedyc8423932017-10-05 08:58:36 -07004205 if (needsUpdate == null) {
4206 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
4207 }
4208 needsUpdate.add(bp);
4209 }
4210 }
4211 if (needsUpdate != null) {
4212 for (final BasePermission bp : needsUpdate) {
Winson14ff7172019-10-23 10:42:27 -07004213 final AndroidPackage sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07004214 mPackageManagerInt.getPackage(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07004215 final PackageSetting sourcePs =
4216 (PackageSetting) mPackageManagerInt.getPackageSetting(
4217 bp.getSourcePackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07004218 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07004219 if (sourcePkg != null && sourcePs != null) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004220 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004221 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07004222 }
4223 continue;
4224 }
4225 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
4226 + " from package " + bp.getSourcePackageName());
4227 mSettings.removePermissionLocked(bp.getName());
4228 }
4229 }
4230 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004231 return changed;
Todd Kennedyc8423932017-10-05 08:58:36 -07004232 }
4233
Todd Kennedy0eb97382017-10-03 16:57:22 -07004234 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4235 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4236 != PackageManager.PERMISSION_GRANTED
4237 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4238 != PackageManager.PERMISSION_GRANTED) {
4239 throw new SecurityException(message + " requires "
4240 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4241 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4242 }
4243 }
4244
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08004245 private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
4246 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
4247 != PackageManager.PERMISSION_GRANTED
4248 && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4249 != PackageManager.PERMISSION_GRANTED
4250 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4251 != PackageManager.PERMISSION_GRANTED) {
4252 throw new SecurityException(message + " requires "
4253 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4254 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
4255 + Manifest.permission.GET_RUNTIME_PERMISSIONS);
4256 }
4257 }
4258
Todd Kennedy0eb97382017-10-03 16:57:22 -07004259 /**
4260 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4261 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4262 * @param checkShell whether to prevent shell from access if there's a debugging restriction
4263 * @param message the message to log on security exception
4264 */
4265 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07004266 boolean requireFullPermission, boolean checkShell,
4267 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004268 if (userId < 0) {
4269 throw new IllegalArgumentException("Invalid userId " + userId);
4270 }
4271 if (checkShell) {
Patrick Baumann2f2fd712019-07-31 15:18:53 -07004272 PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
Todd Kennedy0eb97382017-10-03 16:57:22 -07004273 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4274 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004275 final int callingUserId = UserHandle.getUserId(callingUid);
4276 if (hasCrossUserPermission(
4277 callingUid, callingUserId, userId, requireFullPermission,
4278 requirePermissionWhenSameUser)) {
4279 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07004280 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004281 String errorMessage = buildInvalidCrossUserPermissionMessage(
4282 message, requireFullPermission);
4283 Slog.w(TAG, errorMessage);
4284 throw new SecurityException(errorMessage);
4285 }
4286
4287 /**
4288 * Checks if the request is from the system or an app that has the appropriate cross-user
4289 * permissions defined as follows:
4290 * <ul>
4291 * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
4292 * <li>INTERACT_ACROSS_USERS if the given {@userId} is in a different profile group
4293 * to the caller.</li>
4294 * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@userId} is in the same profile group
4295 * as the caller.</li>
4296 * </ul>
4297 *
4298 * @param checkShell whether to prevent shell from access if there's a debugging restriction
4299 * @param message the message to log on security exception
4300 */
4301 private void enforceCrossUserOrProfilePermission(int callingUid, int userId,
4302 boolean requireFullPermission, boolean checkShell,
4303 String message) {
4304 if (userId < 0) {
4305 throw new IllegalArgumentException("Invalid userId " + userId);
4306 }
4307 if (checkShell) {
4308 PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
4309 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4310 }
4311 final int callingUserId = UserHandle.getUserId(callingUid);
4312 if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission,
4313 /*requirePermissionWhenSameUser= */ false)) {
4314 return;
4315 }
4316 final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
kholoud mohamed79a89f02020-01-15 15:30:07 +00004317 if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight(
4318 mContext,
4319 android.Manifest.permission.INTERACT_ACROSS_PROFILES,
4320 PermissionChecker.PID_UNKNOWN,
4321 callingUid,
4322 mPackageManagerInt.getPackage(callingUid).getPackageName())
4323 == PermissionChecker.PERMISSION_GRANTED) {
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004324 return;
4325 }
4326 String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
4327 message, requireFullPermission, isSameProfileGroup);
4328 Slog.w(TAG, errorMessage);
4329 throw new SecurityException(errorMessage);
4330 }
4331
4332 private boolean hasCrossUserPermission(
4333 int callingUid, int callingUserId, int userId, boolean requireFullPermission,
4334 boolean requirePermissionWhenSameUser) {
4335 if (!requirePermissionWhenSameUser && userId == callingUserId) {
4336 return true;
4337 }
4338 if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
4339 return true;
4340 }
4341 if (requireFullPermission) {
4342 return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4343 }
4344 return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
4345 || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
4346 }
4347
4348 private boolean hasPermission(String permission) {
4349 return mContext.checkCallingOrSelfPermission(permission)
4350 == PackageManager.PERMISSION_GRANTED;
4351 }
4352
4353 private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
4354 final long identity = Binder.clearCallingIdentity();
4355 try {
4356 return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
4357 } finally {
4358 Binder.restoreCallingIdentity(identity);
4359 }
4360 }
4361
4362 private static String buildInvalidCrossUserPermissionMessage(
4363 String message, boolean requireFullPermission) {
4364 StringBuilder builder = new StringBuilder();
4365 if (message != null) {
4366 builder.append(message);
4367 builder.append(": ");
4368 }
4369 builder.append("Requires ");
4370 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4371 if (requireFullPermission) {
4372 builder.append(".");
4373 return builder.toString();
4374 }
4375 builder.append(" or ");
4376 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
4377 builder.append(".");
4378 return builder.toString();
4379 }
4380
4381 private static String buildInvalidCrossUserOrProfilePermissionMessage(
4382 String message, boolean requireFullPermission, boolean isSameProfileGroup) {
4383 StringBuilder builder = new StringBuilder();
4384 if (message != null) {
4385 builder.append(message);
4386 builder.append(": ");
4387 }
4388 builder.append("Requires ");
4389 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4390 if (requireFullPermission) {
4391 builder.append(".");
4392 return builder.toString();
4393 }
4394 builder.append(" or ");
4395 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
4396 if (isSameProfileGroup) {
4397 builder.append(" or ");
4398 builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES);
4399 }
4400 builder.append(".");
4401 return builder.toString();
Todd Kennedy0eb97382017-10-03 16:57:22 -07004402 }
4403
Andreas Gampea71bee82018-07-20 12:55:36 -07004404 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07004405 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4406 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07004407 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004408 size += tree.calculateFootprint(perm);
4409 }
4410 return size;
4411 }
4412
Andreas Gampea71bee82018-07-20 12:55:36 -07004413 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07004414 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4415 // We calculate the max size of permissions defined by this uid and throw
4416 // if that plus the size of 'info' would exceed our stated maximum.
4417 if (tree.getUid() != Process.SYSTEM_UID) {
4418 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4419 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
4420 throw new SecurityException("Permission tree size cap exceeded");
4421 }
4422 }
4423 }
4424
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004425 private void systemReady() {
4426 mSystemReady = true;
4427 if (mPrivappPermissionsViolations != null) {
4428 throw new IllegalStateException("Signature|privileged permissions not in "
4429 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
4430 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08004431
4432 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
Svet Ganov3c499ea2019-07-26 17:45:56 -07004433 mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
Todd Kennedy583378d2019-07-12 06:50:30 -07004434
4435 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
4436 for (int userId : UserManagerService.getInstance().getUserIds()) {
Evan Severson0dc24cb2020-02-04 10:25:08 -08004437 if (mPackageManagerInt.isPermissionUpgradeNeeded(userId)) {
Todd Kennedy583378d2019-07-12 06:50:30 -07004438 grantPermissionsUserIds = ArrayUtils.appendInt(
4439 grantPermissionsUserIds, userId);
4440 }
4441 }
4442 // If we upgraded grant all default permissions before kicking off.
4443 for (int userId : grantPermissionsUserIds) {
4444 mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
4445 }
4446 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
4447 // If we did not grant default permissions, we preload from this the
4448 // default permission exceptions lazily to ensure we don't hit the
4449 // disk on a new user creation.
4450 mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
4451 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004452 }
4453
Winson14ff7172019-10-23 10:42:27 -07004454 private static String getVolumeUuidForPackage(AndroidPackage pkg) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004455 if (pkg == null) {
4456 return StorageManager.UUID_PRIVATE_INTERNAL;
4457 }
Winson5e0a1d52020-01-24 12:00:33 -08004458 if (pkg.isExternalStorage()) {
Winson14ff7172019-10-23 10:42:27 -07004459 if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004460 return StorageManager.UUID_PRIMARY_PHYSICAL;
4461 } else {
Winson14ff7172019-10-23 10:42:27 -07004462 return pkg.getVolumeUuid();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004463 }
4464 } else {
4465 return StorageManager.UUID_PRIVATE_INTERNAL;
4466 }
4467 }
4468
Winson14ff7172019-10-23 10:42:27 -07004469 private static boolean hasPermission(AndroidPackage pkg, String permName) {
Winsone23ae202020-01-24 11:56:44 -08004470 if (pkg.getPermissions().isEmpty()) {
Winson14ff7172019-10-23 10:42:27 -07004471 return false;
4472 }
4473
4474 for (int i = pkg.getPermissions().size() - 1; i >= 0; i--) {
4475 if (pkg.getPermissions().get(i).getName().equals(permName)) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004476 return true;
4477 }
4478 }
4479 return false;
4480 }
4481
Todd Kennedy0eb97382017-10-03 16:57:22 -07004482 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004483 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07004484 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004485 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07004486 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004487 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07004488 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004489 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
4490 final LogMaker log = new LogMaker(action);
4491 log.setPackageName(packageName);
4492 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004493
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004494 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004495 }
4496
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07004497 /**
4498 * Get the mapping of background permissions to their foreground permissions.
4499 *
4500 * <p>Only initialized in the system server.
4501 *
4502 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
4503 */
4504 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
4505 return mBackgroundPermissions;
4506 }
4507
Philip P. Moltmann48456672019-01-20 13:14:03 -08004508 private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004509 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004510 public void systemReady() {
4511 PermissionManagerService.this.systemReady();
4512 }
4513 @Override
Winson14ff7172019-10-23 10:42:27 -07004514 public boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
4515 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004516 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
4517 }
Winson14ff7172019-10-23 10:42:27 -07004518
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004519 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004520 public void revokeRuntimePermissionsIfGroupChanged(
Winson14ff7172019-10-23 10:42:27 -07004521 @NonNull AndroidPackage newPackage,
4522 @NonNull AndroidPackage oldPackage,
Todd Kennedyc971a452019-07-08 16:04:52 -07004523 @NonNull ArrayList<String> allPackageNames) {
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004524 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
Todd Kennedyc971a452019-07-08 16:04:52 -07004525 oldPackage, allPackageNames, mDefaultPermissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004526 }
4527 @Override
Winson14ff7172019-10-23 10:42:27 -07004528 public void addAllPermissions(AndroidPackage pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004529 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004530 }
4531 @Override
Winson14ff7172019-10-23 10:42:27 -07004532 public void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07004533 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
4534 }
4535 @Override
Winson14ff7172019-10-23 10:42:27 -07004536 public void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
Hongming Jinae750fb2018-09-27 23:00:20 +00004537 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07004538 }
4539 @Override
Winson14ff7172019-10-23 10:42:27 -07004540 public void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
Todd Kennedyc971a452019-07-08 16:04:52 -07004541 String[] grantedPermissions, int callingUid) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004542 PermissionManagerService.this.grantRequestedRuntimePermissions(
Todd Kennedyc971a452019-07-08 16:04:52 -07004543 pkg, userIds, grantedPermissions, callingUid, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004544 }
4545 @Override
Winson14ff7172019-10-23 10:42:27 -07004546 public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004547 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
Todd Kennedyc971a452019-07-08 16:04:52 -07004548 @PackageManager.PermissionWhitelistFlags int flags) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004549 for (int userId : userIds) {
4550 setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
Todd Kennedyc971a452019-07-08 16:04:52 -07004551 callingUid, flags, mDefaultPermissionCallback);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004552 }
4553 }
4554 @Override
4555 public void setWhitelistedRestrictedPermissions(String packageName,
4556 List<String> permissions, int flags, int userId) {
4557 PermissionManagerService.this.setWhitelistedRestrictedPermissionsInternal(
4558 packageName, permissions, flags, userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004559 }
4560 @Override
Eugene Susla922cd082020-03-11 12:38:17 -07004561 public void setAutoRevokeWhitelisted(
4562 @NonNull String packageName, boolean whitelisted, int userId) {
4563 PermissionManagerService.this.setAutoRevokeWhitelisted(
4564 packageName, whitelisted, userId);
4565 }
4566 @Override
Winson14ff7172019-10-23 10:42:27 -07004567 public void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004568 PermissionManagerService.this
4569 .updatePermissions(packageName, pkg, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004570 }
4571 @Override
Todd Kennedyc971a452019-07-08 16:04:52 -07004572 public void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated) {
4573 PermissionManagerService.this
4574 .updateAllPermissions(volumeUuid, sdkUpdated, mDefaultPermissionCallback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004575 }
4576 @Override
Winson14ff7172019-10-23 10:42:27 -07004577 public void resetRuntimePermissions(AndroidPackage pkg, int userId) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004578 PermissionManagerService.this.resetRuntimePermissionsInternal(pkg, userId);
4579 }
4580 @Override
4581 public void resetAllRuntimePermissions(final int userId) {
4582 mPackageManagerInt.forEachPackage(
Winson14ff7172019-10-23 10:42:27 -07004583 (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
Todd Kennedy0eb97382017-10-03 16:57:22 -07004584 }
4585 @Override
Todd Kennedy8f135982019-07-02 07:35:15 -07004586 public String[] getAppOpPermissionPackages(String permName, int callingUid) {
4587 return PermissionManagerService.this
4588 .getAppOpPermissionPackagesInternal(permName, callingUid);
Todd Kennedyc8423932017-10-05 08:58:36 -07004589 }
4590 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004591 public void enforceCrossUserPermission(int callingUid, int userId,
4592 boolean requireFullPermission, boolean checkShell, String message) {
4593 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07004594 requireFullPermission, checkShell, false, message);
4595 }
4596 @Override
4597 public void enforceCrossUserPermission(int callingUid, int userId,
4598 boolean requireFullPermission, boolean checkShell,
4599 boolean requirePermissionWhenSameUser, String message) {
4600 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
4601 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004602 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004603
4604 @Override
4605 public void enforceCrossUserOrProfilePermission(int callingUid, int userId,
4606 boolean requireFullPermission, boolean checkShell, String message) {
kholoud mohamed79a89f02020-01-15 15:30:07 +00004607 PermissionManagerService.this.enforceCrossUserOrProfilePermission(
4608 callingUid,
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004609 userId,
4610 requireFullPermission,
4611 checkShell,
4612 message);
4613 }
4614
Todd Kennedy0eb97382017-10-03 16:57:22 -07004615 @Override
4616 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4617 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
4618 }
4619 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004620 public PermissionSettings getPermissionSettings() {
4621 return mSettings;
4622 }
4623 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004624 public BasePermission getPermissionTEMP(String permName) {
4625 synchronized (PermissionManagerService.this.mLock) {
4626 return mSettings.getPermissionLocked(permName);
4627 }
4628 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08004629
4630 @Override
Hai Zhang57bc3122019-10-21 16:04:15 -07004631 public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtection(
4632 @PermissionInfo.Protection int protection) {
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07004633 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
4634
4635 synchronized (PermissionManagerService.this.mLock) {
4636 int numTotalPermissions = mSettings.mPermissions.size();
4637
4638 for (int i = 0; i < numTotalPermissions; i++) {
4639 BasePermission bp = mSettings.mPermissions.valueAt(i);
4640
Winson655a5b92019-10-23 10:49:32 -07004641 if (bp.perm != null && bp.perm.getProtection() == protection) {
4642 matchingPermissions.add(
4643 PackageInfoUtils.generatePermissionInfo(bp.perm, 0));
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07004644 }
4645 }
4646 }
4647
4648 return matchingPermissions;
4649 }
4650
4651 @Override
Philip P. Moltmann48456672019-01-20 13:14:03 -08004652 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
4653 return PermissionManagerService.this.backupRuntimePermissions(user);
4654 }
4655
4656 @Override
4657 public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
4658 PermissionManagerService.this.restoreRuntimePermissions(backup, user);
4659 }
4660
4661 @Override
4662 public void restoreDelayedRuntimePermissions(@NonNull String packageName,
4663 @NonNull UserHandle user) {
4664 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
4665 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004666
4667 @Override
4668 public void addOnRuntimePermissionStateChangedListener(
4669 OnRuntimePermissionStateChangedListener listener) {
4670 PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
4671 listener);
4672 }
4673
4674 @Override
4675 public void removeOnRuntimePermissionStateChangedListener(
4676 OnRuntimePermissionStateChangedListener listener) {
4677 PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
4678 listener);
4679 }
Todd Kennedyca1ea172019-07-03 15:02:28 -07004680
4681 @Override
4682 public CheckPermissionDelegate getCheckPermissionDelegate() {
4683 synchronized (mLock) {
4684 return mCheckPermissionDelegate;
4685 }
4686 }
4687
4688 @Override
4689 public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
4690 synchronized (mLock) {
Daniel Colascionea3c6c092020-02-27 03:51:30 -08004691 if (delegate != null || mCheckPermissionDelegate != null) {
4692 PackageManager.invalidatePackageInfoCache();
4693 }
Todd Kennedyca1ea172019-07-03 15:02:28 -07004694 mCheckPermissionDelegate = delegate;
4695 }
4696 }
Todd Kennedy583378d2019-07-12 06:50:30 -07004697
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004698 @Override
Todd Kennedy583378d2019-07-12 06:50:30 -07004699 public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
4700 synchronized (mLock) {
4701 mDefaultBrowserProvider = provider;
4702 }
4703 }
4704
4705 @Override
4706 public void setDefaultBrowser(String packageName, boolean async, boolean doGrant,
4707 int userId) {
4708 setDefaultBrowserInternal(packageName, async, doGrant, userId);
4709 }
4710
4711 @Override
4712 public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
4713 synchronized (mLock) {
4714 mDefaultDialerProvider = provider;
4715 }
4716 }
4717
4718 @Override
4719 public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
4720 synchronized (mLock) {
4721 mDefaultHomeProvider = provider;
4722 }
4723 }
4724
4725 @Override
4726 public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004727 if (userId == UserHandle.USER_ALL) {
4728 return;
Todd Kennedy583378d2019-07-12 06:50:30 -07004729 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004730 DefaultHomeProvider provider;
4731 synchronized (mLock) {
4732 provider = mDefaultHomeProvider;
4733 }
4734 if (provider == null) {
4735 return;
4736 }
4737 provider.setDefaultHomeAsync(packageName, userId, callback);
Todd Kennedy583378d2019-07-12 06:50:30 -07004738 }
4739
4740 @Override
4741 public void setDialerAppPackagesProvider(PackagesProvider provider) {
4742 synchronized (mLock) {
4743 mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
4744 }
4745 }
4746
4747 @Override
4748 public void setLocationExtraPackagesProvider(PackagesProvider provider) {
4749 synchronized (mLock) {
4750 mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
4751 }
4752 }
4753
4754 @Override
4755 public void setLocationPackagesProvider(PackagesProvider provider) {
4756 synchronized (mLock) {
4757 mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
4758 }
4759 }
4760
4761 @Override
4762 public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
4763 synchronized (mLock) {
4764 mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
4765 }
4766 }
4767
4768 @Override
4769 public void setSmsAppPackagesProvider(PackagesProvider provider) {
4770 synchronized (mLock) {
4771 mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
4772 }
4773 }
4774
4775 @Override
4776 public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
4777 synchronized (mLock) {
4778 mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
4779 }
4780 }
4781
4782 @Override
4783 public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
4784 synchronized (mLock) {
4785 mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
4786 }
4787 }
4788
4789 @Override
4790 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
4791 synchronized (mLock) {
4792 mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
4793 }
4794 }
4795
4796 @Override
4797 public String getDefaultBrowser(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004798 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004799 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004800 provider = mDefaultBrowserProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004801 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004802 return provider != null ? provider.getDefaultBrowser(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004803 }
4804
4805 @Override
4806 public String getDefaultDialer(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004807 DefaultDialerProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004808 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004809 provider = mDefaultDialerProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004810 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004811 return provider != null ? provider.getDefaultDialer(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004812 }
4813
4814 @Override
4815 public String getDefaultHome(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004816 DefaultHomeProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004817 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004818 provider = mDefaultHomeProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004819 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004820 return provider != null ? provider.getDefaultHome(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004821 }
4822
4823 @Override
4824 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
4825 synchronized (mLock) {
4826 mDefaultPermissionGrantPolicy
4827 .grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
4828 }
4829 }
4830
4831 @Override
4832 public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
4833 synchronized (mLock) {
4834 mDefaultPermissionGrantPolicy
4835 .grantDefaultPermissionsToDefaultUseOpenWifiApp(packageName, userId);
4836 }
4837 }
4838
4839 @Override
4840 public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
4841 synchronized (mLock) {
4842 mDefaultPermissionGrantPolicy
4843 .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
4844 }
4845 }
4846
4847 @Override
Todd Kennedy583378d2019-07-12 06:50:30 -07004848 public void onNewUserCreated(int userId) {
Hai Zhang93236822020-01-09 13:15:17 -08004849 mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
Todd Kennedy583378d2019-07-12 06:50:30 -07004850 synchronized (mLock) {
Todd Kennedy583378d2019-07-12 06:50:30 -07004851 // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
4852 PermissionManagerService.this.updateAllPermissions(
4853 StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
4854 }
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004855 }
4856 }
4857
4858 private static final class OnPermissionChangeListeners extends Handler {
4859 private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
4860
4861 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
4862 new RemoteCallbackList<>();
4863
4864 OnPermissionChangeListeners(Looper looper) {
4865 super(looper);
4866 }
4867
4868 @Override
4869 public void handleMessage(Message msg) {
4870 switch (msg.what) {
4871 case MSG_ON_PERMISSIONS_CHANGED: {
4872 final int uid = msg.arg1;
4873 handleOnPermissionsChanged(uid);
4874 } break;
4875 }
4876 }
4877
4878 public void addListenerLocked(IOnPermissionsChangeListener listener) {
4879 mPermissionListeners.register(listener);
4880
4881 }
4882
4883 public void removeListenerLocked(IOnPermissionsChangeListener listener) {
4884 mPermissionListeners.unregister(listener);
4885 }
4886
4887 public void onPermissionsChanged(int uid) {
4888 if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
4889 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
4890 }
4891 }
4892
4893 private void handleOnPermissionsChanged(int uid) {
4894 final int count = mPermissionListeners.beginBroadcast();
4895 try {
4896 for (int i = 0; i < count; i++) {
4897 IOnPermissionsChangeListener callback = mPermissionListeners
4898 .getBroadcastItem(i);
4899 try {
4900 callback.onPermissionsChanged(uid);
4901 } catch (RemoteException e) {
4902 Log.e(TAG, "Permission listener is dead", e);
4903 }
4904 }
4905 } finally {
4906 mPermissionListeners.finishBroadcast();
4907 }
4908 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07004909 }
Michael Groover56a84b22020-03-04 20:41:36 -08004910
4911 /**
4912 * Allows injection of services and method responses to facilitate testing.
4913 *
4914 * <p>Test classes can create a mock of this class and pass it to the PermissionManagerService
4915 * constructor to control behavior of services and external methods during execution.
4916 * @hide
4917 */
4918 @VisibleForTesting
4919 public static class Injector {
4920 private final Context mContext;
4921
4922 /**
4923 * Public constructor that accepts a {@code context} within which to operate.
4924 */
4925 public Injector(@NonNull Context context) {
4926 mContext = context;
4927 }
4928
4929 /**
4930 * Returns the UID of the calling package.
4931 */
4932 public int getCallingUid() {
4933 return Binder.getCallingUid();
4934 }
4935
4936 /**
4937 * Returns the process ID of the calling package.
4938 */
4939 public int getCallingPid() {
4940 return Binder.getCallingPid();
4941 }
4942
4943 /**
4944 * Invalidates the package info cache.
4945 */
4946 public void invalidatePackageInfoCache() {
4947 PackageManager.invalidatePackageInfoCache();
4948 }
4949
4950 /**
4951 * Disables the permission cache.
4952 */
4953 public void disablePermissionCache() {
4954 PermissionManager.disablePermissionCache();
4955 }
4956
4957 /**
4958 * Disables the package name permission cache.
4959 */
4960 public void disablePackageNamePermissionCache() {
4961 PermissionManager.disablePackageNamePermissionCache();
4962 }
4963
4964 /**
4965 * Checks if the package running under the specified {@code pid} and {@code uid} has been
4966 * granted the provided {@code permission}.
4967 *
4968 * @return {@link PackageManager#PERMISSION_GRANTED} if the package has been granted the
4969 * permission, {@link PackageManager#PERMISSION_DENIED} otherwise
4970 */
4971 public int checkPermission(@NonNull String permission, int pid, int uid) {
4972 return mContext.checkPermission(permission, pid, uid);
4973 }
4974
4975 /**
4976 * Clears the calling identity to allow subsequent calls to be treated as coming from this
4977 * package.
4978 *
4979 * @return a token that can be used to restore the calling identity
4980 */
4981 public long clearCallingIdentity() {
4982 return Binder.clearCallingIdentity();
4983 }
4984
4985 /**
4986 * Restores the calling identity to that of the calling package based on the provided
4987 * {@code token}.
4988 */
4989 public void restoreCallingIdentity(long token) {
4990 Binder.restoreCallingIdentity(token);
4991 }
4992
4993 /**
4994 * Returns the system service with the provided {@code name}.
4995 */
4996 public Object getSystemService(@NonNull String name) {
4997 return mContext.getSystemService(name);
4998 }
4999 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07005000}