blob: bacc7acf3dc711b40d443539f46adc3535a78fb2 [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;
Evan Seversonf21a09a2020-03-19 10:54:51 -070029import static android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070030import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
Todd Kennedy3bc94722017-10-10 09:55:53 -070031import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Hai Zhang50a5a9b2019-09-19 13:57:45 -070032import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070033import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070037import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
39import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
Philip P. Moltmannba742062019-04-08 13:22:44 -070040import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
Todd Kennedyc5b0e862019-07-16 09:47:58 -070041import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
Hongwei Wangf391b552018-04-06 13:52:46 -070042import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Todd Kennedyc971a452019-07-08 16:04:52 -070043import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070044import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
Hongwei Wangf391b552018-04-06 13:52:46 -070045
Philip P. Moltmannbd278012020-03-10 14:46:27 -070046import static com.android.server.pm.ApexManager.MATCH_ACTIVE_PACKAGE;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070047import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
48import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
49import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
50import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
51import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Philip P. Moltmann48456672019-01-20 13:14:03 -080052import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
53
54import static java.util.concurrent.TimeUnit.SECONDS;
Todd Kennedy0eb97382017-10-03 16:57:22 -070055
56import android.Manifest;
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -070057import android.annotation.IntDef;
Todd Kennedy0eb97382017-10-03 16:57:22 -070058import android.annotation.NonNull;
59import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070060import android.annotation.UserIdInt;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070061import android.app.ActivityManager;
Eugene Susla922cd082020-03-11 12:38:17 -070062import android.app.AppOpsManager;
Eugene Suslad516bee2019-05-01 09:48:43 -070063import android.app.ApplicationPackageManager;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070064import android.app.IActivityManager;
wayneyang8126b1f2020-01-09 14:10:31 +080065import android.app.admin.DeviceAdminInfo;
Michael Groover56a84b22020-03-04 20:41:36 -080066import android.app.admin.DevicePolicyManager;
wayneyang8126b1f2020-01-09 14:10:31 +080067import android.app.admin.DevicePolicyManagerInternal;
Evan Severson50a77742020-01-06 10:38:19 -080068import android.compat.annotation.ChangeId;
69import android.compat.annotation.EnabledAfter;
Todd Kennedy0eb97382017-10-03 16:57:22 -070070import android.content.Context;
kholoud mohamed79a89f02020-01-15 15:30:07 +000071import android.content.PermissionChecker;
Hongming Jinbc4d0102019-08-16 14:28:30 -070072import android.content.pm.ApplicationInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070073import android.content.pm.PackageManager;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070074import android.content.pm.PackageManager.PermissionGroupInfoFlags;
75import android.content.pm.PackageManager.PermissionInfoFlags;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070076import android.content.pm.PackageManager.PermissionWhitelistFlags;
Todd Kennedy0eb97382017-10-03 16:57:22 -070077import android.content.pm.PackageManagerInternal;
78import android.content.pm.PackageParser;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070079import android.content.pm.ParceledListSlice;
Todd Kennedy460f28c2017-10-06 13:46:22 -070080import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070081import android.content.pm.PermissionInfo;
Winsonf00c7552020-01-28 12:52:01 -080082import android.content.pm.parsing.component.ParsedPermission;
83import android.content.pm.parsing.component.ParsedPermissionGroup;
Anthony Hughde787d42019-08-22 15:35:48 -070084import android.content.pm.permission.SplitPermissionInfoParcelable;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070085import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070086import android.os.Binder;
87import android.os.Build;
88import android.os.Handler;
89import android.os.HandlerThread;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070090import android.os.Looper;
91import android.os.Message;
Todd Kennedy0eb97382017-10-03 16:57:22 -070092import android.os.Process;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070093import android.os.RemoteCallbackList;
94import android.os.RemoteException;
Todd Kennedy8f135982019-07-02 07:35:15 -070095import android.os.ServiceManager;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070096import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070097import android.os.UserHandle;
98import android.os.UserManager;
99import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700100import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700101import android.os.storage.StorageManagerInternal;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700102import android.permission.IOnPermissionsChangeListener;
Todd Kennedy8f135982019-07-02 07:35:15 -0700103import android.permission.IPermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800104import android.permission.PermissionControllerManager;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -0700105import android.permission.PermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800106import android.permission.PermissionManagerInternal;
Todd Kennedyca1ea172019-07-03 15:02:28 -0700107import android.permission.PermissionManagerInternal.CheckPermissionDelegate;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700108import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700109import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700110import android.util.ArrayMap;
111import android.util.ArraySet;
Eugene Suslad516bee2019-05-01 09:48:43 -0700112import android.util.DebugUtils;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700113import android.util.EventLog;
Todd Kennedyc971a452019-07-08 16:04:52 -0700114import android.util.IntArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700115import android.util.Log;
116import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700117import android.util.SparseArray;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800118import android.util.SparseBooleanArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700119
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700120import com.android.internal.annotations.GuardedBy;
Michael Groover56a84b22020-03-04 20:41:36 -0800121import com.android.internal.annotations.VisibleForTesting;
Evan Severson50a77742020-01-06 10:38:19 -0800122import com.android.internal.compat.IPlatformCompat;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700123import com.android.internal.logging.MetricsLogger;
124import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700125import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700126import com.android.internal.util.ArrayUtils;
Todd Kennedyc971a452019-07-08 16:04:52 -0700127import com.android.internal.util.IntPair;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700128import com.android.internal.util.Preconditions;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700129import com.android.internal.util.function.pooled.PooledLambda;
130import com.android.server.FgThread;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700131import com.android.server.LocalServices;
132import com.android.server.ServiceThread;
133import com.android.server.SystemConfig;
134import com.android.server.Watchdog;
Philip P. Moltmannbd278012020-03-10 14:46:27 -0700135import com.android.server.pm.ApexManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700136import com.android.server.pm.PackageManagerServiceUtils;
137import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700138import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700139import com.android.server.pm.UserManagerService;
Winson5e0a1d52020-01-24 12:00:33 -0800140import com.android.server.pm.parsing.PackageInfoUtils;
Winsonf00c7552020-01-28 12:52:01 -0800141import com.android.server.pm.parsing.pkg.AndroidPackage;
Todd Kennedy583378d2019-07-12 06:50:30 -0700142import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider;
143import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider;
144import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800145import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700146import com.android.server.pm.permission.PermissionsState.PermissionState;
Svet Ganov3c499ea2019-07-26 17:45:56 -0700147import com.android.server.policy.PermissionPolicyInternal;
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -0700148import com.android.server.policy.SoftRestrictedPermissionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700149
150import libcore.util.EmptyArray;
151
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -0700152import java.lang.annotation.Retention;
153import java.lang.annotation.RetentionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700154import java.util.ArrayList;
Hongwei Wangf391b552018-04-06 13:52:46 -0700155import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700156import java.util.Iterator;
157import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700158import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700159import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700160import java.util.Set;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800161import java.util.concurrent.CompletableFuture;
162import java.util.concurrent.ExecutionException;
163import java.util.concurrent.TimeUnit;
164import java.util.concurrent.TimeoutException;
Todd Kennedy230c0a72019-07-03 13:06:35 -0700165import java.util.function.Consumer;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700166
167/**
168 * Manages all permissions and handles permissions related tasks.
169 */
Todd Kennedy8f135982019-07-02 07:35:15 -0700170public class PermissionManagerService extends IPermissionManager.Stub {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700171 private static final String TAG = "PackageManager";
172
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700173 /** Permission grant: not grant the permission. */
174 private static final int GRANT_DENIED = 1;
175 /** Permission grant: grant the permission as an install permission. */
176 private static final int GRANT_INSTALL = 2;
177 /** Permission grant: grant the permission as a runtime one. */
178 private static final int GRANT_RUNTIME = 3;
179 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
180 private static final int GRANT_UPGRADE = 4;
181
Philip P. Moltmann48456672019-01-20 13:14:03 -0800182 private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
183
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700184 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
185 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
186 /** Empty array to avoid allocations */
187 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700188
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -0800189 /**
190 * When these flags are set, the system should not automatically modify the permission grant
191 * state.
192 */
193 private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
194 | FLAG_PERMISSION_POLICY_FIXED
195 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
196
197 /** Permission flags set by the user */
198 private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
199 | FLAG_PERMISSION_USER_FIXED;
200
Hongwei Wangf391b552018-04-06 13:52:46 -0700201 /** If the permission of the value is granted, so is the key */
202 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
203
204 static {
205 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
206 Manifest.permission.ACCESS_FINE_LOCATION);
207 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
208 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
209 }
210
Todd Kennedy0eb97382017-10-03 16:57:22 -0700211 /** Lock to protect internal data access */
212 private final Object mLock;
213
214 /** Internal connection to the package manager */
215 private final PackageManagerInternal mPackageManagerInt;
216
217 /** Internal connection to the user manager */
218 private final UserManagerInternal mUserManagerInt;
219
Philip P. Moltmann48456672019-01-20 13:14:03 -0800220 /** Permission controller: User space permission management */
221 private PermissionControllerManager mPermissionControllerManager;
222
Evan Seversonb252d8b2019-11-20 08:41:33 -0800223 /** Map of OneTimePermissionUserManagers keyed by userId */
224 private final SparseArray<OneTimePermissionUserManager> mOneTimePermissionUserManagers =
225 new SparseArray<>();
226
Todd Kennedy0eb97382017-10-03 16:57:22 -0700227 /** Default permission policy to provide proper behaviour out-of-the-box */
228 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
229
Eugene Susla922cd082020-03-11 12:38:17 -0700230 /** App ops manager */
231 private final AppOpsManager mAppOpsManager;
232
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700233 /**
234 * Built-in permissions. Read from system configuration files. Mapping is from
235 * UID to permission name.
236 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700237 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700238
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700239 /** Built-in group IDs given to all packages. Read from system configuration files. */
240 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700241
242 private final HandlerThread mHandlerThread;
243 private final Handler mHandler;
244 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700245 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Evan Severson50a77742020-01-06 10:38:19 -0800246 private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
247 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
Todd Kennedy0eb97382017-10-03 16:57:22 -0700248
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700249 /** Internal storage for permissions and related settings */
250 @GuardedBy("mLock")
251 private final PermissionSettings mSettings;
252
Michael Groover56a84b22020-03-04 20:41:36 -0800253 /** Injector that can be used to facilitate testing. */
254 private final Injector mInjector;
255
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700256 @GuardedBy("mLock")
257 private ArraySet<String> mPrivappPermissionsViolations;
258
259 @GuardedBy("mLock")
260 private boolean mSystemReady;
261
Svet Ganov3c499ea2019-07-26 17:45:56 -0700262 @GuardedBy("mLock")
263 private PermissionPolicyInternal mPermissionPolicyInternal;
264
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700265 /**
266 * For each foreground/background permission the mapping:
267 * Background permission -> foreground permissions
268 */
269 @GuardedBy("mLock")
270 private ArrayMap<String, List<String>> mBackgroundPermissions;
271
Philip P. Moltmann48456672019-01-20 13:14:03 -0800272 /**
273 * A permission backup might contain apps that are not installed. In this case we delay the
274 * restoration until the app is installed.
275 *
276 * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
277 * there is <u>no more</u> delayed backup left.
278 */
279 @GuardedBy("mLock")
280 private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
281
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700282 /** Listeners for permission state (granting and flags) changes */
283 @GuardedBy("mLock")
284 final private ArrayList<OnRuntimePermissionStateChangedListener>
285 mRuntimePermissionStateChangedListeners = new ArrayList<>();
286
Todd Kennedyca1ea172019-07-03 15:02:28 -0700287 @GuardedBy("mLock")
288 private CheckPermissionDelegate mCheckPermissionDelegate;
289
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700290 @GuardedBy("mLock")
291 private final OnPermissionChangeListeners mOnPermissionChangeListeners;
292
Todd Kennedy583378d2019-07-12 06:50:30 -0700293 @GuardedBy("mLock")
294 private DefaultBrowserProvider mDefaultBrowserProvider;
295
296 @GuardedBy("mLock")
297 private DefaultDialerProvider mDefaultDialerProvider;
298
299 @GuardedBy("mLock")
300 private DefaultHomeProvider mDefaultHomeProvider;
301
Todd Kennedy230c0a72019-07-03 13:06:35 -0700302 // TODO: Take a look at the methods defined in the callback.
303 // The callback was initially created to support the split between permission
304 // manager and the package manager. However, it's started to be used for other
305 // purposes. It may make sense to keep as an abstraction, but, the methods
306 // necessary to be overridden may be different than what was initially needed
307 // for the split.
308 private PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
309 @Override
310 public void onGidsChanged(int appId, int userId) {
Todd Kennedyc971a452019-07-08 16:04:52 -0700311 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
Todd Kennedy230c0a72019-07-03 13:06:35 -0700312 }
313 @Override
314 public void onPermissionGranted(int uid, int userId) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700315 mOnPermissionChangeListeners.onPermissionsChanged(uid);
316
317 // Not critical; if this is lost, the application has to request again.
318 mPackageManagerInt.writeSettings(true);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700319 }
320 @Override
321 public void onInstallPermissionGranted() {
322 mPackageManagerInt.writeSettings(true);
323 }
324 @Override
325 public void onPermissionRevoked(int uid, int userId) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700326 mOnPermissionChangeListeners.onPermissionsChanged(uid);
327
328 // Critical; after this call the application should never have the permission
329 mPackageManagerInt.writeSettings(false);
330 final int appId = UserHandle.getAppId(uid);
Philip P. Moltmannd3c37422019-10-11 14:59:33 -0700331 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED));
Todd Kennedy230c0a72019-07-03 13:06:35 -0700332 }
333 @Override
334 public void onInstallPermissionRevoked() {
335 mPackageManagerInt.writeSettings(true);
336 }
337 @Override
338 public void onPermissionUpdated(int[] userIds, boolean sync) {
339 mPackageManagerInt.writePermissionSettings(userIds, !sync);
340 }
341 @Override
342 public void onInstallPermissionUpdated() {
343 mPackageManagerInt.writeSettings(true);
344 }
345 @Override
346 public void onPermissionRemoved() {
347 mPackageManagerInt.writeSettings(false);
348 }
349 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync,
350 int uid) {
351 onPermissionUpdated(updatedUserIds, sync);
Nate Myren3fb13a12019-12-11 12:30:39 -0800352 for (int i = 0; i < updatedUserIds.length; i++) {
353 int userUid = UserHandle.getUid(updatedUserIds[i], UserHandle.getAppId(uid));
354 mOnPermissionChangeListeners.onPermissionsChanged(userUid);
355 }
Todd Kennedy230c0a72019-07-03 13:06:35 -0700356 }
357 public void onInstallPermissionUpdatedNotifyListener(int uid) {
358 onInstallPermissionUpdated();
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700359 mOnPermissionChangeListeners.onPermissionsChanged(uid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700360 }
361 };
362
Todd Kennedy0eb97382017-10-03 16:57:22 -0700363 PermissionManagerService(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700364 @NonNull Object externalLock) {
Michael Groover56a84b22020-03-04 20:41:36 -0800365 this(context, externalLock, new Injector(context));
366 }
367
368 @VisibleForTesting
369 PermissionManagerService(Context context, @NonNull Object externalLock,
370 @NonNull Injector injector) {
371 mInjector = injector;
Daniel Colascionea46b7b32020-01-24 13:30:25 -0800372 // The package info cache is the cache for package and permission information.
Michael Groover56a84b22020-03-04 20:41:36 -0800373 mInjector.invalidatePackageInfoCache();
374 mInjector.disablePermissionCache();
375 mInjector.disablePackageNamePermissionCache();
Daniel Colascionea46b7b32020-01-24 13:30:25 -0800376
Todd Kennedy0eb97382017-10-03 16:57:22 -0700377 mContext = context;
378 mLock = externalLock;
379 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
380 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700381 mSettings = new PermissionSettings(mLock);
Eugene Susla922cd082020-03-11 12:38:17 -0700382 mAppOpsManager = context.getSystemService(AppOpsManager.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700383
384 mHandlerThread = new ServiceThread(TAG,
385 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
386 mHandlerThread.start();
387 mHandler = new Handler(mHandlerThread.getLooper());
388 Watchdog.getInstance().addThread(mHandler);
389
390 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700391 context, mHandlerThread.getLooper(), this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700392 SystemConfig systemConfig = SystemConfig.getInstance();
393 mSystemPermissions = systemConfig.getSystemPermissions();
394 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700395 mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());
Todd Kennedy0eb97382017-10-03 16:57:22 -0700396
397 // propagate permission configuration
398 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
399 SystemConfig.getInstance().getPermissions();
400 synchronized (mLock) {
401 for (int i=0; i<permConfig.size(); i++) {
402 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
403 BasePermission bp = mSettings.getPermissionLocked(perm.name);
404 if (bp == null) {
405 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
406 mSettings.putPermissionLocked(perm.name, bp);
407 }
408 if (perm.gids != null) {
409 bp.setGids(perm.gids, perm.perUser);
410 }
411 }
412 }
413
Philip P. Moltmann48456672019-01-20 13:14:03 -0800414 PermissionManagerServiceInternalImpl localService =
415 new PermissionManagerServiceInternalImpl();
416 LocalServices.addService(PermissionManagerServiceInternal.class, localService);
417 LocalServices.addService(PermissionManagerInternal.class, localService);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700418 }
419
420 /**
421 * Creates and returns an initialized, internal service for use by other components.
422 * <p>
423 * The object returned is identical to the one returned by the LocalServices class using:
Philip P. Moltmann48456672019-01-20 13:14:03 -0800424 * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
Todd Kennedy0eb97382017-10-03 16:57:22 -0700425 * <p>
426 * NOTE: The external lock is temporary and should be removed. This needs to be a
427 * lock created by the permission manager itself.
428 */
Philip P. Moltmann48456672019-01-20 13:14:03 -0800429 public static PermissionManagerServiceInternal create(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700430 @NonNull Object externalLock) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800431 final PermissionManagerServiceInternal permMgrInt =
432 LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700433 if (permMgrInt != null) {
434 return permMgrInt;
435 }
Todd Kennedy8f135982019-07-02 07:35:15 -0700436 PermissionManagerService permissionService =
437 (PermissionManagerService) ServiceManager.getService("permissionmgr");
438 if (permissionService == null) {
439 permissionService =
440 new PermissionManagerService(context, externalLock);
441 ServiceManager.addService("permissionmgr", permissionService);
442 }
Philip P. Moltmann48456672019-01-20 13:14:03 -0800443 return LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700444 }
445
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700446 /**
447 * This method should typically only be used when granting or revoking
448 * permissions, since the app may immediately restart after this call.
449 * <p>
450 * If you're doing surgery on app code/data, use {@link PackageFreezer} to
451 * guard your work against the app being relaunched.
452 */
453 public static void killUid(int appId, int userId, String reason) {
454 final long identity = Binder.clearCallingIdentity();
455 try {
456 IActivityManager am = ActivityManager.getService();
457 if (am != null) {
458 try {
459 am.killUid(appId, userId, reason);
460 } catch (RemoteException e) {
461 /* ignore - same process */
462 }
463 }
464 } finally {
465 Binder.restoreCallingIdentity(identity);
466 }
467 }
468
Winson14ff7172019-10-23 10:42:27 -0700469 @Nullable
470 BasePermission getPermission(String permName) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700471 synchronized (mLock) {
472 return mSettings.getPermissionLocked(permName);
473 }
474 }
475
Todd Kennedy8f135982019-07-02 07:35:15 -0700476 @Override
477 public String[] getAppOpPermissionPackages(String permName) {
478 return getAppOpPermissionPackagesInternal(permName, getCallingUid());
479 }
480
481 private String[] getAppOpPermissionPackagesInternal(String permName, int callingUid) {
482 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
483 return null;
484 }
485 synchronized (mLock) {
486 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
487 if (pkgs == null) {
488 return null;
489 }
490 return pkgs.toArray(new String[pkgs.size()]);
491 }
492 }
493
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700494 @Override
495 @NonNull
496 public ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(
497 @PermissionGroupInfoFlags int flags) {
498 final int callingUid = getCallingUid();
499 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
500 return ParceledListSlice.emptyList();
501 }
502 synchronized (mLock) {
503 final int n = mSettings.mPermissionGroups.size();
Winson14ff7172019-10-23 10:42:27 -0700504 final ArrayList<PermissionGroupInfo> out = new ArrayList<>(n);
505 for (ParsedPermissionGroup pg : mSettings.mPermissionGroups.values()) {
506 out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags));
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700507 }
508 return new ParceledListSlice<>(out);
509 }
510 }
511
512
513 @Override
514 @Nullable
515 public PermissionGroupInfo getPermissionGroupInfo(String groupName,
516 @PermissionGroupInfoFlags int flags) {
517 final int callingUid = getCallingUid();
518 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
519 return null;
520 }
521 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -0700522 return PackageInfoUtils.generatePermissionGroupInfo(
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700523 mSettings.mPermissionGroups.get(groupName), flags);
524 }
525 }
526
527
528 @Override
529 @Nullable
530 public PermissionInfo getPermissionInfo(String permName, String packageName,
531 @PermissionInfoFlags int flags) {
532 final int callingUid = getCallingUid();
533 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
534 return null;
535 }
536 synchronized (mLock) {
537 final BasePermission bp = mSettings.getPermissionLocked(permName);
538 if (bp == null) {
539 return null;
540 }
541 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
542 bp.getProtectionLevel(), packageName, callingUid);
543 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
544 }
545 }
546
547 @Override
548 @Nullable
549 public ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
550 @PermissionInfoFlags int flags) {
551 final int callingUid = getCallingUid();
552 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
553 return null;
554 }
555 synchronized (mLock) {
556 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
557 return null;
558 }
559 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
560 for (BasePermission bp : mSettings.mPermissions.values()) {
561 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
562 if (pi != null) {
563 out.add(pi);
564 }
565 }
566 return new ParceledListSlice<>(out);
567 }
568 }
569
Todd Kennedy6ffc5a62019-07-03 09:35:31 -0700570 @Override
571 public boolean addPermission(PermissionInfo info, boolean async) {
572 final int callingUid = getCallingUid();
573 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
574 throw new SecurityException("Instant apps can't add permissions");
575 }
576 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
577 throw new SecurityException("Label must be specified in permission");
578 }
579 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
580 final boolean added;
581 final boolean changed;
582 synchronized (mLock) {
583 BasePermission bp = mSettings.getPermissionLocked(info.name);
584 added = bp == null;
585 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
586 if (added) {
587 enforcePermissionCapLocked(info, tree);
588 bp = new BasePermission(info.name, tree.getSourcePackageName(),
589 BasePermission.TYPE_DYNAMIC);
590 } else if (!bp.isDynamic()) {
591 throw new SecurityException("Not allowed to modify non-dynamic permission "
592 + info.name);
593 }
594 changed = bp.addToTree(fixedLevel, info, tree);
595 if (added) {
596 mSettings.putPermissionLocked(info.name, bp);
597 }
598 }
599 if (changed) {
600 mPackageManagerInt.writeSettings(async);
601 }
602 return added;
603 }
604
605 @Override
606 public void removePermission(String permName) {
607 final int callingUid = getCallingUid();
608 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
609 throw new SecurityException("Instant applications don't have access to this method");
610 }
611 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
612 synchronized (mLock) {
613 final BasePermission bp = mSettings.getPermissionLocked(permName);
614 if (bp == null) {
615 return;
616 }
617 if (bp.isDynamic()) {
618 // TODO: switch this back to SecurityException
619 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
620 + permName);
621 }
622 mSettings.removePermissionLocked(permName);
623 mPackageManagerInt.writeSettings(false);
624 }
625 }
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700626
Todd Kennedy230c0a72019-07-03 13:06:35 -0700627 @Override
628 public int getPermissionFlags(String permName, String packageName, int userId) {
629 final int callingUid = getCallingUid();
630 return getPermissionFlagsInternal(permName, packageName, callingUid, userId);
631 }
632
633 private int getPermissionFlagsInternal(
634 String permName, String packageName, int callingUid, int userId) {
635 if (!mUserManagerInt.exists(userId)) {
636 return 0;
637 }
638
639 enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
640 enforceCrossUserPermission(callingUid, userId,
641 true, // requireFullPermission
642 false, // checkShell
643 false, // requirePermissionWhenSameUser
644 "getPermissionFlags");
645
Winson14ff7172019-10-23 10:42:27 -0700646 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
647 if (pkg == null) {
648 return 0;
649 }
650 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
651 pkg.getPackageName());
652 if (ps == null) {
Todd Kennedy230c0a72019-07-03 13:06:35 -0700653 return 0;
654 }
655 synchronized (mLock) {
656 if (mSettings.getPermissionLocked(permName) == null) {
657 return 0;
658 }
659 }
660 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
661 return 0;
662 }
Todd Kennedy230c0a72019-07-03 13:06:35 -0700663 PermissionsState permissionsState = ps.getPermissionsState();
664 return permissionsState.getPermissionFlags(permName, userId);
665 }
666
667 @Override
668 public void updatePermissionFlags(String permName, String packageName, int flagMask,
669 int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) {
670 final int callingUid = getCallingUid();
671 boolean overridePolicy = false;
672
673 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
674 long callingIdentity = Binder.clearCallingIdentity();
675 try {
676 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
677 if (checkAdjustPolicyFlagPermission) {
678 mContext.enforceCallingOrSelfPermission(
679 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
680 "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
681 + " to change policy flags");
Hai Zhang053c3a22019-08-23 15:08:03 -0700682 } else if (mPackageManagerInt.getUidTargetSdkVersion(callingUid)
Todd Kennedy230c0a72019-07-03 13:06:35 -0700683 >= Build.VERSION_CODES.Q) {
684 throw new IllegalArgumentException(
685 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
686 + " to be checked for packages targeting "
687 + Build.VERSION_CODES.Q + " or later when changing policy "
688 + "flags");
689 }
690 overridePolicy = true;
691 }
692 } finally {
693 Binder.restoreCallingIdentity(callingIdentity);
694 }
695 }
696
697 updatePermissionFlagsInternal(
698 permName, packageName, flagMask, flagValues, callingUid, userId,
699 overridePolicy, mDefaultPermissionCallback);
700 }
701
702 private void updatePermissionFlagsInternal(String permName, String packageName, int flagMask,
703 int flagValues, int callingUid, int userId, boolean overridePolicy,
704 PermissionCallback callback) {
Eugene Suslacb923e32019-08-20 16:48:55 -0700705 if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
Todd Kennedy230c0a72019-07-03 13:06:35 -0700706 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -0700707 Log.i(TAG, "System is updating flags for " + packageName + " "
Todd Kennedy230c0a72019-07-03 13:06:35 -0700708 + permName + " for user " + userId + " "
709 + DebugUtils.flagsToString(
710 PackageManager.class, "FLAG_PERMISSION_", flagMask)
711 + " := "
712 + DebugUtils.flagsToString(
713 PackageManager.class, "FLAG_PERMISSION_", flagValues)
714 + " on behalf of uid " + callingUid
715 + " " + mPackageManagerInt.getNameForUid(callingUid),
716 new RuntimeException());
717 }
718
719 if (!mUserManagerInt.exists(userId)) {
720 return;
721 }
722
723 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
724
725 enforceCrossUserPermission(callingUid, userId,
726 true, // requireFullPermission
727 true, // checkShell
728 false, // requirePermissionWhenSameUser
729 "updatePermissionFlags");
730
731 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
732 throw new SecurityException("updatePermissionFlags requires "
733 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
734 }
735
736 // Only the system can change these flags and nothing else.
737 if (callingUid != Process.SYSTEM_UID) {
738 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
739 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
740 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
741 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
742 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
743 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
744 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
745 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
746 flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
747 }
748
Winson14ff7172019-10-23 10:42:27 -0700749 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
750 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
751 packageName);
752 if (pkg == null || ps == null) {
Todd Kennedy230c0a72019-07-03 13:06:35 -0700753 Log.e(TAG, "Unknown package: " + packageName);
754 return;
755 }
756 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
757 throw new IllegalArgumentException("Unknown package: " + packageName);
758 }
759
760 final BasePermission bp;
761 synchronized (mLock) {
762 bp = mSettings.getPermissionLocked(permName);
763 }
764 if (bp == null) {
765 throw new IllegalArgumentException("Unknown permission: " + permName);
766 }
767
Todd Kennedy230c0a72019-07-03 13:06:35 -0700768 final PermissionsState permissionsState = ps.getPermissionsState();
769 final boolean hadState =
770 permissionsState.getRuntimePermissionState(permName, userId) != null;
771 final boolean permissionUpdated =
772 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
773 if (permissionUpdated && bp.isRuntime()) {
774 notifyRuntimePermissionStateChanged(packageName, userId);
775 }
776 if (permissionUpdated && callback != null) {
777 // Install and runtime permissions are stored in different places,
778 // so figure out what permission changed and persist the change.
779 if (permissionsState.getInstallPermissionState(permName) != null) {
Nate Myren3fb13a12019-12-11 12:30:39 -0800780 int userUid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
781 callback.onInstallPermissionUpdatedNotifyListener(userUid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700782 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
783 || hadState) {
Winson14ff7172019-10-23 10:42:27 -0700784 callback.onPermissionUpdatedNotifyListener(new int[]{userId}, false,
785 pkg.getUid());
Todd Kennedy230c0a72019-07-03 13:06:35 -0700786 }
787 }
788 }
789
790 /**
791 * Update the permission flags for all packages and runtime permissions of a user in order
792 * to allow device or profile owner to remove POLICY_FIXED.
793 */
794 @Override
795 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues,
796 final int userId) {
797 final int callingUid = getCallingUid();
798 if (!mUserManagerInt.exists(userId)) {
799 return;
800 }
801
802 enforceGrantRevokeRuntimePermissionPermissions(
803 "updatePermissionFlagsForAllApps");
804 enforceCrossUserPermission(callingUid, userId,
805 true, // requireFullPermission
806 true, // checkShell
807 false, // requirePermissionWhenSameUser
808 "updatePermissionFlagsForAllApps");
809
810 // Only the system can change system fixed flags.
811 final int effectiveFlagMask = (callingUid != Process.SYSTEM_UID)
812 ? flagMask : flagMask & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
813 final int effectiveFlagValues = (callingUid != Process.SYSTEM_UID)
814 ? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
815
816 final boolean[] changed = new boolean[1];
Winson14ff7172019-10-23 10:42:27 -0700817 mPackageManagerInt.forEachPackage(pkg -> {
818 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
819 pkg.getPackageName());
820 if (ps == null) {
821 return;
Todd Kennedy230c0a72019-07-03 13:06:35 -0700822 }
Winson14ff7172019-10-23 10:42:27 -0700823 final PermissionsState permissionsState = ps.getPermissionsState();
824 changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions(
825 userId, effectiveFlagMask, effectiveFlagValues);
826 mOnPermissionChangeListeners.onPermissionsChanged(pkg.getUid());
Todd Kennedy230c0a72019-07-03 13:06:35 -0700827 });
828
829 if (changed[0]) {
830 mPackageManagerInt.writePermissionSettings(new int[] { userId }, true);
831 }
832 }
833
Todd Kennedyca1ea172019-07-03 15:02:28 -0700834 @Override
835 public int checkPermission(String permName, String pkgName, int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000836 // Not using Objects.requireNonNull() here for compatibility reasons.
Hai Zhang3b049a52019-08-16 15:37:46 -0700837 if (permName == null || pkgName == null) {
838 return PackageManager.PERMISSION_DENIED;
839 }
840 if (!mUserManagerInt.exists(userId)) {
841 return PackageManager.PERMISSION_DENIED;
842 }
843
Todd Kennedyca1ea172019-07-03 15:02:28 -0700844 final CheckPermissionDelegate checkPermissionDelegate;
845 synchronized (mLock) {
Todd Kennedyca1ea172019-07-03 15:02:28 -0700846 checkPermissionDelegate = mCheckPermissionDelegate;
847 }
Hai Zhang61b4d352019-10-07 13:45:26 -0700848 if (checkPermissionDelegate == null) {
849 return checkPermissionImpl(permName, pkgName, userId);
850 }
Todd Kennedyca1ea172019-07-03 15:02:28 -0700851 return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
Hai Zhang61b4d352019-10-07 13:45:26 -0700852 this::checkPermissionImpl);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700853 }
854
Hai Zhang4fef76a2019-09-28 00:03:50 +0000855 private int checkPermissionImpl(String permName, String pkgName, int userId) {
Winson655a5b92019-10-23 10:49:32 -0700856 final AndroidPackage pkg = mPackageManagerInt.getPackage(pkgName);
Hai Zhang3b049a52019-08-16 15:37:46 -0700857 if (pkg == null) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700858 return PackageManager.PERMISSION_DENIED;
859 }
Hai Zhang4fef76a2019-09-28 00:03:50 +0000860 return checkPermissionInternal(pkg, true, permName, userId);
Hai Zhang3b049a52019-08-16 15:37:46 -0700861 }
862
Winson655a5b92019-10-23 10:49:32 -0700863 private int checkPermissionInternal(@NonNull AndroidPackage pkg, boolean isPackageExplicit,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000864 @NonNull String permissionName, @UserIdInt int userId) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700865 final int callingUid = getCallingUid();
Winson14ff7172019-10-23 10:42:27 -0700866 if (isPackageExplicit || pkg.getSharedUserId() == null) {
Patrick Baumann97b9b532018-04-11 14:51:30 +0000867 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000868 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700869 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700870 } else {
871 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000872 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700873 }
874 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700875
Winson14ff7172019-10-23 10:42:27 -0700876 final int uid = UserHandle.getUid(userId, pkg.getUid());
877 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
878 pkg.getPackageName());
Hai Zhang3b049a52019-08-16 15:37:46 -0700879 if (ps == null) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000880 return PackageManager.PERMISSION_DENIED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700881 }
882 final PermissionsState permissionsState = ps.getPermissionsState();
883
Hai Zhang4fef76a2019-09-28 00:03:50 +0000884 if (checkSinglePermissionInternal(uid, permissionsState, permissionName)) {
885 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700886 }
887
888 final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000889 if (fullerPermissionName != null
890 && checkSinglePermissionInternal(uid, permissionsState, fullerPermissionName)) {
891 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700892 }
893
Hai Zhang4fef76a2019-09-28 00:03:50 +0000894 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700895 }
896
Hai Zhang3b049a52019-08-16 15:37:46 -0700897 private boolean checkSinglePermissionInternal(int uid,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000898 @NonNull PermissionsState permissionsState, @NonNull String permissionName) {
Hai Zhang61b4d352019-10-07 13:45:26 -0700899 if (!permissionsState.hasPermission(permissionName, UserHandle.getUserId(uid))) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700900 return false;
901 }
902
903 if (mPackageManagerInt.getInstantAppPackageName(uid) != null) {
904 return mSettings.isPermissionInstant(permissionName);
905 }
906
907 return true;
908 }
909
Todd Kennedyca1ea172019-07-03 15:02:28 -0700910 @Override
911 public int checkUidPermission(String permName, int uid) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000912 // Not using Objects.requireNonNull() here for compatibility reasons.
Hai Zhang3b049a52019-08-16 15:37:46 -0700913 if (permName == null) {
914 return PackageManager.PERMISSION_DENIED;
915 }
916 final int userId = UserHandle.getUserId(uid);
917 if (!mUserManagerInt.exists(userId)) {
918 return PackageManager.PERMISSION_DENIED;
919 }
920
Todd Kennedyca1ea172019-07-03 15:02:28 -0700921 final CheckPermissionDelegate checkPermissionDelegate;
922 synchronized (mLock) {
Todd Kennedyca1ea172019-07-03 15:02:28 -0700923 checkPermissionDelegate = mCheckPermissionDelegate;
924 }
Hai Zhang61b4d352019-10-07 13:45:26 -0700925 if (checkPermissionDelegate == null) {
926 return checkUidPermissionImpl(permName, uid);
927 }
Todd Kennedyca1ea172019-07-03 15:02:28 -0700928 return checkPermissionDelegate.checkUidPermission(permName, uid,
Hai Zhang61b4d352019-10-07 13:45:26 -0700929 this::checkUidPermissionImpl);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700930 }
931
Hai Zhang4fef76a2019-09-28 00:03:50 +0000932 private int checkUidPermissionImpl(String permName, int uid) {
Winson655a5b92019-10-23 10:49:32 -0700933 final AndroidPackage pkg = mPackageManagerInt.getPackage(uid);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000934 return checkUidPermissionInternal(pkg, uid, permName);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700935 }
936
937 /**
938 * Checks whether or not the given package has been granted the specified
939 * permission. If the given package is {@code null}, we instead check the
940 * system permissions for the given UID.
941 *
942 * @see SystemConfig#getSystemPermissions()
943 */
Winson655a5b92019-10-23 10:49:32 -0700944 private int checkUidPermissionInternal(@Nullable AndroidPackage pkg, int uid,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000945 @NonNull String permissionName) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700946 if (pkg != null) {
947 final int userId = UserHandle.getUserId(uid);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000948 return checkPermissionInternal(pkg, false, permissionName, userId);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700949 }
950
Hai Zhang3b049a52019-08-16 15:37:46 -0700951 if (checkSingleUidPermissionInternal(uid, permissionName)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000952 return PackageManager.PERMISSION_GRANTED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700953 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700954
955 final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
956 if (fullerPermissionName != null
957 && checkSingleUidPermissionInternal(uid, fullerPermissionName)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000958 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700959 }
960
Hai Zhang4fef76a2019-09-28 00:03:50 +0000961 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700962 }
963
Hai Zhang3b049a52019-08-16 15:37:46 -0700964 private boolean checkSingleUidPermissionInternal(int uid, @NonNull String permissionName) {
965 synchronized (mLock) {
966 ArraySet<String> permissions = mSystemPermissions.get(uid);
967 return permissions != null && permissions.contains(permissionName);
968 }
969 }
970
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700971 @Override
Michael Groover56a84b22020-03-04 20:41:36 -0800972 public int checkDeviceIdentifierAccess(@Nullable String packageName, @Nullable String message,
973 @Nullable String callingFeatureId, int pid, int uid) {
974 // If the check is being requested by an app then only allow the app to query its own
975 // access status.
976 int callingUid = mInjector.getCallingUid();
977 int callingPid = mInjector.getCallingPid();
978 if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID && (callingUid != uid
979 || callingPid != pid)) {
980 String response = String.format(
981 "Calling uid %d, pid %d cannot check device identifier access for package %s "
982 + "(uid=%d, pid=%d)",
983 callingUid, callingPid, packageName, uid, pid);
984 Log.w(TAG, response);
985 throw new SecurityException(response);
986 }
987 // Allow system and root access to the device identifiers.
988 final int appId = UserHandle.getAppId(uid);
989 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
990 return PackageManager.PERMISSION_GRANTED;
991 }
992 // Allow access to packages that have the READ_PRIVILEGED_PHONE_STATE permission.
993 if (mInjector.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid,
994 uid) == PackageManager.PERMISSION_GRANTED) {
995 return PackageManager.PERMISSION_GRANTED;
996 }
997 // If the calling package is not null then perform the appop and device / profile owner
998 // check.
999 if (packageName != null) {
1000 // Allow access to a package that has been granted the READ_DEVICE_IDENTIFIERS appop.
1001 long token = mInjector.clearCallingIdentity();
1002 AppOpsManager appOpsManager = (AppOpsManager) mInjector.getSystemService(
1003 Context.APP_OPS_SERVICE);
1004 try {
1005 if (appOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, uid,
1006 packageName, callingFeatureId, message) == AppOpsManager.MODE_ALLOWED) {
1007 return PackageManager.PERMISSION_GRANTED;
1008 }
1009 } finally {
1010 mInjector.restoreCallingIdentity(token);
1011 }
1012 // Check if the calling packages meets the device / profile owner requirements for
1013 // identifier access.
1014 DevicePolicyManager devicePolicyManager =
1015 (DevicePolicyManager) mInjector.getSystemService(Context.DEVICE_POLICY_SERVICE);
1016 if (devicePolicyManager != null && devicePolicyManager.hasDeviceIdentifierAccess(
1017 packageName, pid, uid)) {
1018 return PackageManager.PERMISSION_GRANTED;
1019 }
1020 }
1021 return PackageManager.PERMISSION_DENIED;
1022 }
1023
1024 @Override
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001025 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
1026 mContext.enforceCallingOrSelfPermission(
1027 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
1028 "addOnPermissionsChangeListener");
1029
1030 synchronized (mLock) {
1031 mOnPermissionChangeListeners.addListenerLocked(listener);
1032 }
1033 }
1034
1035 @Override
1036 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
1037 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
1038 throw new SecurityException("Instant applications don't have access to this method");
1039 }
1040 synchronized (mLock) {
1041 mOnPermissionChangeListeners.removeListenerLocked(listener);
1042 }
1043 }
1044
1045 @Override
1046 @Nullable public List<String> getWhitelistedRestrictedPermissions(@NonNull String packageName,
1047 @PermissionWhitelistFlags int flags, @UserIdInt int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001048 Objects.requireNonNull(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001049 Preconditions.checkFlagsArgument(flags,
1050 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1051 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
1052 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
1053 Preconditions.checkArgumentNonNegative(userId, null);
1054
1055 if (UserHandle.getCallingUserId() != userId) {
1056 mContext.enforceCallingOrSelfPermission(
1057 android.Manifest.permission.INTERACT_ACROSS_USERS,
1058 "getWhitelistedRestrictedPermissions for user " + userId);
1059 }
1060
Winson14ff7172019-10-23 10:42:27 -07001061 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001062 if (pkg == null) {
1063 return null;
1064 }
1065
1066 final int callingUid = Binder.getCallingUid();
1067 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
1068 return null;
1069 }
1070 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1071 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1072 == PackageManager.PERMISSION_GRANTED;
1073 final boolean isCallerInstallerOnRecord =
1074 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1075
1076 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
1077 && !isCallerPrivileged) {
1078 throw new SecurityException("Querying system whitelist requires "
1079 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1080 }
1081
1082 if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1083 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) {
1084 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1085 throw new SecurityException("Querying upgrade or installer whitelist"
1086 + " requires being installer on record or "
1087 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1088 }
1089 }
1090
1091 final long identity = Binder.clearCallingIdentity();
1092 try {
1093 final PermissionsState permissionsState =
Winson14ff7172019-10-23 10:42:27 -07001094 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001095 if (permissionsState == null) {
1096 return null;
1097 }
1098
1099 int queryFlags = 0;
1100 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
1101 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
1102 }
1103 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1104 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
1105 }
1106 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1107 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
1108 }
1109
1110 ArrayList<String> whitelistedPermissions = null;
1111
Winson14ff7172019-10-23 10:42:27 -07001112 final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001113 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07001114 final String permissionName = pkg.getRequestedPermissions().get(i);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001115 final int currentFlags =
1116 permissionsState.getPermissionFlags(permissionName, userId);
1117 if ((currentFlags & queryFlags) != 0) {
1118 if (whitelistedPermissions == null) {
1119 whitelistedPermissions = new ArrayList<>();
1120 }
1121 whitelistedPermissions.add(permissionName);
1122 }
1123 }
1124
1125 return whitelistedPermissions;
1126 } finally {
1127 Binder.restoreCallingIdentity(identity);
1128 }
1129 }
1130
1131 @Override
1132 public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
1133 @NonNull String permName, @PermissionWhitelistFlags int flags,
1134 @UserIdInt int userId) {
1135 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001136 Objects.requireNonNull(permName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001137
1138 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1139 return false;
1140 }
1141
1142 List<String> permissions =
1143 getWhitelistedRestrictedPermissions(packageName, flags, userId);
1144 if (permissions == null) {
1145 permissions = new ArrayList<>(1);
1146 }
1147 if (permissions.indexOf(permName) < 0) {
1148 permissions.add(permName);
1149 return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
1150 flags, userId);
1151 }
1152 return false;
1153 }
1154
1155 private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
1156 @NonNull String permName) {
1157 synchronized (mLock) {
1158 final BasePermission bp = mSettings.getPermissionLocked(permName);
1159 if (bp == null) {
1160 Slog.w(TAG, "No such permissions: " + permName);
1161 return false;
1162 }
1163 if (bp.isHardOrSoftRestricted() && bp.isImmutablyRestricted()
1164 && mContext.checkCallingOrSelfPermission(
1165 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1166 != PackageManager.PERMISSION_GRANTED) {
1167 throw new SecurityException("Cannot modify whitelisting of an immutably "
1168 + "restricted permission: " + permName);
1169 }
1170 return true;
1171 }
1172 }
1173
1174 @Override
1175 public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
1176 @NonNull String permName, @PermissionWhitelistFlags int flags,
1177 @UserIdInt int userId) {
1178 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001179 Objects.requireNonNull(permName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001180
1181 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1182 return false;
1183 }
1184
1185 final List<String> permissions =
1186 getWhitelistedRestrictedPermissions(packageName, flags, userId);
1187 if (permissions != null && permissions.remove(permName)) {
1188 return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
1189 flags, userId);
1190 }
1191 return false;
1192 }
1193
1194 private boolean setWhitelistedRestrictedPermissionsInternal(@NonNull String packageName,
1195 @Nullable List<String> permissions, @PermissionWhitelistFlags int flags,
1196 @UserIdInt int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001197 Objects.requireNonNull(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001198 Preconditions.checkFlagsArgument(flags,
1199 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1200 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
1201 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
1202 Preconditions.checkArgument(Integer.bitCount(flags) == 1);
1203 Preconditions.checkArgumentNonNegative(userId, null);
1204
1205 if (UserHandle.getCallingUserId() != userId) {
1206 mContext.enforceCallingOrSelfPermission(
1207 Manifest.permission.INTERACT_ACROSS_USERS,
1208 "setWhitelistedRestrictedPermissions for user " + userId);
1209 }
1210
Winson14ff7172019-10-23 10:42:27 -07001211 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001212 if (pkg == null) {
1213 return false;
1214 }
1215
1216 final int callingUid = Binder.getCallingUid();
1217 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
1218 return false;
1219 }
1220
1221 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1222 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1223 == PackageManager.PERMISSION_GRANTED;
1224 final boolean isCallerInstallerOnRecord =
1225 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1226
1227 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
1228 && !isCallerPrivileged) {
1229 throw new SecurityException("Modifying system whitelist requires "
1230 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1231 }
1232
1233 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1234 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1235 throw new SecurityException("Modifying upgrade whitelist requires"
1236 + " being installer on record or "
1237 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1238 }
1239 final List<String> whitelistedPermissions =
Winson14ff7172019-10-23 10:42:27 -07001240 getWhitelistedRestrictedPermissions(pkg.getPackageName(), flags, userId);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001241 if (permissions == null || permissions.isEmpty()) {
1242 if (whitelistedPermissions == null || whitelistedPermissions.isEmpty()) {
1243 return true;
1244 }
1245 } else {
1246 // Only the system can add and remove while the installer can only remove.
1247 final int permissionCount = permissions.size();
1248 for (int i = 0; i < permissionCount; i++) {
1249 if ((whitelistedPermissions == null
1250 || !whitelistedPermissions.contains(permissions.get(i)))
1251 && !isCallerPrivileged) {
1252 throw new SecurityException("Adding to upgrade whitelist requires"
1253 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1254 }
1255 }
1256 }
1257
1258 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1259 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1260 throw new SecurityException("Modifying installer whitelist requires"
1261 + " being installer on record or "
1262 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1263 }
1264 }
1265 }
1266
1267 final long identity = Binder.clearCallingIdentity();
1268 try {
1269 setWhitelistedRestrictedPermissionsForUser(
1270 pkg, userId, permissions, Process.myUid(), flags, mDefaultPermissionCallback);
1271 } finally {
1272 Binder.restoreCallingIdentity(identity);
1273 }
1274
1275 return true;
1276 }
1277
Todd Kennedyc971a452019-07-08 16:04:52 -07001278 @Override
Eugene Susla922cd082020-03-11 12:38:17 -07001279 public boolean setAutoRevokeWhitelisted(
1280 @NonNull String packageName, boolean whitelisted, int userId) {
1281 Objects.requireNonNull(packageName);
1282
1283 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1284 final int callingUid = Binder.getCallingUid();
1285
1286 if (!checkAutoRevokeAccess(pkg, callingUid)) {
1287 return false;
1288 }
1289
1290 if (mAppOpsManager
1291 .checkOpNoThrow(AppOpsManager.OP_AUTO_REVOKE_MANAGED_BY_INSTALLER,
1292 callingUid, packageName)
1293 != MODE_ALLOWED) {
1294 // Whitelist user set - don't override
1295 return false;
1296 }
1297
1298 final long identity = Binder.clearCallingIdentity();
1299 try {
1300 mAppOpsManager.setMode(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
1301 callingUid, packageName,
1302 whitelisted ? MODE_IGNORED : MODE_ALLOWED);
1303 } finally {
1304 Binder.restoreCallingIdentity(identity);
1305 }
1306 return true;
1307 }
1308
1309 private boolean checkAutoRevokeAccess(AndroidPackage pkg, int callingUid) {
1310 if (pkg == null) {
1311 return false;
1312 }
1313
1314 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1315 Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS)
1316 == PackageManager.PERMISSION_GRANTED;
1317 final boolean isCallerInstallerOnRecord =
1318 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1319
1320 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1321 throw new SecurityException("Caller must either hold "
1322 + Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS
1323 + " or be the installer on record");
1324 }
1325 return true;
1326 }
1327
1328 @Override
1329 public boolean isAutoRevokeWhitelisted(@NonNull String packageName, int userId) {
1330 Objects.requireNonNull(packageName);
1331
1332 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1333 final int callingUid = Binder.getCallingUid();
1334
1335 if (!checkAutoRevokeAccess(pkg, callingUid)) {
1336 return false;
1337 }
1338
1339 final long identity = Binder.clearCallingIdentity();
1340 try {
1341 return mAppOpsManager.checkOpNoThrow(
1342 AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, callingUid, packageName)
1343 == MODE_IGNORED;
1344 } finally {
1345 Binder.restoreCallingIdentity(identity);
1346 }
1347 }
1348
1349 @Override
Todd Kennedyc971a452019-07-08 16:04:52 -07001350 public void grantRuntimePermission(String packageName, String permName, final int userId) {
1351 final int callingUid = Binder.getCallingUid();
1352 final boolean overridePolicy =
1353 checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
1354 == PackageManager.PERMISSION_GRANTED;
1355
1356 grantRuntimePermissionInternal(permName, packageName, overridePolicy,
1357 callingUid, userId, mDefaultPermissionCallback);
1358 }
1359
1360 // TODO swap permission name and package name
1361 private void grantRuntimePermissionInternal(String permName, String packageName,
1362 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
1363 if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
1364 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001365 Log.i(TAG, "System is granting " + packageName + " "
Todd Kennedyc971a452019-07-08 16:04:52 -07001366 + permName + " for user " + userId + " on behalf of uid " + callingUid
1367 + " " + mPackageManagerInt.getNameForUid(callingUid),
1368 new RuntimeException());
1369 }
1370 if (!mUserManagerInt.exists(userId)) {
1371 Log.e(TAG, "No such user:" + userId);
1372 return;
1373 }
1374
1375 mContext.enforceCallingOrSelfPermission(
1376 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1377 "grantRuntimePermission");
1378
1379 enforceCrossUserPermission(callingUid, userId,
1380 true, // requireFullPermission
1381 true, // checkShell
1382 false, // requirePermissionWhenSameUser
1383 "grantRuntimePermission");
1384
Winson14ff7172019-10-23 10:42:27 -07001385 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1386 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
1387 packageName);
1388 if (pkg == null || ps == null) {
Hai Zhangb94491c2019-07-31 14:07:17 -07001389 Log.e(TAG, "Unknown package: " + packageName);
1390 return;
Todd Kennedyc971a452019-07-08 16:04:52 -07001391 }
1392 final BasePermission bp;
1393 synchronized (mLock) {
1394 bp = mSettings.getPermissionLocked(permName);
1395 }
1396 if (bp == null) {
1397 throw new IllegalArgumentException("Unknown permission: " + permName);
1398 }
1399 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1400 throw new IllegalArgumentException("Unknown package: " + packageName);
1401 }
1402
Winson14ff7172019-10-23 10:42:27 -07001403 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
Todd Kennedyc971a452019-07-08 16:04:52 -07001404
1405 // If a permission review is required for legacy apps we represent
1406 // their permissions as always granted runtime ones since we need
1407 // to keep the review required permission flag per user while an
1408 // install permission's state is shared across all users.
Winson14ff7172019-10-23 10:42:27 -07001409 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Todd Kennedyc971a452019-07-08 16:04:52 -07001410 && bp.isRuntime()) {
1411 return;
1412 }
1413
Winson14ff7172019-10-23 10:42:27 -07001414 final int uid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
Todd Kennedyc971a452019-07-08 16:04:52 -07001415
Todd Kennedyc971a452019-07-08 16:04:52 -07001416 final PermissionsState permissionsState = ps.getPermissionsState();
1417
1418 final int flags = permissionsState.getPermissionFlags(permName, userId);
1419 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1420 Log.e(TAG, "Cannot grant system fixed permission "
1421 + permName + " for package " + packageName);
1422 return;
1423 }
1424 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1425 Log.e(TAG, "Cannot grant policy fixed permission "
1426 + permName + " for package " + packageName);
1427 return;
1428 }
1429
1430 if (bp.isHardRestricted()
1431 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
1432 Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
1433 + permName + " for package " + packageName);
1434 return;
1435 }
1436
1437 if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
Winson33eacc62020-01-24 12:02:58 -08001438 pkg.toAppInfoWithoutState(), pkg, UserHandle.of(userId), permName)
Winson6571c8a2019-10-23 17:00:42 -07001439 .mayGrantPermission()) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001440 Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
1441 + packageName);
1442 return;
1443 }
1444
1445 if (bp.isDevelopment()) {
1446 // Development permissions must be handled specially, since they are not
1447 // normal runtime permissions. For now they apply to all users.
1448 if (permissionsState.grantInstallPermission(bp)
1449 != PERMISSION_OPERATION_FAILURE) {
1450 if (callback != null) {
1451 callback.onInstallPermissionGranted();
1452 }
1453 }
1454 return;
1455 }
1456
1457 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1458 throw new SecurityException("Cannot grant non-ephemeral permission"
1459 + permName + " for package " + packageName);
1460 }
1461
Winson14ff7172019-10-23 10:42:27 -07001462 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001463 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1464 return;
1465 }
1466
1467 final int result = permissionsState.grantRuntimePermission(bp, userId);
1468 switch (result) {
1469 case PERMISSION_OPERATION_FAILURE: {
1470 return;
1471 }
1472
1473 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1474 if (callback != null) {
Winson14ff7172019-10-23 10:42:27 -07001475 callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId);
Todd Kennedyc971a452019-07-08 16:04:52 -07001476 }
1477 }
1478 break;
1479 }
1480
1481 if (bp.isRuntime()) {
1482 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
1483 }
1484
1485 if (callback != null) {
1486 callback.onPermissionGranted(uid, userId);
1487 }
1488
1489 if (bp.isRuntime()) {
1490 notifyRuntimePermissionStateChanged(packageName, userId);
1491 }
1492
1493 // Only need to do this if user is initialized. Otherwise it's a new user
1494 // and there are no processes running as the user yet and there's no need
1495 // to make an expensive call to remount processes for the changed permissions.
1496 if (READ_EXTERNAL_STORAGE.equals(permName)
1497 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1498 final long token = Binder.clearCallingIdentity();
1499 try {
1500 if (mUserManagerInt.isUserInitialized(userId)) {
1501 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1502 StorageManagerInternal.class);
1503 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1504 }
1505 } finally {
1506 Binder.restoreCallingIdentity(token);
1507 }
1508 }
1509
1510 }
1511
1512 @Override
1513 public void revokeRuntimePermission(String packageName, String permName, int userId) {
1514 final int callingUid = Binder.getCallingUid();
1515 final boolean overridePolicy =
1516 checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
1517 == PackageManager.PERMISSION_GRANTED;
1518
1519 revokeRuntimePermissionInternal(permName, packageName, overridePolicy, callingUid, userId,
1520 mDefaultPermissionCallback);
1521 }
1522
1523 // TODO swap permission name and package name
1524 private void revokeRuntimePermissionInternal(String permName, String packageName,
1525 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001526 if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
Todd Kennedyc971a452019-07-08 16:04:52 -07001527 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001528 Log.i(TAG, "System is revoking " + packageName + " "
Todd Kennedyc971a452019-07-08 16:04:52 -07001529 + permName + " for user " + userId + " on behalf of uid " + callingUid
1530 + " " + mPackageManagerInt.getNameForUid(callingUid),
1531 new RuntimeException());
1532 }
1533 if (!mUserManagerInt.exists(userId)) {
1534 Log.e(TAG, "No such user:" + userId);
1535 return;
1536 }
1537
1538 mContext.enforceCallingOrSelfPermission(
1539 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1540 "revokeRuntimePermission");
1541
1542 enforceCrossUserPermission(callingUid, userId,
1543 true, // requireFullPermission
1544 true, // checkShell
1545 false, // requirePermissionWhenSameUser
1546 "revokeRuntimePermission");
1547
Winson14ff7172019-10-23 10:42:27 -07001548 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1549 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
1550 packageName);
1551 if (pkg == null || ps == null) {
Hai Zhangb94491c2019-07-31 14:07:17 -07001552 Log.e(TAG, "Unknown package: " + packageName);
1553 return;
Todd Kennedyc971a452019-07-08 16:04:52 -07001554 }
1555 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1556 throw new IllegalArgumentException("Unknown package: " + packageName);
1557 }
1558 final BasePermission bp = mSettings.getPermissionLocked(permName);
1559 if (bp == null) {
1560 throw new IllegalArgumentException("Unknown permission: " + permName);
1561 }
1562
Winson14ff7172019-10-23 10:42:27 -07001563 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
Todd Kennedyc971a452019-07-08 16:04:52 -07001564
1565 // If a permission review is required for legacy apps we represent
1566 // their permissions as always granted runtime ones since we need
1567 // to keep the review required permission flag per user while an
1568 // install permission's state is shared across all users.
Winson14ff7172019-10-23 10:42:27 -07001569 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Todd Kennedyc971a452019-07-08 16:04:52 -07001570 && bp.isRuntime()) {
1571 return;
1572 }
1573
Todd Kennedyc971a452019-07-08 16:04:52 -07001574 final PermissionsState permissionsState = ps.getPermissionsState();
1575
1576 final int flags = permissionsState.getPermissionFlags(permName, userId);
1577 // Only the system may revoke SYSTEM_FIXED permissions.
1578 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1579 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1580 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
1581 + permName + " for package " + packageName);
1582 }
1583 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1584 throw new SecurityException("Cannot revoke policy fixed permission "
1585 + permName + " for package " + packageName);
1586 }
1587
1588 if (bp.isDevelopment()) {
1589 // Development permissions must be handled specially, since they are not
1590 // normal runtime permissions. For now they apply to all users.
1591 if (permissionsState.revokeInstallPermission(bp)
1592 != PERMISSION_OPERATION_FAILURE) {
1593 if (callback != null) {
1594 mDefaultPermissionCallback.onInstallPermissionRevoked();
1595 }
1596 }
1597 return;
1598 }
1599
1600 // Permission is already revoked, no need to do anything.
1601 if (!permissionsState.hasRuntimePermission(permName, userId)) {
1602 return;
1603 }
1604
1605 if (permissionsState.revokeRuntimePermission(bp, userId)
1606 == PERMISSION_OPERATION_FAILURE) {
1607 return;
1608 }
1609
1610 if (bp.isRuntime()) {
1611 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
1612 }
1613
1614 if (callback != null) {
Nate Myren8f6a9092019-08-27 15:50:03 -07001615 callback.onPermissionRevoked(UserHandle.getUid(userId,
Winson14ff7172019-10-23 10:42:27 -07001616 UserHandle.getAppId(pkg.getUid())), userId);
Todd Kennedyc971a452019-07-08 16:04:52 -07001617 }
1618
1619 if (bp.isRuntime()) {
1620 notifyRuntimePermissionStateChanged(packageName, userId);
1621 }
1622 }
1623
1624 @Override
1625 public void resetRuntimePermissions() {
1626 mContext.enforceCallingOrSelfPermission(
1627 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1628 "revokeRuntimePermission");
1629
1630 final int callingUid = Binder.getCallingUid();
1631 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
1632 mContext.enforceCallingOrSelfPermission(
1633 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1634 "resetRuntimePermissions");
1635 }
1636
1637 updateAllPermissions(
1638 StorageManager.UUID_PRIVATE_INTERNAL, false, mDefaultPermissionCallback);
1639 for (final int userId : UserManagerService.getInstance().getUserIds()) {
1640 mPackageManagerInt.forEachPackage(
Winson14ff7172019-10-23 10:42:27 -07001641 (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
Todd Kennedyc971a452019-07-08 16:04:52 -07001642 }
1643 }
1644
1645 /**
1646 * Reverts user permission state changes (permissions and flags).
1647 *
Hai Zhang4ffebb72019-07-18 14:50:58 -07001648 * @param pkg The package for which to reset.
Todd Kennedyc971a452019-07-08 16:04:52 -07001649 * @param userId The device user for which to do a reset.
1650 */
Patrick Baumann865fd3a2019-07-26 14:53:02 -07001651 @GuardedBy("mLock")
Winson14ff7172019-10-23 10:42:27 -07001652 private void resetRuntimePermissionsInternal(final AndroidPackage pkg,
Todd Kennedyc971a452019-07-08 16:04:52 -07001653 final int userId) {
Winson14ff7172019-10-23 10:42:27 -07001654 final String packageName = pkg.getPackageName();
Todd Kennedyc971a452019-07-08 16:04:52 -07001655
1656 // These are flags that can change base on user actions.
1657 final int userSettableMask = FLAG_PERMISSION_USER_SET
1658 | FLAG_PERMISSION_USER_FIXED
Hai Zhang50a5a9b2019-09-19 13:57:45 -07001659 | FLAG_PERMISSION_REVOKED_COMPAT
Evan Seversonf21a09a2020-03-19 10:54:51 -07001660 | FLAG_PERMISSION_REVIEW_REQUIRED
1661 | FLAG_PERMISSION_ONE_TIME;
Todd Kennedyc971a452019-07-08 16:04:52 -07001662
1663 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
1664 | FLAG_PERMISSION_POLICY_FIXED;
1665
1666 // Delay and combine non-async permission callbacks
Winson14ff7172019-10-23 10:42:27 -07001667 final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
Todd Kennedyc971a452019-07-08 16:04:52 -07001668 final boolean[] permissionRemoved = new boolean[1];
1669 final ArraySet<Long> revokedPermissions = new ArraySet<>();
1670 final IntArray syncUpdatedUsers = new IntArray(permissionCount);
1671 final IntArray asyncUpdatedUsers = new IntArray(permissionCount);
1672
1673 PermissionCallback delayingPermCallback = new PermissionCallback() {
1674 public void onGidsChanged(int appId, int userId) {
1675 mDefaultPermissionCallback.onGidsChanged(appId, userId);
1676 }
1677
1678 public void onPermissionChanged() {
1679 mDefaultPermissionCallback.onPermissionChanged();
1680 }
1681
1682 public void onPermissionGranted(int uid, int userId) {
1683 mDefaultPermissionCallback.onPermissionGranted(uid, userId);
1684 }
1685
1686 public void onInstallPermissionGranted() {
1687 mDefaultPermissionCallback.onInstallPermissionGranted();
1688 }
1689
1690 public void onPermissionRevoked(int uid, int userId) {
1691 revokedPermissions.add(IntPair.of(uid, userId));
1692
1693 syncUpdatedUsers.add(userId);
1694 }
1695
1696 public void onInstallPermissionRevoked() {
1697 mDefaultPermissionCallback.onInstallPermissionRevoked();
1698 }
1699
1700 public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1701 for (int userId : updatedUserIds) {
1702 if (sync) {
1703 syncUpdatedUsers.add(userId);
1704 asyncUpdatedUsers.remove(userId);
1705 } else {
1706 // Don't override sync=true by sync=false
1707 if (syncUpdatedUsers.indexOf(userId) == -1) {
1708 asyncUpdatedUsers.add(userId);
1709 }
1710 }
1711 }
1712 }
1713
1714 public void onPermissionRemoved() {
1715 permissionRemoved[0] = true;
1716 }
1717
1718 public void onInstallPermissionUpdated() {
1719 mDefaultPermissionCallback.onInstallPermissionUpdated();
1720 }
Nate Myrencc9e2c72019-11-08 14:57:15 -08001721
1722 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds,
1723 boolean sync, int uid) {
1724 onPermissionUpdated(updatedUserIds, sync);
1725 mOnPermissionChangeListeners.onPermissionsChanged(uid);
1726 }
1727
1728 public void onInstallPermissionUpdatedNotifyListener(int uid) {
1729 mDefaultPermissionCallback.onInstallPermissionUpdatedNotifyListener(uid);
1730 }
Todd Kennedyc971a452019-07-08 16:04:52 -07001731 };
1732
1733 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07001734 final String permName = pkg.getRequestedPermissions().get(i);
Todd Kennedyc971a452019-07-08 16:04:52 -07001735 final BasePermission bp;
1736 synchronized (mLock) {
1737 bp = mSettings.getPermissionLocked(permName);
1738 }
1739 if (bp == null) {
1740 continue;
1741 }
1742
1743 if (bp.isRemoved()) {
1744 continue;
1745 }
1746
1747 // If shared user we just reset the state to which only this app contributed.
Alan Stokes20fbef22019-12-17 15:33:12 +00001748 final String[] pkgNames = mPackageManagerInt.getSharedUserPackagesForPackage(
1749 pkg.getPackageName(), userId);
1750 if (pkgNames.length > 0) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001751 boolean used = false;
Alan Stokes20fbef22019-12-17 15:33:12 +00001752 for (String sharedPkgName : pkgNames) {
Winson14ff7172019-10-23 10:42:27 -07001753 final AndroidPackage sharedPkg =
Todd Kennedyc971a452019-07-08 16:04:52 -07001754 mPackageManagerInt.getPackage(sharedPkgName);
Winson14ff7172019-10-23 10:42:27 -07001755 if (sharedPkg != null && !sharedPkg.getPackageName().equals(packageName)
1756 && sharedPkg.getRequestedPermissions().contains(permName)) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001757 used = true;
1758 break;
1759 }
1760 }
1761 if (used) {
1762 continue;
1763 }
1764 }
1765
1766 final int oldFlags =
1767 getPermissionFlagsInternal(permName, packageName, Process.SYSTEM_UID, userId);
1768
1769 // Always clear the user settable flags.
1770 // If permission review is enabled and this is a legacy app, mark the
1771 // permission as requiring a review as this is the initial state.
1772 final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
Hai Zhang053c3a22019-08-23 15:08:03 -07001773 final int targetSdk = mPackageManagerInt.getUidTargetSdkVersion(uid);
Todd Kennedyc971a452019-07-08 16:04:52 -07001774 final int flags = (targetSdk < Build.VERSION_CODES.M && bp.isRuntime())
Hai Zhang50a5a9b2019-09-19 13:57:45 -07001775 ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT
Todd Kennedyc971a452019-07-08 16:04:52 -07001776 : 0;
1777
1778 updatePermissionFlagsInternal(
1779 permName, packageName, userSettableMask, flags, Process.SYSTEM_UID, userId,
1780 false, delayingPermCallback);
1781
1782 // Below is only runtime permission handling.
1783 if (!bp.isRuntime()) {
1784 continue;
1785 }
1786
1787 // Never clobber system or policy.
1788 if ((oldFlags & policyOrSystemFlags) != 0) {
1789 continue;
1790 }
1791
1792 // If this permission was granted by default, make sure it is.
1793 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
Hai Zhangab6a6822019-10-18 00:34:06 +00001794 // PermissionPolicyService will handle the app op for runtime permissions later.
Todd Kennedyc971a452019-07-08 16:04:52 -07001795 grantRuntimePermissionInternal(permName, packageName, false,
1796 Process.SYSTEM_UID, userId, delayingPermCallback);
1797 // If permission review is enabled the permissions for a legacy apps
1798 // are represented as constantly granted runtime ones, so don't revoke.
1799 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
1800 // Otherwise, reset the permission.
1801 revokeRuntimePermissionInternal(permName, packageName, false, Process.SYSTEM_UID,
1802 userId, delayingPermCallback);
1803 }
1804 }
1805
1806 // Execute delayed callbacks
1807 if (permissionRemoved[0]) {
1808 mDefaultPermissionCallback.onPermissionRemoved();
1809 }
1810
1811 // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
1812 // kill uid while holding mPackages-lock
1813 if (!revokedPermissions.isEmpty()) {
1814 int numRevokedPermissions = revokedPermissions.size();
1815 for (int i = 0; i < numRevokedPermissions; i++) {
1816 int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
1817 int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));
1818
1819 mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);
1820
1821 // Kill app later as we are holding mPackages
1822 mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
1823 KILL_APP_REASON_PERMISSIONS_REVOKED));
1824 }
1825 }
1826
1827 mPackageManagerInt.writePermissionSettings(syncUpdatedUsers.toArray(), false);
1828 mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true);
1829 }
1830
Todd Kennedy583378d2019-07-12 06:50:30 -07001831 @Override
1832 public String getDefaultBrowser(int userId) {
1833 final int callingUid = Binder.getCallingUid();
1834 if (UserHandle.getUserId(callingUid) != userId) {
1835 mContext.enforceCallingOrSelfPermission(
1836 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
1837 }
1838 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
1839 return null;
1840 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001841 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001842 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001843 provider = mDefaultBrowserProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001844 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001845 return provider != null ? provider.getDefaultBrowser(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07001846 }
1847
1848 @Override
1849 public boolean setDefaultBrowser(String packageName, int userId) {
1850 mContext.enforceCallingOrSelfPermission(
1851 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
1852 if (UserHandle.getCallingUserId() != userId) {
1853 mContext.enforceCallingOrSelfPermission(
1854 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
1855 }
1856 return setDefaultBrowserInternal(packageName, false, true, userId);
1857 }
1858
1859 private boolean setDefaultBrowserInternal(String packageName, boolean async,
1860 boolean doGrant, int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001861 if (userId == UserHandle.USER_ALL) {
1862 return false;
1863 }
1864 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001865 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001866 provider = mDefaultBrowserProvider;
1867 }
1868 if (provider == null) {
1869 return false;
1870 }
1871 if (async) {
1872 provider.setDefaultBrowserAsync(packageName, userId);
1873 } else {
1874 if (!provider.setDefaultBrowser(packageName, userId)) {
Todd Kennedy583378d2019-07-12 06:50:30 -07001875 return false;
1876 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001877 }
1878 if (doGrant && packageName != null) {
1879 synchronized (mLock) {
1880 mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
1881 userId);
Todd Kennedy583378d2019-07-12 06:50:30 -07001882 }
1883 }
1884 return true;
1885 }
1886
1887 @Override
1888 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
1889 final int callingUid = Binder.getCallingUid();
1890 PackageManagerServiceUtils
1891 .enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
1892 synchronized (mLock) {
1893 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1894 .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
1895 }
1896 }
1897
1898 @Override
1899 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
1900 final int callingUid = Binder.getCallingUid();
1901 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1902 "grantDefaultPermissionsToEnabledImsServices", callingUid);
1903 synchronized (mLock) {
1904 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1905 .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
1906 }
1907 }
1908
1909 @Override
1910 public void grantDefaultPermissionsToEnabledTelephonyDataServices(
1911 String[] packageNames, int userId) {
1912 final int callingUid = Binder.getCallingUid();
1913 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1914 "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
1915 synchronized (mLock) {
1916 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1917 .grantDefaultPermissionsToEnabledTelephonyDataServices(
1918 packageNames, userId));
1919 }
1920 }
1921
1922 @Override
1923 public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
1924 String[] packageNames, int userId) {
1925 final int callingUid = Binder.getCallingUid();
1926 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1927 "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
1928 synchronized (mLock) {
1929 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1930 .revokeDefaultPermissionsFromDisabledTelephonyDataServices(
1931 packageNames, userId));
1932 }
1933 }
1934
1935 @Override
1936 public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
1937 final int callingUid = Binder.getCallingUid();
1938 PackageManagerServiceUtils
1939 .enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
1940 synchronized (mLock) {
1941 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1942 .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
1943 }
1944 }
1945
1946 @Override
1947 public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
1948 final int callingUid = Binder.getCallingUid();
1949 PackageManagerServiceUtils
1950 .enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
1951 synchronized (mLock) {
1952 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1953 .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
1954 }
1955 }
1956
Todd Kennedyc5b0e862019-07-16 09:47:58 -07001957 @Override
1958 public void setPermissionEnforced(String permName, boolean enforced) {
1959 // TODO: Now that we no longer change GID for storage, this should to away.
1960 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1961 "setPermissionEnforced");
1962 if (READ_EXTERNAL_STORAGE.equals(permName)) {
1963 mPackageManagerInt.setReadExternalStorageEnforced(enforced);
1964 // kill any non-foreground processes so we restart them and
1965 // grant/revoke the GID.
1966 final IActivityManager am = ActivityManager.getService();
1967 if (am != null) {
1968 final long token = Binder.clearCallingIdentity();
1969 try {
1970 am.killProcessesBelowForeground("setPermissionEnforcement");
1971 } catch (RemoteException e) {
1972 } finally {
1973 Binder.restoreCallingIdentity(token);
1974 }
1975 }
1976 } else {
1977 throw new IllegalArgumentException("No selective enforcement for " + permName);
1978 }
1979 }
1980
1981 /** @deprecated */
1982 @Override
1983 @Deprecated
1984 public boolean isPermissionEnforced(String permName) {
1985 // allow instant applications
1986 return true;
1987 }
1988
Evan Severson50a77742020-01-06 10:38:19 -08001989 /**
1990 * This change makes it so that apps are told to show rationale for asking for background
1991 * location access every time they request.
1992 */
1993 @ChangeId
1994 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
1995 private static final long BACKGROUND_RATIONALE_CHANGE_ID = 147316723L;
1996
Todd Kennedyc5b0e862019-07-16 09:47:58 -07001997 @Override
1998 public boolean shouldShowRequestPermissionRationale(String permName,
1999 String packageName, int userId) {
2000 final int callingUid = Binder.getCallingUid();
2001 if (UserHandle.getCallingUserId() != userId) {
2002 mContext.enforceCallingPermission(
2003 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2004 "canShowRequestPermissionRationale for user " + userId);
2005 }
2006
2007 final int uid =
2008 mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
2009 if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) {
2010 return false;
2011 }
2012
2013 if (checkPermission(permName, packageName, userId)
2014 == PackageManager.PERMISSION_GRANTED) {
2015 return false;
2016 }
2017
2018 final int flags;
2019
2020 final long identity = Binder.clearCallingIdentity();
2021 try {
2022 flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
2023 } finally {
2024 Binder.restoreCallingIdentity(identity);
2025 }
2026
2027 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2028 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
2029 | PackageManager.FLAG_PERMISSION_USER_FIXED;
2030
2031 if ((flags & fixedFlags) != 0) {
2032 return false;
2033 }
2034
atrost24274272020-02-17 19:26:41 +00002035 final long token = Binder.clearCallingIdentity();
Evan Severson50a77742020-01-06 10:38:19 -08002036 try {
2037 if (permName.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
2038 && mPlatformCompat.isChangeEnabledByPackageName(BACKGROUND_RATIONALE_CHANGE_ID,
2039 packageName, userId)) {
2040 return true;
2041 }
2042 } catch (RemoteException e) {
2043 Log.e(TAG, "Unable to check if compatibility change is enabled.", e);
atrost24274272020-02-17 19:26:41 +00002044 } finally {
2045 Binder.restoreCallingIdentity(token);
Evan Severson50a77742020-01-06 10:38:19 -08002046 }
2047
Todd Kennedyc5b0e862019-07-16 09:47:58 -07002048 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
2049 }
2050
2051 @Override
2052 public boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId) {
2053 if (UserHandle.getCallingUserId() != userId) {
2054 mContext.enforceCallingPermission(
2055 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2056 "isPermissionRevokedByPolicy for user " + userId);
2057 }
2058
2059 if (checkPermission(permName, packageName, userId) == PackageManager.PERMISSION_GRANTED) {
2060 return false;
2061 }
2062
2063 final int callingUid = Binder.getCallingUid();
2064 if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) {
2065 return false;
2066 }
2067
2068 final long identity = Binder.clearCallingIdentity();
2069 try {
2070 final int flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
2071 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
2072 } finally {
2073 Binder.restoreCallingIdentity(identity);
2074 }
2075 }
2076
Hongwei Wangf391b552018-04-06 13:52:46 -07002077 /**
Philip P. Moltmann48456672019-01-20 13:14:03 -08002078 * Get the state of the runtime permissions as xml file.
2079 *
2080 * <p>Can not be called on main thread.
2081 *
2082 * @param user The user the data should be extracted for
2083 *
2084 * @return The state as a xml file
2085 */
2086 private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
2087 CompletableFuture<byte[]> backup = new CompletableFuture<>();
2088 mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
2089 backup::complete);
2090
2091 try {
2092 return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
2093 } catch (InterruptedException | ExecutionException | TimeoutException e) {
2094 Slog.e(TAG, "Cannot create permission backup for " + user, e);
2095 return null;
2096 }
2097 }
2098
2099 /**
2100 * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
2101 *
2102 * <p>If not all state can be restored, the un-appliable state will be delayed and can be
2103 * applied via {@link #restoreDelayedRuntimePermissions}.
2104 *
2105 * @param backup The state as an xml file
2106 * @param user The user the data should be restored for
2107 */
2108 private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
2109 synchronized (mLock) {
2110 mHasNoDelayedPermBackup.delete(user.getIdentifier());
Philip P. Moltmann4a6c5de2019-09-13 11:15:44 -07002111 mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup, user);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002112 }
2113 }
2114
2115 /**
2116 * Try to apply permission backup that was previously not applied.
2117 *
2118 * <p>Can not be called on main thread.
2119 *
2120 * @param packageName The package that is newly installed
2121 * @param user The user the package is installed for
2122 *
2123 * @see #restoreRuntimePermissions
2124 */
2125 private void restoreDelayedRuntimePermissions(@NonNull String packageName,
2126 @NonNull UserHandle user) {
2127 synchronized (mLock) {
2128 if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
2129 return;
2130 }
2131
Philip P. Moltmann4a6c5de2019-09-13 11:15:44 -07002132 mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName, user,
Philip P. Moltmann48456672019-01-20 13:14:03 -08002133 mContext.getMainExecutor(), (hasMoreBackup) -> {
2134 if (hasMoreBackup) {
2135 return;
2136 }
2137
2138 synchronized (mLock) {
2139 mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
2140 }
2141 });
2142 }
2143 }
2144
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002145 private void addOnRuntimePermissionStateChangedListener(@NonNull
2146 OnRuntimePermissionStateChangedListener listener) {
2147 synchronized (mLock) {
2148 mRuntimePermissionStateChangedListeners.add(listener);
2149 }
2150 }
2151
2152 private void removeOnRuntimePermissionStateChangedListener(@NonNull
2153 OnRuntimePermissionStateChangedListener listener) {
2154 synchronized (mLock) {
2155 mRuntimePermissionStateChangedListeners.remove(listener);
2156 }
2157 }
2158
2159 private void notifyRuntimePermissionStateChanged(@NonNull String packageName,
2160 @UserIdInt int userId) {
2161 FgThread.getHandler().sendMessage(PooledLambda.obtainMessage
2162 (PermissionManagerService::doNotifyRuntimePermissionStateChanged,
2163 PermissionManagerService.this, packageName, userId));
2164 }
2165
2166 private void doNotifyRuntimePermissionStateChanged(@NonNull String packageName,
2167 @UserIdInt int userId) {
2168 final ArrayList<OnRuntimePermissionStateChangedListener> listeners;
2169 synchronized (mLock) {
2170 if (mRuntimePermissionStateChangedListeners.isEmpty()) {
2171 return;
2172 }
2173 listeners = new ArrayList<>(mRuntimePermissionStateChangedListeners);
2174 }
2175 final int listenerCount = listeners.size();
2176 for (int i = 0; i < listenerCount; i++) {
2177 listeners.get(i).onRuntimePermissionStateChanged(packageName, userId);
2178 }
2179 }
2180
Todd Kennedy0eb97382017-10-03 16:57:22 -07002181 private int adjustPermissionProtectionFlagsLocked(
2182 int protectionLevel, String packageName, int uid) {
2183 // Signature permission flags area always reported
2184 final int protectionLevelMasked = protectionLevel
2185 & (PermissionInfo.PROTECTION_NORMAL
2186 | PermissionInfo.PROTECTION_DANGEROUS
2187 | PermissionInfo.PROTECTION_SIGNATURE);
2188 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
2189 return protectionLevel;
2190 }
2191 // System sees all flags.
2192 final int appId = UserHandle.getAppId(uid);
2193 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
2194 || appId == Process.SHELL_UID) {
2195 return protectionLevel;
2196 }
2197 // Normalize package name to handle renamed packages and static libs
Winson14ff7172019-10-23 10:42:27 -07002198 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002199 if (pkg == null) {
2200 return protectionLevel;
2201 }
Winson14ff7172019-10-23 10:42:27 -07002202 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002203 return protectionLevelMasked;
2204 }
2205 // Apps that target O see flags for all protection levels.
Winson14ff7172019-10-23 10:42:27 -07002206 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
2207 pkg.getPackageName());
Todd Kennedy0eb97382017-10-03 16:57:22 -07002208 if (ps == null) {
2209 return protectionLevel;
2210 }
2211 if (ps.getAppId() != appId) {
2212 return protectionLevel;
2213 }
2214 return protectionLevel;
2215 }
2216
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002217 /**
2218 * We might auto-grant permissions if any permission of the group is already granted. Hence if
2219 * the group of a granted permission changes we need to revoke it to avoid having permissions of
2220 * the new group auto-granted.
2221 *
2222 * @param newPackage The new package that was installed
2223 * @param oldPackage The old package that was updated
2224 * @param allPackageNames All package names
2225 * @param permissionCallback Callback for permission changed
2226 */
2227 private void revokeRuntimePermissionsIfGroupChanged(
Winson14ff7172019-10-23 10:42:27 -07002228 @NonNull AndroidPackage newPackage,
2229 @NonNull AndroidPackage oldPackage,
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002230 @NonNull ArrayList<String> allPackageNames,
2231 @NonNull PermissionCallback permissionCallback) {
Winson14ff7172019-10-23 10:42:27 -07002232 final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002233 final ArrayMap<String, String> oldPermissionNameToGroupName
2234 = new ArrayMap<>(numOldPackagePermissions);
2235
2236 for (int i = 0; i < numOldPackagePermissions; i++) {
Winson14ff7172019-10-23 10:42:27 -07002237 final ParsedPermission permission = oldPackage.getPermissions().get(i);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002238
Winsonf00c7552020-01-28 12:52:01 -08002239 if (permission.getParsedPermissionGroup() != null) {
Winson14ff7172019-10-23 10:42:27 -07002240 oldPermissionNameToGroupName.put(permission.getName(),
Winsonf00c7552020-01-28 12:52:01 -08002241 permission.getParsedPermissionGroup().getName());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002242 }
2243 }
2244
Todd Kennedyc971a452019-07-08 16:04:52 -07002245 final int callingUid = Binder.getCallingUid();
Winson14ff7172019-10-23 10:42:27 -07002246 final int numNewPackagePermissions = ArrayUtils.size(newPackage.getPermissions());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002247 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
2248 newPermissionNum++) {
Winson14ff7172019-10-23 10:42:27 -07002249 final ParsedPermission newPermission =
2250 newPackage.getPermissions().get(newPermissionNum);
2251 final int newProtection = newPermission.getProtection();
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002252
2253 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
Winson14ff7172019-10-23 10:42:27 -07002254 final String permissionName = newPermission.getName();
Winsonf00c7552020-01-28 12:52:01 -08002255 final String newPermissionGroupName =
2256 newPermission.getParsedPermissionGroup() == null
2257 ? null : newPermission.getParsedPermissionGroup().getName();
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002258 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
2259 permissionName);
2260
2261 if (newPermissionGroupName != null
2262 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
2263 final int[] userIds = mUserManagerInt.getUserIds();
2264 final int numUserIds = userIds.length;
2265 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
2266 final int userId = userIds[userIdNum];
2267
2268 final int numPackages = allPackageNames.size();
2269 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
2270 final String packageName = allPackageNames.get(packageNum);
Hai Zhang3b049a52019-08-16 15:37:46 -07002271 final int permissionState = checkPermission(permissionName, packageName,
2272 userId);
Todd Kennedyca1ea172019-07-03 15:02:28 -07002273 if (permissionState == PackageManager.PERMISSION_GRANTED) {
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002274 EventLog.writeEvent(0x534e4554, "72710897",
Winson14ff7172019-10-23 10:42:27 -07002275 newPackage.getUid(),
Koji Fukuiacae3ef2018-05-09 11:38:01 +09002276 "Revoking permission " + permissionName +
2277 " from package " + packageName +
2278 " as the group changed from " + oldPermissionGroupName +
2279 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002280
2281 try {
Todd Kennedyc971a452019-07-08 16:04:52 -07002282 revokeRuntimePermissionInternal(permissionName, packageName,
2283 false, callingUid, userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002284 } catch (IllegalArgumentException e) {
2285 Slog.e(TAG, "Could not revoke " + permissionName + " from "
2286 + packageName, e);
2287 }
2288 }
2289 }
2290 }
2291 }
2292 }
2293 }
2294 }
2295
Winson14ff7172019-10-23 10:42:27 -07002296 private void addAllPermissions(AndroidPackage pkg, boolean chatty) {
2297 final int N = ArrayUtils.size(pkg.getPermissions());
Todd Kennedyc8423932017-10-05 08:58:36 -07002298 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002299 ParsedPermission p = pkg.getPermissions().get(i);
Todd Kennedyc8423932017-10-05 08:58:36 -07002300
2301 // Assume by default that we did not install this permission into the system.
Winsonf00c7552020-01-28 12:52:01 -08002302 p.setFlags(p.getFlags() & ~PermissionInfo.FLAG_INSTALLED);
Todd Kennedyc8423932017-10-05 08:58:36 -07002303
Todd Kennedyc8423932017-10-05 08:58:36 -07002304 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002305 // Now that permission groups have a special meaning, we ignore permission
2306 // groups for legacy apps to prevent unexpected behavior. In particular,
2307 // permissions for one app being granted to someone just because they happen
2308 // to be in a group defined by another app (before this had no implications).
Winson14ff7172019-10-23 10:42:27 -07002309 if (pkg.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) {
Winsonf00c7552020-01-28 12:52:01 -08002310 p.setParsedPermissionGroup(mSettings.mPermissionGroups.get(p.getGroup()));
Todd Kennedy460f28c2017-10-06 13:46:22 -07002311 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002312 if (DEBUG_PERMISSIONS
Winsonf00c7552020-01-28 12:52:01 -08002313 && p.getGroup() != null && p.getParsedPermissionGroup() == null) {
Winson14ff7172019-10-23 10:42:27 -07002314 Slog.i(TAG, "Permission " + p.getName() + " from package "
2315 + p.getPackageName() + " in an unknown group " + p.getGroup());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002316 }
2317 }
2318
Winsonf00c7552020-01-28 12:52:01 -08002319 if (p.isTree()) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002320 final BasePermission bp = BasePermission.createOrUpdate(
Winson14ff7172019-10-23 10:42:27 -07002321 mPackageManagerInt,
2322 mSettings.getPermissionTreeLocked(p.getName()), p, pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002323 mSettings.getAllPermissionTreesLocked(), chatty);
Winson14ff7172019-10-23 10:42:27 -07002324 mSettings.putPermissionTreeLocked(p.getName(), bp);
Todd Kennedyc8423932017-10-05 08:58:36 -07002325 } else {
2326 final BasePermission bp = BasePermission.createOrUpdate(
Winson14ff7172019-10-23 10:42:27 -07002327 mPackageManagerInt,
2328 mSettings.getPermissionLocked(p.getName()),
Todd Kennedyc8423932017-10-05 08:58:36 -07002329 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
Winson14ff7172019-10-23 10:42:27 -07002330 mSettings.putPermissionLocked(p.getName(), bp);
Todd Kennedyc8423932017-10-05 08:58:36 -07002331 }
2332 }
2333 }
2334 }
2335
Winson14ff7172019-10-23 10:42:27 -07002336 private void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
2337 final int N = ArrayUtils.size(pkg.getPermissionGroups());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002338 StringBuilder r = null;
2339 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002340 final ParsedPermissionGroup pg = pkg.getPermissionGroups().get(i);
2341 final ParsedPermissionGroup cur = mSettings.mPermissionGroups.get(pg.getName());
2342 final String curPackageName = (cur == null) ? null : cur.getPackageName();
2343 final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName);
Todd Kennedy460f28c2017-10-06 13:46:22 -07002344 if (cur == null || isPackageUpdate) {
Winson14ff7172019-10-23 10:42:27 -07002345 mSettings.mPermissionGroups.put(pg.getName(), pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002346 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002347 if (r == null) {
2348 r = new StringBuilder(256);
2349 } else {
2350 r.append(' ');
2351 }
2352 if (isPackageUpdate) {
2353 r.append("UPD:");
2354 }
Winson14ff7172019-10-23 10:42:27 -07002355 r.append(pg.getName());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002356 }
2357 } else {
Winson14ff7172019-10-23 10:42:27 -07002358 Slog.w(TAG, "Permission group " + pg.getName() + " from package "
2359 + pg.getPackageName() + " ignored: original from "
2360 + cur.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002361 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002362 if (r == null) {
2363 r = new StringBuilder(256);
2364 } else {
2365 r.append(' ');
2366 }
2367 r.append("DUP:");
Winson14ff7172019-10-23 10:42:27 -07002368 r.append(pg.getName());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002369 }
2370 }
2371 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002372 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002373 Log.d(TAG, " Permission Groups: " + r);
2374 }
2375
2376 }
2377
Winson14ff7172019-10-23 10:42:27 -07002378 private void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002379 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07002380 int N = ArrayUtils.size(pkg.getPermissions());
Todd Kennedyc8423932017-10-05 08:58:36 -07002381 StringBuilder r = null;
2382 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002383 ParsedPermission p = pkg.getPermissions().get(i);
2384 BasePermission bp = mSettings.mPermissions.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002385 if (bp == null) {
Winson14ff7172019-10-23 10:42:27 -07002386 bp = mSettings.mPermissionTrees.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002387 }
2388 if (bp != null && bp.isPermission(p)) {
2389 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002390 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002391 if (r == null) {
2392 r = new StringBuilder(256);
2393 } else {
2394 r.append(' ');
2395 }
Winson14ff7172019-10-23 10:42:27 -07002396 r.append(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002397 }
2398 }
2399 if (p.isAppOp()) {
2400 ArraySet<String> appOpPkgs =
Winson14ff7172019-10-23 10:42:27 -07002401 mSettings.mAppOpPermissionPackages.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002402 if (appOpPkgs != null) {
Winson14ff7172019-10-23 10:42:27 -07002403 appOpPkgs.remove(pkg.getPackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002404 }
2405 }
2406 }
2407 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002408 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -07002409 }
2410
Winson14ff7172019-10-23 10:42:27 -07002411 N = pkg.getRequestedPermissions().size();
Todd Kennedyc8423932017-10-05 08:58:36 -07002412 r = null;
2413 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002414 String perm = pkg.getRequestedPermissions().get(i);
Todd Kennedyc8423932017-10-05 08:58:36 -07002415 if (mSettings.isPermissionAppOp(perm)) {
2416 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
2417 if (appOpPkgs != null) {
Winson14ff7172019-10-23 10:42:27 -07002418 appOpPkgs.remove(pkg.getPackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002419 if (appOpPkgs.isEmpty()) {
2420 mSettings.mAppOpPermissionPackages.remove(perm);
2421 }
2422 }
2423 }
2424 }
2425 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002426 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -07002427 }
2428 }
2429 }
2430
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002431 /**
2432 * Restore the permission state for a package.
2433 *
2434 * <ul>
2435 * <li>During boot the state gets restored from the disk</li>
2436 * <li>During app update the state gets restored from the last version of the app</li>
2437 * </ul>
2438 *
2439 * <p>This restores the permission state for all users.
2440 *
2441 * @param pkg the package the permissions belong to
2442 * @param replace if the package is getting replaced (this might change the requested
2443 * permissions of this package)
2444 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
2445 * @param callback Result call back
2446 */
Winson14ff7172019-10-23 10:42:27 -07002447 private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace,
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002448 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002449 // IMPORTANT: There are two types of permissions: install and runtime.
2450 // Install time permissions are granted when the app is installed to
2451 // all device users and users added in the future. Runtime permissions
2452 // are granted at runtime explicitly to specific users. Normal and signature
2453 // protected permissions are install time permissions. Dangerous permissions
2454 // are install permissions if the app's target SDK is Lollipop MR1 or older,
2455 // otherwise they are runtime permissions. This function does not manage
2456 // runtime permissions except for the case an app targeting Lollipop MR1
2457 // being upgraded to target a newer SDK, in which case dangerous permissions
2458 // are transformed from install time to runtime ones.
2459
Winson14ff7172019-10-23 10:42:27 -07002460 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
2461 pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002462 if (ps == null) {
2463 return;
2464 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002465
2466 final PermissionsState permissionsState = ps.getPermissionsState();
2467 PermissionsState origPermissions = permissionsState;
2468
2469 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2470
2471 boolean runtimePermissionsRevoked = false;
2472 int[] updatedUserIds = EMPTY_INT_ARRAY;
2473
2474 boolean changedInstallPermission = false;
2475
2476 if (replace) {
2477 ps.setInstallPermissionsFixed(false);
2478 if (!ps.isSharedUser()) {
2479 origPermissions = new PermissionsState(permissionsState);
2480 permissionsState.reset();
2481 } else {
2482 // We need to know only about runtime permission changes since the
2483 // calling code always writes the install permissions state but
2484 // the runtime ones are written only if changed. The only cases of
2485 // changed runtime permissions here are promotion of an install to
2486 // runtime and revocation of a runtime from a shared user.
2487 synchronized (mLock) {
2488 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
2489 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
2490 if (!ArrayUtils.isEmpty(updatedUserIds)) {
2491 runtimePermissionsRevoked = true;
2492 }
2493 }
2494 }
2495 }
2496
2497 permissionsState.setGlobalGids(mGlobalGids);
2498
2499 synchronized (mLock) {
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002500 ArraySet<String> newImplicitPermissions = new ArraySet<>();
2501
Nate Myrenc6900622020-03-31 11:54:31 -07002502 // TODO ntmyren: Remove once propagated to droidfood
2503 int flagMask = PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED
2504 | PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED;
2505 int user = UserHandle.getUserId(pkg.getUid());
2506
Winson14ff7172019-10-23 10:42:27 -07002507 final int N = pkg.getRequestedPermissions().size();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002508 for (int i = 0; i < N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002509 final String permName = pkg.getRequestedPermissions().get(i);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002510 final BasePermission bp = mSettings.getPermissionLocked(permName);
Nate Myrenc6900622020-03-31 11:54:31 -07002511
2512 // TODO ntmyren: Remove once propagated to droidfood
2513 if (bp != null && !bp.isRuntime()) {
2514 PermissionState permState = permissionsState.getInstallPermissionState(bp.name);
2515 if (permState == null || (permState.getFlags() & flagMask) != 0) {
2516 permissionsState.updatePermissionFlags(bp, user, flagMask, 0);
2517 }
2518 }
2519
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002520 final boolean appSupportsRuntimePermissions =
Winson14ff7172019-10-23 10:42:27 -07002521 pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;
Zimuzoe6411402019-05-13 16:32:57 +01002522 String upgradedActivityRecognitionPermission = null;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002523
Songchun Fanbcc899e2020-04-06 16:51:45 -07002524 if (DEBUG_INSTALL && bp != null) {
Winson14ff7172019-10-23 10:42:27 -07002525 Log.i(TAG, "Package " + pkg.getPackageName()
2526 + " checking " + permName + ": " + bp);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002527 }
2528
2529 if (bp == null || bp.getSourcePackageSetting() == null) {
Winson14ff7172019-10-23 10:42:27 -07002530 if (packageOfInterest == null || packageOfInterest.equals(
2531 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002532 if (DEBUG_PERMISSIONS) {
2533 Slog.i(TAG, "Unknown permission " + permName
Winson14ff7172019-10-23 10:42:27 -07002534 + " in package " + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002535 }
2536 }
2537 continue;
2538 }
2539
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002540 // Cache newImplicitPermissions before modifing permissionsState as for the shared
2541 // uids the original and new state are the same object
2542 if (!origPermissions.hasRequestedPermission(permName)
Winson14ff7172019-10-23 10:42:27 -07002543 && (pkg.getImplicitPermissions().contains(permName)
Zimuzoe6411402019-05-13 16:32:57 +01002544 || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
Winson14ff7172019-10-23 10:42:27 -07002545 if (pkg.getImplicitPermissions().contains(permName)) {
Zimuzoe6411402019-05-13 16:32:57 +01002546 // If permName is an implicit permission, try to auto-grant
2547 newImplicitPermissions.add(permName);
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002548
Zimuzoe6411402019-05-13 16:32:57 +01002549 if (DEBUG_PERMISSIONS) {
Winson14ff7172019-10-23 10:42:27 -07002550 Slog.i(TAG, permName + " is newly added for " + pkg.getPackageName());
Zimuzoe6411402019-05-13 16:32:57 +01002551 }
2552 } else {
2553 // Special case for Activity Recognition permission. Even if AR permission
2554 // is not an implicit permission we want to add it to the list (try to
2555 // auto-grant it) if the app was installed on a device before AR permission
2556 // was split, regardless of if the app now requests the new AR permission
2557 // or has updated its target SDK and AR is no longer implicit to it.
2558 // This is a compatibility workaround for apps when AR permission was
2559 // split in Q.
Anthony Hughde787d42019-08-22 15:35:48 -07002560 final List<SplitPermissionInfoParcelable> permissionList =
2561 getSplitPermissions();
2562 int numSplitPerms = permissionList.size();
Zimuzoe6411402019-05-13 16:32:57 +01002563 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
Anthony Hughde787d42019-08-22 15:35:48 -07002564 SplitPermissionInfoParcelable sp = permissionList.get(splitPermNum);
Zimuzoe6411402019-05-13 16:32:57 +01002565 String splitPermName = sp.getSplitPermission();
2566 if (sp.getNewPermissions().contains(permName)
2567 && origPermissions.hasInstallPermission(splitPermName)) {
2568 upgradedActivityRecognitionPermission = splitPermName;
2569 newImplicitPermissions.add(permName);
2570
2571 if (DEBUG_PERMISSIONS) {
2572 Slog.i(TAG, permName + " is newly added for "
Winson14ff7172019-10-23 10:42:27 -07002573 + pkg.getPackageName());
Zimuzoe6411402019-05-13 16:32:57 +01002574 }
2575 break;
2576 }
2577 }
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002578 }
2579 }
2580
Winson5e0a1d52020-01-24 12:00:33 -08002581 // TODO(b/140256621): The package instant app method has been removed
2582 // as part of work in b/135203078, so this has been commented out in the meantime
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002583 // Limit ephemeral apps to ephemeral allowed permissions.
Winson5e0a1d52020-01-24 12:00:33 -08002584// if (/*pkg.isInstantApp()*/ false && !bp.isInstant()) {
2585// if (DEBUG_PERMISSIONS) {
2586// Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
2587// + " for package " + pkg.getPackageName());
2588// }
2589// continue;
2590// }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002591
2592 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
2593 if (DEBUG_PERMISSIONS) {
2594 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
Winson14ff7172019-10-23 10:42:27 -07002595 + " for package " + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002596 }
2597 continue;
2598 }
2599
2600 final String perm = bp.getName();
2601 boolean allowedSig = false;
2602 int grant = GRANT_DENIED;
2603
2604 // Keep track of app op permissions.
2605 if (bp.isAppOp()) {
Winson14ff7172019-10-23 10:42:27 -07002606 mSettings.addAppOpPackage(perm, pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002607 }
2608
2609 if (bp.isNormal()) {
2610 // For all apps normal permissions are install time ones.
2611 grant = GRANT_INSTALL;
2612 } else if (bp.isRuntime()) {
Zimuzoe6411402019-05-13 16:32:57 +01002613 if (origPermissions.hasInstallPermission(bp.getName())
2614 || upgradedActivityRecognitionPermission != null) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002615 // Before Q we represented some runtime permissions as install permissions,
2616 // in Q we cannot do this anymore. Hence upgrade them all.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002617 grant = GRANT_UPGRADE;
2618 } else {
2619 // For modern apps keep runtime permissions unchanged.
2620 grant = GRANT_RUNTIME;
2621 }
2622 } else if (bp.isSignature()) {
2623 // For all apps signature permissions are install time ones.
Winsone0756292020-01-31 12:21:54 -08002624 allowedSig = grantSignaturePermission(perm, pkg, ps, bp, origPermissions);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002625 if (allowedSig) {
2626 grant = GRANT_INSTALL;
2627 }
2628 }
2629
2630 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002631 Slog.i(TAG, "Considering granting permission " + perm + " to package "
Winson14ff7172019-10-23 10:42:27 -07002632 + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002633 }
2634
2635 if (grant != GRANT_DENIED) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002636 if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002637 // If this is an existing, non-system package, then
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002638 // we can't add any new permissions to it. Runtime
2639 // permissions can be added any time - they ad dynamic.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002640 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
2641 // Except... if this is a permission that was added
2642 // to the platform (note: need to only do this when
2643 // updating the platform).
2644 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
2645 grant = GRANT_DENIED;
2646 }
2647 }
2648 }
2649
2650 switch (grant) {
2651 case GRANT_INSTALL: {
2652 // Revoke this as runtime permission to handle the case of
2653 // a runtime permission being downgraded to an install one.
2654 // Also in permission review mode we keep dangerous permissions
2655 // for legacy apps
2656 for (int userId : UserManagerService.getInstance().getUserIds()) {
2657 if (origPermissions.getRuntimePermissionState(
2658 perm, userId) != null) {
2659 // Revoke the runtime permission and clear the flags.
2660 origPermissions.revokeRuntimePermission(bp, userId);
2661 origPermissions.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002662 PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002663 // If we revoked a permission permission, we have to write.
2664 updatedUserIds = ArrayUtils.appendInt(
2665 updatedUserIds, userId);
2666 }
2667 }
2668 // Grant an install permission.
2669 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002670 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002671 changedInstallPermission = true;
2672 }
2673 } break;
2674
2675 case GRANT_RUNTIME: {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002676 boolean hardRestricted = bp.isHardRestricted();
2677 boolean softRestricted = bp.isSoftRestricted();
2678
Philip P. Moltmann48456672019-01-20 13:14:03 -08002679 for (int userId : currentUserIds) {
Svet Ganov3c499ea2019-07-26 17:45:56 -07002680 // If permission policy is not ready we don't deal with restricted
2681 // permissions as the policy may whitelist some permissions. Once
2682 // the policy is initialized we would re-evaluate permissions.
2683 final boolean permissionPolicyInitialized =
2684 mPermissionPolicyInternal != null
2685 && mPermissionPolicyInternal.isInitialized(userId);
2686
Philip P. Moltmann48456672019-01-20 13:14:03 -08002687 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002688 .getRuntimePermissionState(perm, userId);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002689 int flags = permState != null ? permState.getFlags() : 0;
2690
2691 boolean wasChanged = false;
2692
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002693 boolean restrictionExempt =
2694 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002695 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2696 boolean restrictionApplied = (origPermissions.getPermissionFlags(
2697 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2698
Philip P. Moltmann48456672019-01-20 13:14:03 -08002699 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002700 // If hard restricted we don't allow holding it
Svet Ganov3c499ea2019-07-26 17:45:56 -07002701 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002702 if (!restrictionExempt) {
2703 if (permState != null && permState.isGranted()
2704 && permissionsState.revokeRuntimePermission(
2705 bp, userId) != PERMISSION_OPERATION_FAILURE) {
2706 wasChanged = true;
2707 }
2708 if (!restrictionApplied) {
2709 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2710 wasChanged = true;
2711 }
2712 }
2713 // If soft restricted we allow holding in a restricted form
Svet Ganov3c499ea2019-07-26 17:45:56 -07002714 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002715 // Regardless if granted set the restriction flag as it
2716 // may affect app treatment based on this permission.
2717 if (!restrictionExempt && !restrictionApplied) {
2718 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2719 wasChanged = true;
2720 }
2721 }
2722
Philip P. Moltmann48456672019-01-20 13:14:03 -08002723 // Remove review flag as it is not necessary anymore
2724 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2725 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2726 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002727 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002728
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002729 if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
2730 flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002731 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002732 // Hard restricted permissions cannot be held.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002733 } else if (!permissionPolicyInitialized
2734 || (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002735 if (permState != null && permState.isGranted()) {
2736 if (permissionsState.grantRuntimePermission(bp, userId)
2737 == PERMISSION_OPERATION_FAILURE) {
2738 wasChanged = true;
2739 }
2740 }
2741 }
2742 } else {
2743 if (permState == null) {
2744 // New permission
2745 if (PLATFORM_PACKAGE_NAME.equals(
2746 bp.getSourcePackageName())) {
2747 if (!bp.isRemoved()) {
2748 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002749 | FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002750 wasChanged = true;
2751 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002752 }
2753 }
2754
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002755 if (!permissionsState.hasRuntimePermission(bp.name, userId)
2756 && permissionsState.grantRuntimePermission(bp, userId)
2757 != PERMISSION_OPERATION_FAILURE) {
2758 wasChanged = true;
2759 }
2760
2761 // If legacy app always grant the permission but if restricted
2762 // and not exempt take a note a restriction should be applied.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002763 if (permissionPolicyInitialized
2764 && (hardRestricted || softRestricted)
2765 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002766 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2767 wasChanged = true;
2768 }
2769 }
2770
2771 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002772 if (permissionPolicyInitialized) {
2773 if (!(hardRestricted || softRestricted) || restrictionExempt) {
2774 if (restrictionApplied) {
2775 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2776 // Dropping restriction on a legacy app implies a review
2777 if (!appSupportsRuntimePermissions) {
2778 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2779 }
2780 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002781 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002782 }
2783 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002784
2785 if (wasChanged) {
2786 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2787 }
2788
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08002789 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002790 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002791 }
2792 } break;
2793
2794 case GRANT_UPGRADE: {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002795 // Upgrade from Pre-Q to Q permission model. Make all permissions
2796 // runtime
2797 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002798 .getInstallPermissionState(perm);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002799 int flags = (permState != null) ? permState.getFlags() : 0;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002800
Zimuzoe6411402019-05-13 16:32:57 +01002801 BasePermission bpToRevoke =
2802 upgradedActivityRecognitionPermission == null
2803 ? bp : mSettings.getPermissionLocked(
2804 upgradedActivityRecognitionPermission);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002805 // Remove install permission
Zimuzoe6411402019-05-13 16:32:57 +01002806 if (origPermissions.revokeInstallPermission(bpToRevoke)
Philip P. Moltmann48456672019-01-20 13:14:03 -08002807 != PERMISSION_OPERATION_FAILURE) {
Zimuzoe6411402019-05-13 16:32:57 +01002808 origPermissions.updatePermissionFlags(bpToRevoke,
2809 UserHandle.USER_ALL,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002810 (MASK_PERMISSION_FLAGS_ALL
2811 & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002812 changedInstallPermission = true;
2813 }
2814
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002815 boolean hardRestricted = bp.isHardRestricted();
2816 boolean softRestricted = bp.isSoftRestricted();
2817
Philip P. Moltmann48456672019-01-20 13:14:03 -08002818 for (int userId : currentUserIds) {
Svet Ganov3c499ea2019-07-26 17:45:56 -07002819 // If permission policy is not ready we don't deal with restricted
2820 // permissions as the policy may whitelist some permissions. Once
2821 // the policy is initialized we would re-evaluate permissions.
2822 final boolean permissionPolicyInitialized =
2823 mPermissionPolicyInternal != null
2824 && mPermissionPolicyInternal.isInitialized(userId);
2825
Philip P. Moltmann48456672019-01-20 13:14:03 -08002826 boolean wasChanged = false;
2827
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002828 boolean restrictionExempt =
2829 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002830 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2831 boolean restrictionApplied = (origPermissions.getPermissionFlags(
2832 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2833
Philip P. Moltmann48456672019-01-20 13:14:03 -08002834 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002835 // If hard restricted we don't allow holding it
Svet Ganov3c499ea2019-07-26 17:45:56 -07002836 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002837 if (!restrictionExempt) {
2838 if (permState != null && permState.isGranted()
2839 && permissionsState.revokeRuntimePermission(
2840 bp, userId) != PERMISSION_OPERATION_FAILURE) {
2841 wasChanged = true;
2842 }
2843 if (!restrictionApplied) {
2844 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2845 wasChanged = true;
2846 }
2847 }
2848 // If soft restricted we allow holding in a restricted form
Svet Ganov3c499ea2019-07-26 17:45:56 -07002849 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002850 // Regardless if granted set the restriction flag as it
2851 // may affect app treatment based on this permission.
2852 if (!restrictionExempt && !restrictionApplied) {
2853 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2854 wasChanged = true;
2855 }
2856 }
2857
Philip P. Moltmann48456672019-01-20 13:14:03 -08002858 // Remove review flag as it is not necessary anymore
2859 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2860 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2861 wasChanged = true;
2862 }
2863
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002864 if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
2865 flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002866 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002867 // Hard restricted permissions cannot be held.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002868 } else if (!permissionPolicyInitialized ||
2869 (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002870 if (permissionsState.grantRuntimePermission(bp, userId) !=
2871 PERMISSION_OPERATION_FAILURE) {
2872 wasChanged = true;
2873 }
2874 }
2875 } else {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002876 if (!permissionsState.hasRuntimePermission(bp.name, userId)
2877 && permissionsState.grantRuntimePermission(bp,
2878 userId) != PERMISSION_OPERATION_FAILURE) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002879 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2880 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002881 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002882
2883 // If legacy app always grant the permission but if restricted
2884 // and not exempt take a note a restriction should be applied.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002885 if (permissionPolicyInitialized
2886 && (hardRestricted || softRestricted)
2887 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002888 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2889 wasChanged = true;
2890 }
2891 }
2892
2893 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002894 if (permissionPolicyInitialized) {
2895 if (!(hardRestricted || softRestricted) || restrictionExempt) {
2896 if (restrictionApplied) {
2897 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2898 // Dropping restriction on a legacy app implies a review
2899 if (!appSupportsRuntimePermissions) {
2900 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2901 }
2902 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002903 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002904 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002905 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002906
2907 if (wasChanged) {
2908 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2909 }
2910
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08002911 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002912 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002913 }
2914 } break;
2915
2916 default: {
2917 if (packageOfInterest == null
Winson14ff7172019-10-23 10:42:27 -07002918 || packageOfInterest.equals(pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002919 if (DEBUG_PERMISSIONS) {
2920 Slog.i(TAG, "Not granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002921 + " to package " + pkg.getPackageName()
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002922 + " because it was previously installed without");
2923 }
2924 }
2925 } break;
2926 }
2927 } else {
2928 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002929 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002930 // Also drop the permission flags.
2931 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002932 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002933 changedInstallPermission = true;
Nate Myrened67bdd2019-05-07 10:32:22 -07002934 if (DEBUG_PERMISSIONS) {
2935 Slog.i(TAG, "Un-granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002936 + " from package " + pkg.getPackageName()
Nate Myrened67bdd2019-05-07 10:32:22 -07002937 + " (protectionLevel=" + bp.getProtectionLevel()
Winsonf00c7552020-01-28 12:52:01 -08002938 + " flags=0x"
2939 + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, ps))
Nate Myrened67bdd2019-05-07 10:32:22 -07002940 + ")");
2941 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002942 } else if (bp.isAppOp()) {
2943 // Don't print warning for app op permissions, since it is fine for them
2944 // not to be granted, there is a UI for the user to decide.
2945 if (DEBUG_PERMISSIONS
2946 && (packageOfInterest == null
Winson14ff7172019-10-23 10:42:27 -07002947 || packageOfInterest.equals(pkg.getPackageName()))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002948 Slog.i(TAG, "Not granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002949 + " to package " + pkg.getPackageName()
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002950 + " (protectionLevel=" + bp.getProtectionLevel()
Winsonf00c7552020-01-28 12:52:01 -08002951 + " flags=0x"
2952 + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, ps))
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002953 + ")");
2954 }
2955 }
2956 }
2957 }
2958
2959 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
Winson8359e402020-02-21 17:32:14 -08002960 !ps.isSystem() || ps.getPkgState().isUpdatedSystemApp()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002961 // This is the first that we have heard about this package, so the
2962 // permissions we have now selected are fixed until explicitly
2963 // changed.
2964 ps.setInstallPermissionsFixed(true);
2965 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002966
2967 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
2968 updatedUserIds);
2969 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002970 permissionsState, pkg, newImplicitPermissions, updatedUserIds);
Philip P. Moltmann74065c82019-05-15 10:46:32 -07002971 updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002972 }
2973
2974 // Persist the runtime permissions state for users with changes. If permissions
2975 // were revoked because no app in the shared user declares them we have to
2976 // write synchronously to avoid losing runtime permissions state.
2977 if (callback != null) {
2978 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
2979 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002980
2981 for (int userId : updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07002982 notifyRuntimePermissionStateChanged(pkg.getPackageName(), userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002983 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002984 }
2985
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002986 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002987 * Revoke permissions that are not implicit anymore and that have
2988 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
2989 *
2990 * @param ps The state of the permissions of the package
2991 * @param pkg The package that is currently looked at
2992 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
2993 * for a user is changed.
2994 *
2995 * @return The updated value of the {@code updatedUserIds} parameter
2996 */
2997 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
Winson14ff7172019-10-23 10:42:27 -07002998 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002999 @NonNull int[] updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07003000 String pkgName = pkg.getPackageName();
3001 boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
Philip P. Moltmannd030ce22019-02-18 21:05:48 -08003002 >= Build.VERSION_CODES.M;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003003
3004 int[] users = UserManagerService.getInstance().getUserIds();
3005 int numUsers = users.length;
3006 for (int i = 0; i < numUsers; i++) {
3007 int userId = users[i];
3008
3009 for (String permission : ps.getPermissions(userId)) {
Winson14ff7172019-10-23 10:42:27 -07003010 if (!pkg.getImplicitPermissions().contains(permission)) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003011 if (!ps.hasInstallPermission(permission)) {
3012 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
3013
3014 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
3015 BasePermission bp = mSettings.getPermissionLocked(permission);
3016
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08003017 int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003018
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08003019 if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
3020 && supportsRuntimePermissions) {
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08003021 int revokeResult = ps.revokeRuntimePermission(bp, userId);
3022 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
3023 if (DEBUG_PERMISSIONS) {
3024 Slog.i(TAG, "Revoking runtime permission "
3025 + permission + " for " + pkgName
3026 + " as it is now requested");
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003027 }
3028 }
3029
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08003030 flagsToRemove |= USER_PERMISSION_FLAGS;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003031 }
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08003032
3033 ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
3034 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003035 }
3036 }
3037 }
3038 }
3039 }
3040
3041 return updatedUserIds;
3042 }
3043
3044 /**
3045 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
3046 *
3047 * <p>A single new permission can be split off from several source permissions. In this case
3048 * the most leniant state is inherited.
3049 *
3050 * <p>Warning: This does not handle foreground / background permissions
3051 *
3052 * @param sourcePerms The permissions to inherit from
3053 * @param newPerm The permission to inherit to
3054 * @param ps The permission state of the package
3055 * @param pkg The package requesting the permissions
3056 * @param userId The user the permission belongs to
3057 */
3058 private void inheritPermissionStateToNewImplicitPermissionLocked(
3059 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
Winson14ff7172019-10-23 10:42:27 -07003060 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003061 @UserIdInt int userId) {
Winson14ff7172019-10-23 10:42:27 -07003062 String pkgName = pkg.getPackageName();
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003063 boolean isGranted = false;
3064 int flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003065
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003066 int numSourcePerm = sourcePerms.size();
3067 for (int i = 0; i < numSourcePerm; i++) {
3068 String sourcePerm = sourcePerms.valueAt(i);
3069 if ((ps.hasRuntimePermission(sourcePerm, userId))
3070 || ps.hasInstallPermission(sourcePerm)) {
3071 if (!isGranted) {
3072 flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003073 }
3074
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003075 isGranted = true;
3076 flags |= ps.getPermissionFlags(sourcePerm, userId);
3077 } else {
3078 if (!isGranted) {
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08003079 flags |= ps.getPermissionFlags(sourcePerm, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003080 }
3081 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003082 }
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003083
3084 if (isGranted) {
3085 if (DEBUG_PERMISSIONS) {
3086 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
3087 + " for " + pkgName);
3088 }
3089
3090 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
3091 }
3092
3093 // Add permission flags
3094 ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003095 }
3096
3097 /**
Philip P. Moltmann74065c82019-05-15 10:46:32 -07003098 * When the app has requested legacy storage we might need to update
3099 * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
3100 * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
3101 *
3102 * @param pkg The package for which the permissions are updated
3103 * @param replace If the app is being replaced
3104 * @param updatedUserIds The ids of the users that already changed.
3105 *
3106 * @return The ids of the users that are changed
3107 */
3108 private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
Winson14ff7172019-10-23 10:42:27 -07003109 @NonNull AndroidPackage pkg, boolean replace, @NonNull int[] updatedUserIds) {
Winson5e0a1d52020-01-24 12:00:33 -08003110 if (replace && pkg.isRequestLegacyExternalStorage() && (
Winson14ff7172019-10-23 10:42:27 -07003111 pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
3112 || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
Philip P. Moltmann74065c82019-05-15 10:46:32 -07003113 return UserManagerService.getInstance().getUserIds();
3114 }
3115
3116 return updatedUserIds;
3117 }
3118
3119 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003120 * Set the state of a implicit permission that is seen for the first time.
3121 *
3122 * @param origPs The permission state of the package before the split
3123 * @param ps The new permission state
3124 * @param pkg The package the permission belongs to
3125 * @param updatedUserIds List of users for which the permission state has already been changed
3126 *
3127 * @return List of users for which the permission state has been changed
3128 */
3129 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
3130 @NonNull PermissionsState origPs,
Winson14ff7172019-10-23 10:42:27 -07003131 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07003132 @NonNull ArraySet<String> newImplicitPermissions,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003133 @NonNull int[] updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07003134 String pkgName = pkg.getPackageName();
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003135 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
3136
Anthony Hughde787d42019-08-22 15:35:48 -07003137 final List<SplitPermissionInfoParcelable> permissionList = getSplitPermissions();
3138 int numSplitPerms = permissionList.size();
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003139 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
Anthony Hughde787d42019-08-22 15:35:48 -07003140 SplitPermissionInfoParcelable spi = permissionList.get(splitPermNum);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003141
3142 List<String> newPerms = spi.getNewPermissions();
3143 int numNewPerms = newPerms.size();
3144 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
3145 String newPerm = newPerms.get(newPermNum);
3146
3147 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
3148 if (splitPerms == null) {
3149 splitPerms = new ArraySet<>();
3150 newToSplitPerms.put(newPerm, splitPerms);
3151 }
3152
3153 splitPerms.add(spi.getSplitPermission());
3154 }
3155 }
3156
3157 int numNewImplicitPerms = newImplicitPermissions.size();
3158 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
3159 newImplicitPermNum++) {
3160 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
3161 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
3162
3163 if (sourcePerms != null) {
3164 if (!ps.hasInstallPermission(newPerm)) {
3165 BasePermission bp = mSettings.getPermissionLocked(newPerm);
3166
3167 int[] users = UserManagerService.getInstance().getUserIds();
3168 int numUsers = users.length;
3169 for (int userNum = 0; userNum < numUsers; userNum++) {
3170 int userId = users[userNum];
3171
Zimuzoe6411402019-05-13 16:32:57 +01003172 if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
3173 ps.updatePermissionFlags(bp, userId,
3174 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
3175 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
3176 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003177 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
3178
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003179 boolean inheritsFromInstallPerm = false;
3180 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
3181 sourcePermNum++) {
3182 if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
3183 inheritsFromInstallPerm = true;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07003184 break;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07003185 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003186 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003187
3188 if (!origPs.hasRequestedPermission(sourcePerms)
3189 && !inheritsFromInstallPerm) {
3190 // Both permissions are new so nothing to inherit.
3191 if (DEBUG_PERMISSIONS) {
3192 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
3193 + " for " + pkgName + " as split permission is also new");
3194 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003195 } else {
3196 // Inherit from new install or existing runtime permissions
3197 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
3198 newPerm, ps, pkg, userId);
3199 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003200 }
3201 }
3202 }
3203 }
3204
3205 return updatedUserIds;
3206 }
3207
Anthony Hughde787d42019-08-22 15:35:48 -07003208 @Override
3209 public List<SplitPermissionInfoParcelable> getSplitPermissions() {
3210 return PermissionManager.splitPermissionInfoListToParcelableList(
3211 SystemConfig.getInstance().getSplitPermissions());
3212 }
3213
Evan Seversonb252d8b2019-11-20 08:41:33 -08003214 private OneTimePermissionUserManager getOneTimePermissionUserManager(@UserIdInt int userId) {
Evan Severson2cbceb92020-04-14 18:27:10 +00003215 OneTimePermissionUserManager oneTimePermissionUserManager;
Evan Seversonb252d8b2019-11-20 08:41:33 -08003216 synchronized (mLock) {
Evan Severson2cbceb92020-04-14 18:27:10 +00003217 oneTimePermissionUserManager =
Evan Seversonb252d8b2019-11-20 08:41:33 -08003218 mOneTimePermissionUserManagers.get(userId);
Evan Severson2cbceb92020-04-14 18:27:10 +00003219 if (oneTimePermissionUserManager != null) {
3220 return oneTimePermissionUserManager;
Evan Seversonb252d8b2019-11-20 08:41:33 -08003221 }
Evan Severson2cbceb92020-04-14 18:27:10 +00003222 oneTimePermissionUserManager = new OneTimePermissionUserManager(
3223 mContext.createContextAsUser(UserHandle.of(userId), /*flags*/ 0));
3224 mOneTimePermissionUserManagers.put(userId, oneTimePermissionUserManager);
Evan Seversonb252d8b2019-11-20 08:41:33 -08003225 }
Evan Severson2cbceb92020-04-14 18:27:10 +00003226 oneTimePermissionUserManager.registerUninstallListener();
3227 return oneTimePermissionUserManager;
Evan Seversonb252d8b2019-11-20 08:41:33 -08003228 }
3229
3230 @Override
3231 public void startOneTimePermissionSession(String packageName, @UserIdInt int userId,
3232 long timeoutMillis, int importanceToResetTimer, int importanceToKeepSessionAlive) {
Evan Severson43e17e02020-01-03 10:04:38 -08003233 mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
3234 "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
3235 + " to register permissions as one time.");
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00003236 Objects.requireNonNull(packageName);
Evan Seversonb252d8b2019-11-20 08:41:33 -08003237
3238 long token = Binder.clearCallingIdentity();
3239 try {
3240 getOneTimePermissionUserManager(userId).startPackageOneTimeSession(packageName,
3241 timeoutMillis, importanceToResetTimer, importanceToKeepSessionAlive);
3242 } finally {
3243 Binder.restoreCallingIdentity(token);
3244 }
3245 }
3246
3247 @Override
3248 public void stopOneTimePermissionSession(String packageName, @UserIdInt int userId) {
Evan Severson43e17e02020-01-03 10:04:38 -08003249 mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
3250 "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
3251 + " to remove permissions as one time.");
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00003252 Objects.requireNonNull(packageName);
Evan Seversonb252d8b2019-11-20 08:41:33 -08003253
3254 long token = Binder.clearCallingIdentity();
3255 try {
3256 getOneTimePermissionUserManager(userId).stopPackageOneTimeSession(packageName);
3257 } finally {
3258 Binder.restoreCallingIdentity(token);
3259 }
3260 }
3261
Eugene Susladb77bc12020-03-03 12:09:00 -08003262 @Override
3263 public List<String> getAutoRevokeExemptionRequestedPackages(int userId) {
Eugene Susla49b84c32020-03-23 15:19:29 -07003264 return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISCOURAGED, userId);
Eugene Susladb77bc12020-03-03 12:09:00 -08003265 }
3266
3267 @Override
3268 public List<String> getAutoRevokeExemptionGrantedPackages(int userId) {
Eugene Susla49b84c32020-03-23 15:19:29 -07003269 return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISALLOWED, userId);
3270 }
3271
3272 @NonNull
3273 private List<String> getPackagesWithAutoRevokePolicy(int autoRevokePolicy, int userId) {
Eugene Susladb77bc12020-03-03 12:09:00 -08003274 mContext.enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
3275 "Must hold " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
3276
3277 List<String> result = new ArrayList<>();
3278 mPackageManagerInt.forEachInstalledPackage(pkg -> {
Eugene Susla49b84c32020-03-23 15:19:29 -07003279 if (pkg.getAutoRevokePermissions() == autoRevokePolicy) {
Eugene Susladb77bc12020-03-03 12:09:00 -08003280 result.add(pkg.getPackageName());
3281 }
3282 }, userId);
Eugene Susladb77bc12020-03-03 12:09:00 -08003283 return result;
3284 }
3285
Winson14ff7172019-10-23 10:42:27 -07003286 private boolean isNewPlatformPermissionForPackage(String perm, AndroidPackage pkg) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003287 boolean allowed = false;
3288 final int NP = PackageParser.NEW_PERMISSIONS.length;
3289 for (int ip=0; ip<NP; ip++) {
3290 final PackageParser.NewPermissionInfo npi
3291 = PackageParser.NEW_PERMISSIONS[ip];
3292 if (npi.name.equals(perm)
Winson14ff7172019-10-23 10:42:27 -07003293 && pkg.getTargetSdkVersion() < npi.sdkVersion) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003294 allowed = true;
3295 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
Winson14ff7172019-10-23 10:42:27 -07003296 + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003297 break;
3298 }
3299 }
3300 return allowed;
3301 }
3302
3303 /**
3304 * Determines whether a package is whitelisted for a particular privapp permission.
3305 *
3306 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
3307 *
3308 * <p>This handles parent/child apps.
3309 */
Winson14ff7172019-10-23 10:42:27 -07003310 private boolean hasPrivappWhitelistEntry(String perm, AndroidPackage pkg) {
3311 ArraySet<String> wlPermissions;
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003312 if (pkg.isVendor()) {
3313 wlPermissions =
Winson14ff7172019-10-23 10:42:27 -07003314 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003315 } else if (pkg.isProduct()) {
3316 wlPermissions =
Winson14ff7172019-10-23 10:42:27 -07003317 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.getPackageName());
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003318 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01003319 wlPermissions =
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003320 SystemConfig.getInstance().getSystemExtPrivAppPermissions(
Winson14ff7172019-10-23 10:42:27 -07003321 pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003322 } else {
Winson14ff7172019-10-23 10:42:27 -07003323 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003324 }
Winson14ff7172019-10-23 10:42:27 -07003325
3326 return wlPermissions != null && wlPermissions.contains(perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003327 }
3328
Winson14ff7172019-10-23 10:42:27 -07003329 private boolean grantSignaturePermission(String perm, AndroidPackage pkg,
Winsone0756292020-01-31 12:21:54 -08003330 PackageSetting pkgSetting, BasePermission bp, PermissionsState origPermissions) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003331 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09003332 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
3333 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003334 boolean privappPermissionsDisable =
3335 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
3336 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07003337 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003338 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
3339 && !platformPackage && platformPermission) {
3340 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Philip P. Moltmannbd278012020-03-10 14:46:27 -07003341 // Only enforce whitelist this on boot
3342 if (!mSystemReady
3343 // Updated system apps do not need to be whitelisted
Philip P. Moltmann67655a12020-03-26 17:22:40 -07003344 && !pkgSetting.getPkgState().isUpdatedSystemApp()) {
3345 ApexManager apexMgr = ApexManager.getInstance();
3346 String apexContainingPkg = apexMgr.getActiveApexPackageNameContainingPackage(
3347 pkg);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07003348
Philip P. Moltmann67655a12020-03-26 17:22:40 -07003349 // Apps that are in updated apexs' do not need to be whitelisted
3350 if (apexContainingPkg == null || apexMgr.isFactory(
3351 apexMgr.getPackageInfo(apexContainingPkg, MATCH_ACTIVE_PACKAGE))) {
3352 // it's only a reportable violation if the permission isn't explicitly
3353 // denied
3354 ArraySet<String> deniedPermissions = null;
3355 if (pkg.isVendor()) {
3356 deniedPermissions = SystemConfig.getInstance()
3357 .getVendorPrivAppDenyPermissions(pkg.getPackageName());
3358 } else if (pkg.isProduct()) {
3359 deniedPermissions = SystemConfig.getInstance()
3360 .getProductPrivAppDenyPermissions(pkg.getPackageName());
3361 } else if (pkg.isSystemExt()) {
3362 deniedPermissions = SystemConfig.getInstance()
3363 .getSystemExtPrivAppDenyPermissions(pkg.getPackageName());
3364 } else {
3365 deniedPermissions = SystemConfig.getInstance()
3366 .getPrivAppDenyPermissions(pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003367 }
Philip P. Moltmann67655a12020-03-26 17:22:40 -07003368 final boolean permissionViolation =
3369 deniedPermissions == null || !deniedPermissions.contains(perm);
3370 if (permissionViolation) {
3371 Slog.w(TAG, "Privileged permission " + perm + " for package "
3372 + pkg.getPackageName() + " (" + pkg.getCodePath()
3373 + ") not in privapp-permissions whitelist");
3374
3375 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3376 if (mPrivappPermissionsViolations == null) {
3377 mPrivappPermissionsViolations = new ArraySet<>();
3378 }
3379 mPrivappPermissionsViolations.add(
3380 pkg.getPackageName() + " (" + pkg.getCodePath() + "): "
3381 + perm);
3382 }
3383 } else {
3384 return false;
3385 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003386 }
3387 }
3388 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3389 return false;
3390 }
3391 }
3392 }
Chen Xu45c183d2019-10-07 00:24:41 -07003393 // expect single system package
3394 String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
3395 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM));
Winson655a5b92019-10-23 10:49:32 -07003396 final AndroidPackage systemPackage =
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003397 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003398
3399 // check if the package is allow to use this signature permission. A package is allowed to
3400 // use a signature permission if:
3401 // - it has the same set of signing certificates as the source package
3402 // - or its signing certificate was rotated from the source package's certificate
3403 // - or its signing certificate is a previous signing certificate of the defining
3404 // package, and the defining package still trusts the old certificate for permissions
3405 // - or it shares the above relationships with the system package
3406 boolean allowed =
Winson14ff7172019-10-23 10:42:27 -07003407 pkg.getSigningDetails().hasAncestorOrSelf(
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003408 bp.getSourcePackageSetting().getSigningDetails())
3409 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
Winson14ff7172019-10-23 10:42:27 -07003410 pkg.getSigningDetails(),
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003411 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
Winson14ff7172019-10-23 10:42:27 -07003412 || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails())
3413 || systemPackage.getSigningDetails().checkCapability(
3414 pkg.getSigningDetails(),
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003415 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003416 if (!allowed && (privilegedPermission || oemPermission)) {
3417 if (pkg.isSystem()) {
3418 // For updated system applications, a privileged/oem permission
3419 // is granted only if it had been defined by the original application.
Winsone0756292020-01-31 12:21:54 -08003420 if (pkgSetting.getPkgState().isUpdatedSystemApp()) {
3421 final PackageSetting disabledPs = mPackageManagerInt
Winson14ff7172019-10-23 10:42:27 -07003422 .getDisabledSystemPackage(pkg.getPackageName());
3423 final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.pkg;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003424 if (disabledPs != null
3425 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
3426 // If the original was granted this permission, we take
3427 // that grant decision as read and propagate it to the
3428 // update.
3429 if ((privilegedPermission && disabledPs.isPrivileged())
3430 || (oemPermission && disabledPs.isOem()
3431 && canGrantOemPermission(disabledPs, perm))) {
3432 allowed = true;
3433 }
3434 } else {
3435 // The system apk may have been updated with an older
3436 // version of the one on the data partition, but which
3437 // granted a new system permission that it didn't have
3438 // before. In this case we do want to allow the app to
3439 // now get the new permission if the ancestral apk is
3440 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07003441 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003442 && isPackageRequestingPermission(disabledPkg, perm)
3443 && ((privilegedPermission && disabledPs.isPrivileged())
3444 || (oemPermission && disabledPs.isOem()
3445 && canGrantOemPermission(disabledPs, perm)))) {
3446 allowed = true;
3447 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003448 }
3449 } else {
Winson14ff7172019-10-23 10:42:27 -07003450 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3451 pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003452 allowed = (privilegedPermission && pkg.isPrivileged())
3453 || (oemPermission && pkg.isOem()
3454 && canGrantOemPermission(ps, perm));
3455 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09003456 // In any case, don't grant a privileged permission to privileged vendor apps, if
3457 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
3458 // flag.
3459 if (allowed && privilegedPermission &&
3460 !vendorPrivilegedPermission && pkg.isVendor()) {
3461 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
Winson14ff7172019-10-23 10:42:27 -07003462 + pkg.getPackageName()
3463 + " because it isn't a 'vendorPrivileged' permission.");
Jiyong Park002fdbd2017-02-13 20:50:31 +09003464 allowed = false;
3465 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003466 }
3467 }
3468 if (!allowed) {
3469 if (!allowed
3470 && bp.isPre23()
Winson14ff7172019-10-23 10:42:27 -07003471 && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003472 // If this was a previously normal/dangerous permission that got moved
3473 // to a system permission as part of the runtime permission redesign, then
3474 // we still want to blindly grant it to old apps.
3475 allowed = true;
3476 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07003477 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
3478 // need a separate flag anymore. Hence we need to check which
3479 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003480 if (!allowed && bp.isInstaller()
Chen Xu45c183d2019-10-07 00:24:41 -07003481 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3482 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003483 pkg.getPackageName()) || ArrayUtils.contains(
3484 mPackageManagerInt.getKnownPackageNames(
3485 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
3486 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003487 // If this permission is to be granted to the system installer and
3488 // this app is an installer, then it gets the permission.
3489 allowed = true;
3490 }
3491 if (!allowed && bp.isVerifier()
Chen Xu45c183d2019-10-07 00:24:41 -07003492 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3493 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003494 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003495 // If this permission is to be granted to the system verifier and
3496 // this app is a verifier, then it gets the permission.
3497 allowed = true;
3498 }
3499 if (!allowed && bp.isPreInstalled()
3500 && pkg.isSystem()) {
3501 // Any pre-installed system app is allowed to get this permission.
3502 allowed = true;
3503 }
3504 if (!allowed && bp.isDevelopment()) {
3505 // For development permissions, a development permission
3506 // is granted only if it was already granted.
3507 allowed = origPermissions.hasInstallPermission(perm);
3508 }
3509 if (!allowed && bp.isSetup()
Chen Xu45c183d2019-10-07 00:24:41 -07003510 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3511 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003512 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003513 // If this permission is to be granted to the system setup wizard and
3514 // this app is a setup wizard, then it gets the permission.
3515 allowed = true;
3516 }
Makoto Onuki700feef2018-02-15 10:59:41 -08003517 if (!allowed && bp.isSystemTextClassifier()
Chen Xu45c183d2019-10-07 00:24:41 -07003518 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Makoto Onuki700feef2018-02-15 10:59:41 -08003519 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
Winson655a5b92019-10-23 10:49:32 -07003520 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Makoto Onuki700feef2018-02-15 10:59:41 -08003521 // Special permissions for the system default text classifier.
3522 allowed = true;
3523 }
Stanislav Zholnin596437f2018-12-28 15:34:23 +00003524 if (!allowed && bp.isConfigurator()
Chen Xu45c183d2019-10-07 00:24:41 -07003525 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3526 PackageManagerInternal.PACKAGE_CONFIGURATOR,
Winson655a5b92019-10-23 10:49:32 -07003527 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Stanislav Zholnin596437f2018-12-28 15:34:23 +00003528 // Special permissions for the device configurator.
3529 allowed = true;
3530 }
Varun Shah5f303652018-11-16 18:11:19 -08003531 if (!allowed && bp.isWellbeing()
Chen Xu45c183d2019-10-07 00:24:41 -07003532 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3533 PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003534 pkg.getPackageName())) {
Varun Shah5f303652018-11-16 18:11:19 -08003535 // Special permission granted only to the OEM specified wellbeing app
3536 allowed = true;
3537 }
Jeff Sharkey15707b32018-12-10 12:08:41 -07003538 if (!allowed && bp.isDocumenter()
Chen Xu45c183d2019-10-07 00:24:41 -07003539 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3540 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003541 pkg.getPackageName())) {
Jeff Sharkey15707b32018-12-10 12:08:41 -07003542 // If this permission is to be granted to the documenter and
3543 // this app is the documenter, then it gets the permission.
3544 allowed = true;
3545 }
Joe Onorato5a15b552018-12-18 10:40:04 -08003546 if (!allowed && bp.isIncidentReportApprover()
Chen Xu45c183d2019-10-07 00:24:41 -07003547 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Joe Onorato5a15b552018-12-18 10:40:04 -08003548 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
Winson655a5b92019-10-23 10:49:32 -07003549 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Joe Onorato5a15b552018-12-18 10:40:04 -08003550 // If this permission is to be granted to the incident report approver and
3551 // this app is the incident report approver, then it gets the permission.
3552 allowed = true;
3553 }
George Hodulikcd7695d2019-01-29 18:17:05 -08003554 if (!allowed && bp.isAppPredictor()
Chen Xu45c183d2019-10-07 00:24:41 -07003555 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3556 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003557 pkg.getPackageName())) {
George Hodulikcd7695d2019-01-29 18:17:05 -08003558 // Special permissions for the system app predictor.
3559 allowed = true;
3560 }
Eugene Susla1fa23ed02019-07-24 16:30:16 -07003561 if (!allowed && bp.isCompanion()
3562 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3563 PackageManagerInternal.PACKAGE_COMPANION, UserHandle.USER_SYSTEM),
3564 pkg.getPackageName())) {
3565 // Special permissions for the system companion device manager.
3566 allowed = true;
3567 }
wayneyang8126b1f2020-01-09 14:10:31 +08003568 if (!allowed && bp.isRetailDemo()
3569 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3570 PackageManagerInternal.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM),
3571 pkg.getPackageName()) && isProfileOwner(pkg.getUid())) {
3572 // Special permission granted only to the OEM specified retail demo app
3573 allowed = true;
3574 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003575 }
3576 return allowed;
3577 }
3578
wayneyang8126b1f2020-01-09 14:10:31 +08003579 private static boolean isProfileOwner(int uid) {
3580 DevicePolicyManagerInternal dpmInternal =
3581 LocalServices.getService(DevicePolicyManagerInternal.class);
3582 if (dpmInternal != null) {
3583 return dpmInternal
3584 .isActiveAdminWithPolicy(uid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3585 }
3586 return false;
3587 }
3588
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003589 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
3590 if (!ps.isOem()) {
3591 return false;
3592 }
3593 // all oem permissions must explicitly be granted or denied
3594 final Boolean granted =
3595 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
3596 if (granted == null) {
3597 throw new IllegalStateException("OEM permission" + permission + " requested by package "
3598 + ps.name + " must be explicitly declared granted or not");
3599 }
3600 return Boolean.TRUE == granted;
3601 }
3602
Winson14ff7172019-10-23 10:42:27 -07003603 private boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07003604 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003605 // Permission review applies only to apps not supporting the new permission model.
Winson14ff7172019-10-23 10:42:27 -07003606 if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003607 return false;
3608 }
3609
3610 // Legacy apps have the permission and get user consent on launch.
Winson14ff7172019-10-23 10:42:27 -07003611 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3612 pkg.getPackageName());
3613 if (ps == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003614 return false;
3615 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003616 final PermissionsState permissionsState = ps.getPermissionsState();
3617 return permissionsState.isPermissionReviewRequired(userId);
3618 }
3619
Winson14ff7172019-10-23 10:42:27 -07003620 private boolean isPackageRequestingPermission(AndroidPackage pkg, String permission) {
3621 final int permCount = pkg.getRequestedPermissions().size();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003622 for (int j = 0; j < permCount; j++) {
Winson14ff7172019-10-23 10:42:27 -07003623 String requestedPermission = pkg.getRequestedPermissions().get(j);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003624 if (permission.equals(requestedPermission)) {
3625 return true;
3626 }
3627 }
3628 return false;
3629 }
3630
Winson14ff7172019-10-23 10:42:27 -07003631 private void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003632 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3633 for (int userId : userIds) {
3634 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
3635 callback);
3636 }
3637 }
3638
Winson14ff7172019-10-23 10:42:27 -07003639 private void grantRequestedRuntimePermissionsForUser(AndroidPackage pkg, int userId,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003640 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
Winson14ff7172019-10-23 10:42:27 -07003641 PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3642 pkg.getPackageName());
Todd Kennedy0eb97382017-10-03 16:57:22 -07003643 if (ps == null) {
3644 return;
3645 }
3646
3647 PermissionsState permissionsState = ps.getPermissionsState();
3648
3649 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
3650 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3651
Hai Zhangfa291702019-09-19 16:35:44 -07003652 final int compatFlags = PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
3653 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
3654
Winson14ff7172019-10-23 10:42:27 -07003655 final boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
Todd Kennedy0eb97382017-10-03 16:57:22 -07003656 >= Build.VERSION_CODES.M;
3657
Winson14ff7172019-10-23 10:42:27 -07003658 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003659
Winson14ff7172019-10-23 10:42:27 -07003660 for (String permission : pkg.getRequestedPermissions()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003661 final BasePermission bp;
3662 synchronized (mLock) {
3663 bp = mSettings.getPermissionLocked(permission);
3664 }
3665 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
3666 && (!instantApp || bp.isInstant())
3667 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
3668 && (grantedPermissions == null
3669 || ArrayUtils.contains(grantedPermissions, permission))) {
3670 final int flags = permissionsState.getPermissionFlags(permission, userId);
3671 if (supportsRuntimePermissions) {
3672 // Installer cannot change immutable permissions.
3673 if ((flags & immutableFlags) == 0) {
Winson14ff7172019-10-23 10:42:27 -07003674 grantRuntimePermissionInternal(permission, pkg.getPackageName(), false,
Todd Kennedyc971a452019-07-08 16:04:52 -07003675 callingUid, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003676 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07003677 } else {
Hai Zhangfa291702019-09-19 16:35:44 -07003678 // In permission review mode we clear the review flag and the revoked compat
3679 // flag when we are asked to install the app with all permissions granted.
3680 if ((flags & compatFlags) != 0) {
Winson14ff7172019-10-23 10:42:27 -07003681 updatePermissionFlagsInternal(permission, pkg.getPackageName(), compatFlags,
Hai Zhangfa291702019-09-19 16:35:44 -07003682 0, callingUid, userId, false, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003683 }
3684 }
3685 }
3686 }
3687 }
3688
Winson14ff7172019-10-23 10:42:27 -07003689 private void setWhitelistedRestrictedPermissionsForUser(@NonNull AndroidPackage pkg,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003690 @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
3691 @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003692 final PermissionsState permissionsState =
Winson14ff7172019-10-23 10:42:27 -07003693 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003694 if (permissionsState == null) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003695 return;
3696 }
3697
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003698 ArraySet<String> oldGrantedRestrictedPermissions = null;
3699 boolean updatePermissions = false;
3700
Winson14ff7172019-10-23 10:42:27 -07003701 final int permissionCount = pkg.getRequestedPermissions().size();
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003702 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07003703 final String permissionName = pkg.getRequestedPermissions().get(i);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003704
3705 final BasePermission bp = mSettings.getPermissionLocked(permissionName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003706
Evan Seversoncdcaaaa2019-07-02 10:29:25 -07003707 if (bp == null || !bp.isHardOrSoftRestricted()) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003708 continue;
3709 }
3710
3711 if (permissionsState.hasPermission(permissionName, userId)) {
3712 if (oldGrantedRestrictedPermissions == null) {
3713 oldGrantedRestrictedPermissions = new ArraySet<>();
3714 }
3715 oldGrantedRestrictedPermissions.add(permissionName);
3716 }
3717
3718 final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
3719
3720 int newFlags = oldFlags;
3721 int mask = 0;
3722 int whitelistFlagsCopy = whitelistFlags;
3723 while (whitelistFlagsCopy != 0) {
3724 final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
3725 whitelistFlagsCopy &= ~flag;
3726 switch (flag) {
3727 case FLAG_PERMISSION_WHITELIST_SYSTEM: {
3728 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3729 if (permissions != null && permissions.contains(permissionName)) {
3730 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3731 } else {
3732 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3733 }
3734 } break;
3735 case FLAG_PERMISSION_WHITELIST_UPGRADE: {
3736 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3737 if (permissions != null && permissions.contains(permissionName)) {
3738 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3739 } else {
3740 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3741 }
3742 } break;
3743 case FLAG_PERMISSION_WHITELIST_INSTALLER: {
3744 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3745 if (permissions != null && permissions.contains(permissionName)) {
3746 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3747 } else {
3748 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3749 }
3750 } break;
3751 }
3752 }
3753
3754 if (oldFlags == newFlags) {
3755 continue;
3756 }
3757
3758 updatePermissions = true;
3759
Svet Ganovd563e932019-04-14 13:07:41 -07003760 final boolean wasWhitelisted = (oldFlags
3761 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3762 final boolean isWhitelisted = (newFlags
3763 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3764
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003765 // If the permission is policy fixed as granted but it is no longer
3766 // on any of the whitelists we need to clear the policy fixed flag
3767 // as whitelisting trumps policy i.e. policy cannot grant a non
3768 // grantable permission.
3769 if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003770 final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
3771 if (!isWhitelisted && isGranted) {
3772 mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3773 newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3774 }
3775 }
3776
Svet Ganovd563e932019-04-14 13:07:41 -07003777 // If we are whitelisting an app that does not support runtime permissions
3778 // we need to make sure it goes through the permission review UI at launch.
Winson14ff7172019-10-23 10:42:27 -07003779 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Svet Ganovd563e932019-04-14 13:07:41 -07003780 && !wasWhitelisted && isWhitelisted) {
3781 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3782 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3783 }
3784
Winson14ff7172019-10-23 10:42:27 -07003785 updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003786 callingUid, userId, false, null /*callback*/);
3787 }
3788
3789 if (updatePermissions) {
Philip P. Moltmannba742062019-04-08 13:22:44 -07003790 // Update permission of this app to take into account the new whitelist state.
Winson14ff7172019-10-23 10:42:27 -07003791 restorePermissionState(pkg, false, pkg.getPackageName(), callback);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003792
3793 // If this resulted in losing a permission we need to kill the app.
3794 if (oldGrantedRestrictedPermissions != null) {
3795 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
3796 for (int i = 0; i < oldGrantedCount; i++) {
3797 final String permission = oldGrantedRestrictedPermissions.valueAt(i);
3798 // Sometimes we create a new permission state instance during update.
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003799 final PermissionsState newPermissionsState =
Winson14ff7172019-10-23 10:42:27 -07003800 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003801 if (!newPermissionsState.hasPermission(permission, userId)) {
Winson14ff7172019-10-23 10:42:27 -07003802 callback.onPermissionRevoked(pkg.getUid(), userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003803 break;
3804 }
3805 }
3806 }
3807 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07003808 }
3809
Andreas Gampea36dc622018-02-05 17:19:22 -08003810 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003811 private int[] revokeUnusedSharedUserPermissionsLocked(
3812 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003813 // Collect all used permissions in the UID
3814 final ArraySet<String> usedPermissions = new ArraySet<>();
Winson14ff7172019-10-23 10:42:27 -07003815 final List<AndroidPackage> pkgList = suSetting.getPackages();
Todd Kennedy0eb97382017-10-03 16:57:22 -07003816 if (pkgList == null || pkgList.size() == 0) {
3817 return EmptyArray.INT;
3818 }
Winson14ff7172019-10-23 10:42:27 -07003819 for (AndroidPackage pkg : pkgList) {
Winsone23ae202020-01-24 11:56:44 -08003820 if (pkg.getRequestedPermissions().isEmpty()) {
Svet Ganovd8308072018-03-24 00:04:38 -07003821 continue;
3822 }
Winson14ff7172019-10-23 10:42:27 -07003823 final int requestedPermCount = pkg.getRequestedPermissions().size();
Todd Kennedy0eb97382017-10-03 16:57:22 -07003824 for (int j = 0; j < requestedPermCount; j++) {
Winson14ff7172019-10-23 10:42:27 -07003825 String permission = pkg.getRequestedPermissions().get(j);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003826 BasePermission bp = mSettings.getPermissionLocked(permission);
3827 if (bp != null) {
3828 usedPermissions.add(permission);
3829 }
3830 }
3831 }
3832
3833 PermissionsState permissionsState = suSetting.getPermissionsState();
3834 // Prune install permissions
3835 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
3836 final int installPermCount = installPermStates.size();
3837 for (int i = installPermCount - 1; i >= 0; i--) {
3838 PermissionState permissionState = installPermStates.get(i);
3839 if (!usedPermissions.contains(permissionState.getName())) {
3840 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
3841 if (bp != null) {
3842 permissionsState.revokeInstallPermission(bp);
3843 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08003844 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003845 }
3846 }
3847 }
3848
3849 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
3850
3851 // Prune runtime permissions
3852 for (int userId : allUserIds) {
3853 List<PermissionState> runtimePermStates = permissionsState
3854 .getRuntimePermissionStates(userId);
3855 final int runtimePermCount = runtimePermStates.size();
3856 for (int i = runtimePermCount - 1; i >= 0; i--) {
3857 PermissionState permissionState = runtimePermStates.get(i);
3858 if (!usedPermissions.contains(permissionState.getName())) {
3859 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
3860 if (bp != null) {
3861 permissionsState.revokeRuntimePermission(bp, userId);
3862 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08003863 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003864 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
3865 runtimePermissionChangedUserIds, userId);
3866 }
3867 }
3868 }
3869 }
3870
3871 return runtimePermissionChangedUserIds;
3872 }
3873
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003874 /**
3875 * Update permissions when a package changed.
3876 *
3877 * <p><ol>
3878 * <li>Reconsider the ownership of permission</li>
3879 * <li>Update the state (grant, flags) of the permissions</li>
3880 * </ol>
3881 *
3882 * @param packageName The package that is updated
3883 * @param pkg The package that is updated, or {@code null} if package is deleted
3884 * @param allPackages All currently known packages
3885 * @param callback Callback to call after permission changes
3886 */
Winson14ff7172019-10-23 10:42:27 -07003887 private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003888 @NonNull PermissionCallback callback) {
Songchun Fanbcc899e2020-04-06 16:51:45 -07003889 // If the package is being deleted, update the permissions of all the apps
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003890 final int flags =
Songchun Fanbcc899e2020-04-06 16:51:45 -07003891 (pkg == null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG
3892 : UPDATE_PERMISSIONS_REPLACE_PKG);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003893 updatePermissions(
Todd Kennedyc971a452019-07-08 16:04:52 -07003894 packageName, pkg, getVolumeUuidForPackage(pkg), flags, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003895 }
3896
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003897 /**
3898 * Update all permissions for all apps.
3899 *
3900 * <p><ol>
3901 * <li>Reconsider the ownership of permission</li>
3902 * <li>Update the state (grant, flags) of the permissions</li>
3903 * </ol>
3904 *
3905 * @param volumeUuid The volume of the packages to be updated, {@code null} for all volumes
3906 * @param allPackages All currently known packages
3907 * @param callback Callback to call after permission changes
3908 */
3909 private void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003910 @NonNull PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003911 final int flags = UPDATE_PERMISSIONS_ALL |
3912 (sdkUpdated
3913 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
3914 : 0);
Todd Kennedyc971a452019-07-08 16:04:52 -07003915 updatePermissions(null, null, volumeUuid, flags, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003916 }
3917
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003918 /**
3919 * Cache background->foreground permission mapping.
3920 *
3921 * <p>This is only run once.
3922 */
3923 private void cacheBackgroundToForegoundPermissionMapping() {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003924 synchronized (mLock) {
3925 if (mBackgroundPermissions == null) {
3926 // Cache background -> foreground permission mapping.
3927 // Only system declares background permissions, hence mapping does never change.
3928 mBackgroundPermissions = new ArrayMap<>();
3929 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Winsonf00c7552020-01-28 12:52:01 -08003930 if (bp.perm != null && bp.perm.getBackgroundPermission() != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003931 String fgPerm = bp.name;
Winsonf00c7552020-01-28 12:52:01 -08003932 String bgPerm = bp.perm.getBackgroundPermission();
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003933
3934 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
3935 if (fgPerms == null) {
3936 fgPerms = new ArrayList<>();
3937 mBackgroundPermissions.put(bgPerm, fgPerms);
3938 }
3939
3940 fgPerms.add(fgPerm);
3941 }
3942 }
3943 }
3944 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003945 }
3946
3947 /**
3948 * Update all packages on the volume, <u>beside</u> the changing package. If the changing
3949 * package is set too, all packages are updated.
3950 */
3951 private static final int UPDATE_PERMISSIONS_ALL = 1 << 0;
3952 /** The changing package is replaced. Requires the changing package to be set */
3953 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1 << 1;
3954 /**
3955 * Schedule all packages <u>beside</u> the changing package for replacement. Requires
3956 * UPDATE_PERMISSIONS_ALL to be set
3957 */
3958 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1 << 2;
3959
3960 @IntDef(flag = true, prefix = { "UPDATE_PERMISSIONS_" }, value = {
3961 UPDATE_PERMISSIONS_ALL, UPDATE_PERMISSIONS_REPLACE_PKG,
3962 UPDATE_PERMISSIONS_REPLACE_ALL })
3963 @Retention(RetentionPolicy.SOURCE)
3964 private @interface UpdatePermissionFlags {}
3965
3966 /**
3967 * Update permissions when packages changed.
3968 *
3969 * <p><ol>
3970 * <li>Reconsider the ownership of permission</li>
3971 * <li>Update the state (grant, flags) of the permissions</li>
3972 * </ol>
3973 *
3974 * <p>Meaning of combination of package parameters:
3975 * <table>
3976 * <tr><th></th><th>changingPkgName != null</th><th>changingPkgName == null</th></tr>
3977 * <tr><th>changingPkg != null</th><td>package is updated</td><td>invalid</td></tr>
3978 * <tr><th>changingPkg == null</th><td>package is deleted</td><td>all packages are
3979 * updated</td></tr>
3980 * </table>
3981 *
3982 * @param changingPkgName The package that is updated, or {@code null} if all packages should be
3983 * updated
3984 * @param changingPkg The package that is updated, or {@code null} if all packages should be
3985 * updated or package is deleted
3986 * @param replaceVolumeUuid The volume of the packages to be updated are on, {@code null} for
3987 * all volumes
3988 * @param flags Control permission for which apps should be updated
3989 * @param allPackages All currently known packages
3990 * @param callback Callback to call after permission changes
3991 */
Todd Kennedyc971a452019-07-08 16:04:52 -07003992 private void updatePermissions(final @Nullable String changingPkgName,
Winson14ff7172019-10-23 10:42:27 -07003993 final @Nullable AndroidPackage changingPkg,
Todd Kennedyc971a452019-07-08 16:04:52 -07003994 final @Nullable String replaceVolumeUuid,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003995 @UpdatePermissionFlags int flags,
Todd Kennedyc971a452019-07-08 16:04:52 -07003996 final @Nullable PermissionCallback callback) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003997 // TODO: Most of the methods exposing BasePermission internals [source package name,
3998 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
3999 // have package settings, we should make note of it elsewhere [map between
4000 // source package name and BasePermission] and cycle through that here. Then we
4001 // define a single method on BasePermission that takes a PackageSetting, changing
4002 // package name and a package.
4003 // NOTE: With this approach, we also don't need to tree trees differently than
4004 // normal permissions. Today, we need two separate loops because these BasePermission
4005 // objects are stored separately.
4006 // Make sure there are no dangling permission trees.
4007 boolean permissionTreesSourcePackageChanged = updatePermissionTreeSourcePackage(
4008 changingPkgName, changingPkg);
4009 // Make sure all dynamic permissions have been assigned to a package,
4010 // and make sure there are no dangling permissions.
4011 boolean permissionSourcePackageChanged = updatePermissionSourcePackage(changingPkgName,
Hongming Jinbc4d0102019-08-16 14:28:30 -07004012 changingPkg, callback);
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004013
4014 if (permissionTreesSourcePackageChanged | permissionSourcePackageChanged) {
4015 // Permission ownership has changed. This e.g. changes which packages can get signature
4016 // permissions
Songchun Fanbcc899e2020-04-06 16:51:45 -07004017 Slog.i(TAG, "Permission ownership changed. Updating all permissions.");
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004018 flags |= UPDATE_PERMISSIONS_ALL;
4019 }
4020
4021 cacheBackgroundToForegoundPermissionMapping();
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07004022
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07004023 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004024 // Now update the permissions for all packages.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004025 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004026 final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
Winson14ff7172019-10-23 10:42:27 -07004027 mPackageManagerInt.forEachPackage((AndroidPackage pkg) -> {
Todd Kennedyc971a452019-07-08 16:04:52 -07004028 if (pkg == changingPkg) {
4029 return;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004030 }
Todd Kennedyc971a452019-07-08 16:04:52 -07004031 // Only replace for packages on requested volume
4032 final String volumeUuid = getVolumeUuidForPackage(pkg);
4033 final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid);
4034 restorePermissionState(pkg, replace, changingPkgName, callback);
4035 });
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004036 }
4037
4038 if (changingPkg != null) {
4039 // Only replace for packages on requested volume
4040 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
4041 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
4042 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07004043 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004044 }
4045 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4046 }
4047
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004048 /**
4049 * Update which app declares a permission.
4050 *
4051 * <p>Possible parameter combinations
4052 * <table>
4053 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
4054 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
4055 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
4056 * </table>
4057 *
4058 * @param packageName The package that is updated, or {@code null} if all packages should be
4059 * updated
4060 * @param pkg The package that is updated, or {@code null} if all packages should be updated or
4061 * package is deleted
4062 *
4063 * @return {@code true} if a permission source package might have changed
4064 */
4065 private boolean updatePermissionSourcePackage(@Nullable String packageName,
Winson14ff7172019-10-23 10:42:27 -07004066 @Nullable AndroidPackage pkg,
Hongming Jinbc4d0102019-08-16 14:28:30 -07004067 final @Nullable PermissionCallback callback) {
Songchun Fanbcc899e2020-04-06 16:51:45 -07004068 // Always need update if packageName is null
4069 if (packageName == null) {
4070 return true;
4071 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004072
Songchun Fanbcc899e2020-04-06 16:51:45 -07004073 boolean changed = false;
Todd Kennedyc8423932017-10-05 08:58:36 -07004074 Set<BasePermission> needsUpdate = null;
4075 synchronized (mLock) {
4076 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
4077 while (it.hasNext()) {
4078 final BasePermission bp = it.next();
4079 if (bp.isDynamic()) {
4080 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
4081 }
Songchun Fanbcc899e2020-04-06 16:51:45 -07004082 if (bp.getSourcePackageSetting() == null
4083 || !packageName.equals(bp.getSourcePackageName())) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004084 continue;
4085 }
Songchun Fanbcc899e2020-04-06 16:51:45 -07004086 // The target package is the source of the current permission
4087 // Set to changed for either install or uninstall
4088 changed = true;
4089 // If the target package is being uninstalled, we need to revoke this permission
4090 // From all other packages
4091 if (pkg == null || !hasPermission(pkg, bp.getName())) {
4092 Slog.i(TAG, "Removing permission " + bp.getName()
4093 + " that used to be declared by " + bp.getSourcePackageName());
4094 if (bp.isRuntime()) {
4095 final int[] userIds = mUserManagerInt.getUserIds();
4096 final int numUserIds = userIds.length;
4097 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
4098 final int userId = userIds[userIdNum];
4099 mPackageManagerInt.forEachPackage((AndroidPackage p) ->
4100 revokePermissionFromPackageForUser(p.getPackageName(),
4101 bp.getName(), userId, callback));
4102 }
4103 }
4104 it.remove();
4105 }
Todd Kennedyc8423932017-10-05 08:58:36 -07004106 if (needsUpdate == null) {
4107 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
4108 }
4109 needsUpdate.add(bp);
4110 }
4111 }
4112 if (needsUpdate != null) {
4113 for (final BasePermission bp : needsUpdate) {
Winson14ff7172019-10-23 10:42:27 -07004114 final AndroidPackage sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07004115 mPackageManagerInt.getPackage(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07004116 final PackageSetting sourcePs =
4117 (PackageSetting) mPackageManagerInt.getPackageSetting(
4118 bp.getSourcePackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07004119 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07004120 if (sourcePkg != null && sourcePs != null) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004121 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004122 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07004123 }
4124 continue;
4125 }
4126 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
4127 + " from package " + bp.getSourcePackageName());
4128 mSettings.removePermissionLocked(bp.getName());
4129 }
4130 }
4131 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004132 return changed;
Todd Kennedyc8423932017-10-05 08:58:36 -07004133 }
4134
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004135 /**
Songchun Fanbcc899e2020-04-06 16:51:45 -07004136 * Revoke a runtime permission from a package for a given user ID.
4137 */
4138 private void revokePermissionFromPackageForUser(@NonNull String pName,
4139 @NonNull String permissionName, int userId, @Nullable PermissionCallback callback) {
4140 final ApplicationInfo appInfo =
4141 mPackageManagerInt.getApplicationInfo(pName, 0,
4142 Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
4143 if (appInfo != null
4144 && appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4145 return;
4146 }
4147
4148 if (checkPermissionImpl(permissionName, pName, userId)
4149 == PackageManager.PERMISSION_GRANTED) {
4150 try {
4151 revokeRuntimePermissionInternal(
4152 permissionName,
4153 pName,
4154 false,
4155 Process.SYSTEM_UID,
4156 userId,
4157 callback);
4158 } catch (IllegalArgumentException e) {
4159 Slog.e(TAG,
4160 "Failed to revoke "
4161 + permissionName
4162 + " from "
4163 + pName,
4164 e);
4165 }
4166 }
4167 }
4168 /**
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004169 * Update which app owns a permission trees.
4170 *
4171 * <p>Possible parameter combinations
4172 * <table>
4173 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
4174 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
4175 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
4176 * </table>
4177 *
4178 * @param packageName The package that is updated, or {@code null} if all packages should be
4179 * updated
4180 * @param pkg The package that is updated, or {@code null} if all packages should be updated or
4181 * package is deleted
4182 *
4183 * @return {@code true} if a permission tree ownership might have changed
4184 */
4185 private boolean updatePermissionTreeSourcePackage(@Nullable String packageName,
Winson14ff7172019-10-23 10:42:27 -07004186 @Nullable AndroidPackage pkg) {
Songchun Fanbcc899e2020-04-06 16:51:45 -07004187 // Always need update if packageName is null
4188 if (packageName == null) {
4189 return true;
4190 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004191 boolean changed = false;
4192
Todd Kennedyc8423932017-10-05 08:58:36 -07004193 Set<BasePermission> needsUpdate = null;
4194 synchronized (mLock) {
4195 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
4196 while (it.hasNext()) {
4197 final BasePermission bp = it.next();
Songchun Fanbcc899e2020-04-06 16:51:45 -07004198 if (bp.getSourcePackageSetting() == null
4199 || !packageName.equals(bp.getSourcePackageName())) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004200 continue;
4201 }
Songchun Fanbcc899e2020-04-06 16:51:45 -07004202 // The target package is the source of the current permission tree
4203 // Set to changed for either install or uninstall
4204 changed = true;
4205 if (pkg == null || !hasPermission(pkg, bp.getName())) {
4206 Slog.i(TAG, "Removing permission tree " + bp.getName()
4207 + " that used to be declared by " + bp.getSourcePackageName());
4208 it.remove();
4209 }
Todd Kennedyc8423932017-10-05 08:58:36 -07004210 if (needsUpdate == null) {
4211 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
4212 }
4213 needsUpdate.add(bp);
4214 }
4215 }
4216 if (needsUpdate != null) {
4217 for (final BasePermission bp : needsUpdate) {
Winson14ff7172019-10-23 10:42:27 -07004218 final AndroidPackage sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07004219 mPackageManagerInt.getPackage(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07004220 final PackageSetting sourcePs =
4221 (PackageSetting) mPackageManagerInt.getPackageSetting(
4222 bp.getSourcePackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07004223 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07004224 if (sourcePkg != null && sourcePs != null) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004225 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004226 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07004227 }
4228 continue;
4229 }
4230 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
4231 + " from package " + bp.getSourcePackageName());
4232 mSettings.removePermissionLocked(bp.getName());
4233 }
4234 }
4235 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004236 return changed;
Todd Kennedyc8423932017-10-05 08:58:36 -07004237 }
4238
Todd Kennedy0eb97382017-10-03 16:57:22 -07004239 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4240 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4241 != PackageManager.PERMISSION_GRANTED
4242 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4243 != PackageManager.PERMISSION_GRANTED) {
4244 throw new SecurityException(message + " requires "
4245 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4246 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4247 }
4248 }
4249
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08004250 private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
4251 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
4252 != PackageManager.PERMISSION_GRANTED
4253 && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4254 != PackageManager.PERMISSION_GRANTED
4255 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4256 != PackageManager.PERMISSION_GRANTED) {
4257 throw new SecurityException(message + " requires "
4258 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4259 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
4260 + Manifest.permission.GET_RUNTIME_PERMISSIONS);
4261 }
4262 }
4263
Todd Kennedy0eb97382017-10-03 16:57:22 -07004264 /**
4265 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4266 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4267 * @param checkShell whether to prevent shell from access if there's a debugging restriction
4268 * @param message the message to log on security exception
4269 */
4270 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07004271 boolean requireFullPermission, boolean checkShell,
4272 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004273 if (userId < 0) {
4274 throw new IllegalArgumentException("Invalid userId " + userId);
4275 }
4276 if (checkShell) {
Patrick Baumann2f2fd712019-07-31 15:18:53 -07004277 PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
Todd Kennedy0eb97382017-10-03 16:57:22 -07004278 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4279 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004280 final int callingUserId = UserHandle.getUserId(callingUid);
4281 if (hasCrossUserPermission(
4282 callingUid, callingUserId, userId, requireFullPermission,
4283 requirePermissionWhenSameUser)) {
4284 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07004285 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004286 String errorMessage = buildInvalidCrossUserPermissionMessage(
4287 message, requireFullPermission);
4288 Slog.w(TAG, errorMessage);
4289 throw new SecurityException(errorMessage);
4290 }
4291
4292 /**
4293 * Checks if the request is from the system or an app that has the appropriate cross-user
4294 * permissions defined as follows:
4295 * <ul>
4296 * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
4297 * <li>INTERACT_ACROSS_USERS if the given {@userId} is in a different profile group
4298 * to the caller.</li>
4299 * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@userId} is in the same profile group
4300 * as the caller.</li>
4301 * </ul>
4302 *
4303 * @param checkShell whether to prevent shell from access if there's a debugging restriction
4304 * @param message the message to log on security exception
4305 */
4306 private void enforceCrossUserOrProfilePermission(int callingUid, int userId,
4307 boolean requireFullPermission, boolean checkShell,
4308 String message) {
4309 if (userId < 0) {
4310 throw new IllegalArgumentException("Invalid userId " + userId);
4311 }
4312 if (checkShell) {
4313 PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
4314 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4315 }
4316 final int callingUserId = UserHandle.getUserId(callingUid);
4317 if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission,
4318 /*requirePermissionWhenSameUser= */ false)) {
4319 return;
4320 }
4321 final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
kholoud mohamed79a89f02020-01-15 15:30:07 +00004322 if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight(
4323 mContext,
4324 android.Manifest.permission.INTERACT_ACROSS_PROFILES,
4325 PermissionChecker.PID_UNKNOWN,
4326 callingUid,
4327 mPackageManagerInt.getPackage(callingUid).getPackageName())
4328 == PermissionChecker.PERMISSION_GRANTED) {
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004329 return;
4330 }
4331 String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
4332 message, requireFullPermission, isSameProfileGroup);
4333 Slog.w(TAG, errorMessage);
4334 throw new SecurityException(errorMessage);
4335 }
4336
4337 private boolean hasCrossUserPermission(
4338 int callingUid, int callingUserId, int userId, boolean requireFullPermission,
4339 boolean requirePermissionWhenSameUser) {
4340 if (!requirePermissionWhenSameUser && userId == callingUserId) {
4341 return true;
4342 }
4343 if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
4344 return true;
4345 }
4346 if (requireFullPermission) {
4347 return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4348 }
4349 return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
4350 || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
4351 }
4352
4353 private boolean hasPermission(String permission) {
4354 return mContext.checkCallingOrSelfPermission(permission)
4355 == PackageManager.PERMISSION_GRANTED;
4356 }
4357
4358 private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
4359 final long identity = Binder.clearCallingIdentity();
4360 try {
4361 return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
4362 } finally {
4363 Binder.restoreCallingIdentity(identity);
4364 }
4365 }
4366
4367 private static String buildInvalidCrossUserPermissionMessage(
4368 String message, boolean requireFullPermission) {
4369 StringBuilder builder = new StringBuilder();
4370 if (message != null) {
4371 builder.append(message);
4372 builder.append(": ");
4373 }
4374 builder.append("Requires ");
4375 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4376 if (requireFullPermission) {
4377 builder.append(".");
4378 return builder.toString();
4379 }
4380 builder.append(" or ");
4381 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
4382 builder.append(".");
4383 return builder.toString();
4384 }
4385
4386 private static String buildInvalidCrossUserOrProfilePermissionMessage(
4387 String message, boolean requireFullPermission, boolean isSameProfileGroup) {
4388 StringBuilder builder = new StringBuilder();
4389 if (message != null) {
4390 builder.append(message);
4391 builder.append(": ");
4392 }
4393 builder.append("Requires ");
4394 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4395 if (requireFullPermission) {
4396 builder.append(".");
4397 return builder.toString();
4398 }
4399 builder.append(" or ");
4400 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
4401 if (isSameProfileGroup) {
4402 builder.append(" or ");
4403 builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES);
4404 }
4405 builder.append(".");
4406 return builder.toString();
Todd Kennedy0eb97382017-10-03 16:57:22 -07004407 }
4408
Andreas Gampea71bee82018-07-20 12:55:36 -07004409 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07004410 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4411 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07004412 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004413 size += tree.calculateFootprint(perm);
4414 }
4415 return size;
4416 }
4417
Andreas Gampea71bee82018-07-20 12:55:36 -07004418 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07004419 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4420 // We calculate the max size of permissions defined by this uid and throw
4421 // if that plus the size of 'info' would exceed our stated maximum.
4422 if (tree.getUid() != Process.SYSTEM_UID) {
4423 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4424 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
4425 throw new SecurityException("Permission tree size cap exceeded");
4426 }
4427 }
4428 }
4429
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004430 private void systemReady() {
4431 mSystemReady = true;
4432 if (mPrivappPermissionsViolations != null) {
4433 throw new IllegalStateException("Signature|privileged permissions not in "
4434 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
4435 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08004436
4437 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
Svet Ganov3c499ea2019-07-26 17:45:56 -07004438 mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
Todd Kennedy583378d2019-07-12 06:50:30 -07004439
4440 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
4441 for (int userId : UserManagerService.getInstance().getUserIds()) {
Evan Severson0dc24cb2020-02-04 10:25:08 -08004442 if (mPackageManagerInt.isPermissionUpgradeNeeded(userId)) {
Todd Kennedy583378d2019-07-12 06:50:30 -07004443 grantPermissionsUserIds = ArrayUtils.appendInt(
4444 grantPermissionsUserIds, userId);
4445 }
4446 }
4447 // If we upgraded grant all default permissions before kicking off.
4448 for (int userId : grantPermissionsUserIds) {
4449 mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
4450 }
4451 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
4452 // If we did not grant default permissions, we preload from this the
4453 // default permission exceptions lazily to ensure we don't hit the
4454 // disk on a new user creation.
4455 mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
4456 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004457 }
4458
Winson14ff7172019-10-23 10:42:27 -07004459 private static String getVolumeUuidForPackage(AndroidPackage pkg) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004460 if (pkg == null) {
4461 return StorageManager.UUID_PRIVATE_INTERNAL;
4462 }
Winson5e0a1d52020-01-24 12:00:33 -08004463 if (pkg.isExternalStorage()) {
Winson14ff7172019-10-23 10:42:27 -07004464 if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004465 return StorageManager.UUID_PRIMARY_PHYSICAL;
4466 } else {
Winson14ff7172019-10-23 10:42:27 -07004467 return pkg.getVolumeUuid();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004468 }
4469 } else {
4470 return StorageManager.UUID_PRIVATE_INTERNAL;
4471 }
4472 }
4473
Winson14ff7172019-10-23 10:42:27 -07004474 private static boolean hasPermission(AndroidPackage pkg, String permName) {
Winsone23ae202020-01-24 11:56:44 -08004475 if (pkg.getPermissions().isEmpty()) {
Winson14ff7172019-10-23 10:42:27 -07004476 return false;
4477 }
4478
4479 for (int i = pkg.getPermissions().size() - 1; i >= 0; i--) {
4480 if (pkg.getPermissions().get(i).getName().equals(permName)) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004481 return true;
4482 }
4483 }
4484 return false;
4485 }
4486
Todd Kennedy0eb97382017-10-03 16:57:22 -07004487 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004488 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07004489 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004490 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07004491 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004492 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07004493 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004494 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
4495 final LogMaker log = new LogMaker(action);
4496 log.setPackageName(packageName);
4497 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004498
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004499 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004500 }
4501
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07004502 /**
4503 * Get the mapping of background permissions to their foreground permissions.
4504 *
4505 * <p>Only initialized in the system server.
4506 *
4507 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
4508 */
4509 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
4510 return mBackgroundPermissions;
4511 }
4512
Philip P. Moltmann48456672019-01-20 13:14:03 -08004513 private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004514 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004515 public void systemReady() {
4516 PermissionManagerService.this.systemReady();
4517 }
4518 @Override
Winson14ff7172019-10-23 10:42:27 -07004519 public boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
4520 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004521 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
4522 }
Winson14ff7172019-10-23 10:42:27 -07004523
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004524 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004525 public void revokeRuntimePermissionsIfGroupChanged(
Winson14ff7172019-10-23 10:42:27 -07004526 @NonNull AndroidPackage newPackage,
4527 @NonNull AndroidPackage oldPackage,
Todd Kennedyc971a452019-07-08 16:04:52 -07004528 @NonNull ArrayList<String> allPackageNames) {
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004529 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
Todd Kennedyc971a452019-07-08 16:04:52 -07004530 oldPackage, allPackageNames, mDefaultPermissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004531 }
4532 @Override
Winson14ff7172019-10-23 10:42:27 -07004533 public void addAllPermissions(AndroidPackage pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004534 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004535 }
4536 @Override
Winson14ff7172019-10-23 10:42:27 -07004537 public void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07004538 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
4539 }
4540 @Override
Winson14ff7172019-10-23 10:42:27 -07004541 public void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
Hongming Jinae750fb2018-09-27 23:00:20 +00004542 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07004543 }
4544 @Override
Winson14ff7172019-10-23 10:42:27 -07004545 public void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
Todd Kennedyc971a452019-07-08 16:04:52 -07004546 String[] grantedPermissions, int callingUid) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004547 PermissionManagerService.this.grantRequestedRuntimePermissions(
Todd Kennedyc971a452019-07-08 16:04:52 -07004548 pkg, userIds, grantedPermissions, callingUid, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004549 }
4550 @Override
Winson14ff7172019-10-23 10:42:27 -07004551 public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004552 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
Todd Kennedyc971a452019-07-08 16:04:52 -07004553 @PackageManager.PermissionWhitelistFlags int flags) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004554 for (int userId : userIds) {
4555 setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
Todd Kennedyc971a452019-07-08 16:04:52 -07004556 callingUid, flags, mDefaultPermissionCallback);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004557 }
4558 }
4559 @Override
4560 public void setWhitelistedRestrictedPermissions(String packageName,
4561 List<String> permissions, int flags, int userId) {
4562 PermissionManagerService.this.setWhitelistedRestrictedPermissionsInternal(
4563 packageName, permissions, flags, userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004564 }
4565 @Override
Eugene Susla922cd082020-03-11 12:38:17 -07004566 public void setAutoRevokeWhitelisted(
4567 @NonNull String packageName, boolean whitelisted, int userId) {
4568 PermissionManagerService.this.setAutoRevokeWhitelisted(
4569 packageName, whitelisted, userId);
4570 }
4571 @Override
Winson14ff7172019-10-23 10:42:27 -07004572 public void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004573 PermissionManagerService.this
4574 .updatePermissions(packageName, pkg, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004575 }
4576 @Override
Todd Kennedyc971a452019-07-08 16:04:52 -07004577 public void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated) {
4578 PermissionManagerService.this
4579 .updateAllPermissions(volumeUuid, sdkUpdated, mDefaultPermissionCallback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004580 }
4581 @Override
Winson14ff7172019-10-23 10:42:27 -07004582 public void resetRuntimePermissions(AndroidPackage pkg, int userId) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004583 PermissionManagerService.this.resetRuntimePermissionsInternal(pkg, userId);
4584 }
4585 @Override
4586 public void resetAllRuntimePermissions(final int userId) {
4587 mPackageManagerInt.forEachPackage(
Winson14ff7172019-10-23 10:42:27 -07004588 (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
Todd Kennedy0eb97382017-10-03 16:57:22 -07004589 }
4590 @Override
Todd Kennedy8f135982019-07-02 07:35:15 -07004591 public String[] getAppOpPermissionPackages(String permName, int callingUid) {
4592 return PermissionManagerService.this
4593 .getAppOpPermissionPackagesInternal(permName, callingUid);
Todd Kennedyc8423932017-10-05 08:58:36 -07004594 }
4595 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004596 public void enforceCrossUserPermission(int callingUid, int userId,
4597 boolean requireFullPermission, boolean checkShell, String message) {
4598 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07004599 requireFullPermission, checkShell, false, message);
4600 }
4601 @Override
4602 public void enforceCrossUserPermission(int callingUid, int userId,
4603 boolean requireFullPermission, boolean checkShell,
4604 boolean requirePermissionWhenSameUser, String message) {
4605 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
4606 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004607 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004608
4609 @Override
4610 public void enforceCrossUserOrProfilePermission(int callingUid, int userId,
4611 boolean requireFullPermission, boolean checkShell, String message) {
kholoud mohamed79a89f02020-01-15 15:30:07 +00004612 PermissionManagerService.this.enforceCrossUserOrProfilePermission(
4613 callingUid,
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004614 userId,
4615 requireFullPermission,
4616 checkShell,
4617 message);
4618 }
4619
Todd Kennedy0eb97382017-10-03 16:57:22 -07004620 @Override
4621 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4622 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
4623 }
4624 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004625 public PermissionSettings getPermissionSettings() {
4626 return mSettings;
4627 }
4628 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004629 public BasePermission getPermissionTEMP(String permName) {
4630 synchronized (PermissionManagerService.this.mLock) {
4631 return mSettings.getPermissionLocked(permName);
4632 }
4633 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08004634
4635 @Override
Hai Zhang57bc3122019-10-21 16:04:15 -07004636 public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtection(
4637 @PermissionInfo.Protection int protection) {
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07004638 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
4639
4640 synchronized (PermissionManagerService.this.mLock) {
4641 int numTotalPermissions = mSettings.mPermissions.size();
4642
4643 for (int i = 0; i < numTotalPermissions; i++) {
4644 BasePermission bp = mSettings.mPermissions.valueAt(i);
4645
Winson655a5b92019-10-23 10:49:32 -07004646 if (bp.perm != null && bp.perm.getProtection() == protection) {
4647 matchingPermissions.add(
4648 PackageInfoUtils.generatePermissionInfo(bp.perm, 0));
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07004649 }
4650 }
4651 }
4652
4653 return matchingPermissions;
4654 }
4655
4656 @Override
Philip P. Moltmann48456672019-01-20 13:14:03 -08004657 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
4658 return PermissionManagerService.this.backupRuntimePermissions(user);
4659 }
4660
4661 @Override
4662 public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
4663 PermissionManagerService.this.restoreRuntimePermissions(backup, user);
4664 }
4665
4666 @Override
4667 public void restoreDelayedRuntimePermissions(@NonNull String packageName,
4668 @NonNull UserHandle user) {
4669 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
4670 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004671
4672 @Override
4673 public void addOnRuntimePermissionStateChangedListener(
4674 OnRuntimePermissionStateChangedListener listener) {
4675 PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
4676 listener);
4677 }
4678
4679 @Override
4680 public void removeOnRuntimePermissionStateChangedListener(
4681 OnRuntimePermissionStateChangedListener listener) {
4682 PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
4683 listener);
4684 }
Todd Kennedyca1ea172019-07-03 15:02:28 -07004685
4686 @Override
4687 public CheckPermissionDelegate getCheckPermissionDelegate() {
4688 synchronized (mLock) {
4689 return mCheckPermissionDelegate;
4690 }
4691 }
4692
4693 @Override
4694 public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
4695 synchronized (mLock) {
Daniel Colascionea3c6c092020-02-27 03:51:30 -08004696 if (delegate != null || mCheckPermissionDelegate != null) {
4697 PackageManager.invalidatePackageInfoCache();
4698 }
Todd Kennedyca1ea172019-07-03 15:02:28 -07004699 mCheckPermissionDelegate = delegate;
4700 }
4701 }
Todd Kennedy583378d2019-07-12 06:50:30 -07004702
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004703 @Override
Todd Kennedy583378d2019-07-12 06:50:30 -07004704 public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
4705 synchronized (mLock) {
4706 mDefaultBrowserProvider = provider;
4707 }
4708 }
4709
4710 @Override
4711 public void setDefaultBrowser(String packageName, boolean async, boolean doGrant,
4712 int userId) {
4713 setDefaultBrowserInternal(packageName, async, doGrant, userId);
4714 }
4715
4716 @Override
4717 public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
4718 synchronized (mLock) {
4719 mDefaultDialerProvider = provider;
4720 }
4721 }
4722
4723 @Override
4724 public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
4725 synchronized (mLock) {
4726 mDefaultHomeProvider = provider;
4727 }
4728 }
4729
4730 @Override
4731 public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004732 if (userId == UserHandle.USER_ALL) {
4733 return;
Todd Kennedy583378d2019-07-12 06:50:30 -07004734 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004735 DefaultHomeProvider provider;
4736 synchronized (mLock) {
4737 provider = mDefaultHomeProvider;
4738 }
4739 if (provider == null) {
4740 return;
4741 }
4742 provider.setDefaultHomeAsync(packageName, userId, callback);
Todd Kennedy583378d2019-07-12 06:50:30 -07004743 }
4744
4745 @Override
4746 public void setDialerAppPackagesProvider(PackagesProvider provider) {
4747 synchronized (mLock) {
4748 mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
4749 }
4750 }
4751
4752 @Override
4753 public void setLocationExtraPackagesProvider(PackagesProvider provider) {
4754 synchronized (mLock) {
4755 mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
4756 }
4757 }
4758
4759 @Override
4760 public void setLocationPackagesProvider(PackagesProvider provider) {
4761 synchronized (mLock) {
4762 mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
4763 }
4764 }
4765
4766 @Override
4767 public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
4768 synchronized (mLock) {
4769 mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
4770 }
4771 }
4772
4773 @Override
4774 public void setSmsAppPackagesProvider(PackagesProvider provider) {
4775 synchronized (mLock) {
4776 mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
4777 }
4778 }
4779
4780 @Override
4781 public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
4782 synchronized (mLock) {
4783 mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
4784 }
4785 }
4786
4787 @Override
4788 public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
4789 synchronized (mLock) {
4790 mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
4791 }
4792 }
4793
4794 @Override
4795 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
4796 synchronized (mLock) {
4797 mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
4798 }
4799 }
4800
4801 @Override
4802 public String getDefaultBrowser(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004803 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004804 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004805 provider = mDefaultBrowserProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004806 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004807 return provider != null ? provider.getDefaultBrowser(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004808 }
4809
4810 @Override
4811 public String getDefaultDialer(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004812 DefaultDialerProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004813 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004814 provider = mDefaultDialerProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004815 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004816 return provider != null ? provider.getDefaultDialer(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004817 }
4818
4819 @Override
4820 public String getDefaultHome(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004821 DefaultHomeProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004822 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004823 provider = mDefaultHomeProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004824 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004825 return provider != null ? provider.getDefaultHome(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004826 }
4827
4828 @Override
4829 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
4830 synchronized (mLock) {
4831 mDefaultPermissionGrantPolicy
4832 .grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
4833 }
4834 }
4835
4836 @Override
4837 public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
4838 synchronized (mLock) {
4839 mDefaultPermissionGrantPolicy
4840 .grantDefaultPermissionsToDefaultUseOpenWifiApp(packageName, userId);
4841 }
4842 }
4843
4844 @Override
4845 public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
4846 synchronized (mLock) {
4847 mDefaultPermissionGrantPolicy
4848 .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
4849 }
4850 }
4851
4852 @Override
Todd Kennedy583378d2019-07-12 06:50:30 -07004853 public void onNewUserCreated(int userId) {
Hai Zhang93236822020-01-09 13:15:17 -08004854 mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
Todd Kennedy583378d2019-07-12 06:50:30 -07004855 synchronized (mLock) {
Todd Kennedy583378d2019-07-12 06:50:30 -07004856 // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
4857 PermissionManagerService.this.updateAllPermissions(
4858 StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
4859 }
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004860 }
4861 }
4862
4863 private static final class OnPermissionChangeListeners extends Handler {
4864 private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
4865
4866 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
4867 new RemoteCallbackList<>();
4868
4869 OnPermissionChangeListeners(Looper looper) {
4870 super(looper);
4871 }
4872
4873 @Override
4874 public void handleMessage(Message msg) {
4875 switch (msg.what) {
4876 case MSG_ON_PERMISSIONS_CHANGED: {
4877 final int uid = msg.arg1;
4878 handleOnPermissionsChanged(uid);
4879 } break;
4880 }
4881 }
4882
4883 public void addListenerLocked(IOnPermissionsChangeListener listener) {
4884 mPermissionListeners.register(listener);
4885
4886 }
4887
4888 public void removeListenerLocked(IOnPermissionsChangeListener listener) {
4889 mPermissionListeners.unregister(listener);
4890 }
4891
4892 public void onPermissionsChanged(int uid) {
4893 if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
4894 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
4895 }
4896 }
4897
4898 private void handleOnPermissionsChanged(int uid) {
4899 final int count = mPermissionListeners.beginBroadcast();
4900 try {
4901 for (int i = 0; i < count; i++) {
4902 IOnPermissionsChangeListener callback = mPermissionListeners
4903 .getBroadcastItem(i);
4904 try {
4905 callback.onPermissionsChanged(uid);
4906 } catch (RemoteException e) {
4907 Log.e(TAG, "Permission listener is dead", e);
4908 }
4909 }
4910 } finally {
4911 mPermissionListeners.finishBroadcast();
4912 }
4913 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07004914 }
Michael Groover56a84b22020-03-04 20:41:36 -08004915
4916 /**
4917 * Allows injection of services and method responses to facilitate testing.
4918 *
4919 * <p>Test classes can create a mock of this class and pass it to the PermissionManagerService
4920 * constructor to control behavior of services and external methods during execution.
4921 * @hide
4922 */
4923 @VisibleForTesting
4924 public static class Injector {
4925 private final Context mContext;
4926
4927 /**
4928 * Public constructor that accepts a {@code context} within which to operate.
4929 */
4930 public Injector(@NonNull Context context) {
4931 mContext = context;
4932 }
4933
4934 /**
4935 * Returns the UID of the calling package.
4936 */
4937 public int getCallingUid() {
4938 return Binder.getCallingUid();
4939 }
4940
4941 /**
4942 * Returns the process ID of the calling package.
4943 */
4944 public int getCallingPid() {
4945 return Binder.getCallingPid();
4946 }
4947
4948 /**
4949 * Invalidates the package info cache.
4950 */
4951 public void invalidatePackageInfoCache() {
4952 PackageManager.invalidatePackageInfoCache();
4953 }
4954
4955 /**
4956 * Disables the permission cache.
4957 */
4958 public void disablePermissionCache() {
4959 PermissionManager.disablePermissionCache();
4960 }
4961
4962 /**
4963 * Disables the package name permission cache.
4964 */
4965 public void disablePackageNamePermissionCache() {
4966 PermissionManager.disablePackageNamePermissionCache();
4967 }
4968
4969 /**
4970 * Checks if the package running under the specified {@code pid} and {@code uid} has been
4971 * granted the provided {@code permission}.
4972 *
4973 * @return {@link PackageManager#PERMISSION_GRANTED} if the package has been granted the
4974 * permission, {@link PackageManager#PERMISSION_DENIED} otherwise
4975 */
4976 public int checkPermission(@NonNull String permission, int pid, int uid) {
4977 return mContext.checkPermission(permission, pid, uid);
4978 }
4979
4980 /**
4981 * Clears the calling identity to allow subsequent calls to be treated as coming from this
4982 * package.
4983 *
4984 * @return a token that can be used to restore the calling identity
4985 */
4986 public long clearCallingIdentity() {
4987 return Binder.clearCallingIdentity();
4988 }
4989
4990 /**
4991 * Restores the calling identity to that of the calling package based on the provided
4992 * {@code token}.
4993 */
4994 public void restoreCallingIdentity(long token) {
4995 Binder.restoreCallingIdentity(token);
4996 }
4997
4998 /**
4999 * Returns the system service with the provided {@code name}.
5000 */
5001 public Object getSystemService(@NonNull String name) {
5002 return mContext.getSystemService(name);
5003 }
5004 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07005005}