blob: c5d38db2c469886a706d30b82759a865333a7570 [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
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -070019import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION;
Todd Kennedy0eb97382017-10-03 16:57:22 -070020import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
21import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070022import static android.app.AppOpsManager.MODE_ALLOWED;
23import static android.app.AppOpsManager.MODE_DEFAULT;
24import static android.app.AppOpsManager.MODE_ERRORED;
25import static android.app.AppOpsManager.MODE_FOREGROUND;
26import static android.app.AppOpsManager.MODE_IGNORED;
27import static android.app.AppOpsManager.OP_NONE;
28import static android.app.AppOpsManager.permissionToOp;
29import static android.app.AppOpsManager.permissionToOpCode;
30import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
31import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
Todd Kennedy3bc94722017-10-10 09:55:53 -070033import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070034import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Hongwei Wangf391b552018-04-06 13:52:46 -070038import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070039import static android.os.UserHandle.getAppId;
40import static android.os.UserHandle.getUid;
Hongwei Wangf391b552018-04-06 13:52:46 -070041
Todd Kennedyc29b11a2017-10-23 15:55:59 -070042import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
43import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
44import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
45import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
46import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Todd Kennedy0eb97382017-10-03 16:57:22 -070047
48import android.Manifest;
49import android.annotation.NonNull;
50import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070051import android.annotation.UserIdInt;
52import android.app.AppOpsManager;
53import android.app.AppOpsManagerInternal;
Todd Kennedy0eb97382017-10-03 16:57:22 -070054import android.content.Context;
55import android.content.pm.PackageManager;
56import android.content.pm.PackageManagerInternal;
57import android.content.pm.PackageParser;
Hongwei Wangf391b552018-04-06 13:52:46 -070058import android.content.pm.PackageParser.Package;
Todd Kennedy460f28c2017-10-06 13:46:22 -070059import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070060import android.content.pm.PermissionInfo;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070061import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070062import android.os.Binder;
63import android.os.Build;
64import android.os.Handler;
65import android.os.HandlerThread;
66import android.os.Process;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070067import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070068import android.os.UserHandle;
69import android.os.UserManager;
70import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070071import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070072import android.os.storage.StorageManagerInternal;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070073import android.permission.PermissionManager;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070074import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070075import android.util.ArrayMap;
76import android.util.ArraySet;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -070077import android.util.EventLog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070078import android.util.Log;
79import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -070080import android.util.SparseArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -070081
Todd Kennedyc29b11a2017-10-23 15:55:59 -070082import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -070083import com.android.internal.logging.MetricsLogger;
84import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070085import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -070086import com.android.internal.util.ArrayUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070087import com.android.server.LocalServices;
88import com.android.server.ServiceThread;
89import com.android.server.SystemConfig;
90import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070091import com.android.server.pm.PackageManagerServiceUtils;
92import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -070093import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -070094import com.android.server.pm.UserManagerService;
Hongwei Wangf391b552018-04-06 13:52:46 -070095import com.android.server.pm.permission.DefaultPermissionGrantPolicy
96 .DefaultPermissionGrantedCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -070097import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
98import com.android.server.pm.permission.PermissionsState.PermissionState;
99
100import libcore.util.EmptyArray;
101
102import java.util.ArrayList;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700103import java.util.Collection;
Hongwei Wangf391b552018-04-06 13:52:46 -0700104import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700105import java.util.Iterator;
106import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700107import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700108import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700109import java.util.Set;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700110
111/**
112 * Manages all permissions and handles permissions related tasks.
113 */
114public class PermissionManagerService {
115 private static final String TAG = "PackageManager";
116
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700117 /** Permission grant: not grant the permission. */
118 private static final int GRANT_DENIED = 1;
119 /** Permission grant: grant the permission as an install permission. */
120 private static final int GRANT_INSTALL = 2;
121 /** Permission grant: grant the permission as a runtime one. */
122 private static final int GRANT_RUNTIME = 3;
123 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
124 private static final int GRANT_UPGRADE = 4;
125
126 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
127 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
128 /** Empty array to avoid allocations */
129 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700130
Hongwei Wangf391b552018-04-06 13:52:46 -0700131 /** If the permission of the value is granted, so is the key */
132 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
133
134 static {
135 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
136 Manifest.permission.ACCESS_FINE_LOCATION);
137 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
138 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
139 }
140
Todd Kennedy0eb97382017-10-03 16:57:22 -0700141 /** Lock to protect internal data access */
142 private final Object mLock;
143
144 /** Internal connection to the package manager */
145 private final PackageManagerInternal mPackageManagerInt;
146
147 /** Internal connection to the user manager */
148 private final UserManagerInternal mUserManagerInt;
149
150 /** Default permission policy to provide proper behaviour out-of-the-box */
151 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
152
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700153 /**
154 * Built-in permissions. Read from system configuration files. Mapping is from
155 * UID to permission name.
156 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700157 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700158
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700159 /** Built-in group IDs given to all packages. Read from system configuration files. */
160 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700161
162 private final HandlerThread mHandlerThread;
163 private final Handler mHandler;
164 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700165 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700166
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700167 /** Internal storage for permissions and related settings */
168 @GuardedBy("mLock")
169 private final PermissionSettings mSettings;
170
171 @GuardedBy("mLock")
172 private ArraySet<String> mPrivappPermissionsViolations;
173
174 @GuardedBy("mLock")
175 private boolean mSystemReady;
176
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700177 /**
178 * For each foreground/background permission the mapping:
179 * Background permission -> foreground permissions
180 */
181 @GuardedBy("mLock")
182 private ArrayMap<String, List<String>> mBackgroundPermissions;
183
Todd Kennedy0eb97382017-10-03 16:57:22 -0700184 PermissionManagerService(Context context,
185 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
186 @NonNull Object externalLock) {
187 mContext = context;
188 mLock = externalLock;
189 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
190 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700191 mSettings = new PermissionSettings(mLock);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700192
193 mHandlerThread = new ServiceThread(TAG,
194 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
195 mHandlerThread.start();
196 mHandler = new Handler(mHandlerThread.getLooper());
197 Watchdog.getInstance().addThread(mHandler);
198
199 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
200 context, mHandlerThread.getLooper(), defaultGrantCallback, this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700201 SystemConfig systemConfig = SystemConfig.getInstance();
202 mSystemPermissions = systemConfig.getSystemPermissions();
203 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700204
205 // propagate permission configuration
206 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
207 SystemConfig.getInstance().getPermissions();
208 synchronized (mLock) {
209 for (int i=0; i<permConfig.size(); i++) {
210 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
211 BasePermission bp = mSettings.getPermissionLocked(perm.name);
212 if (bp == null) {
213 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
214 mSettings.putPermissionLocked(perm.name, bp);
215 }
216 if (perm.gids != null) {
217 bp.setGids(perm.gids, perm.perUser);
218 }
219 }
220 }
221
222 LocalServices.addService(
223 PermissionManagerInternal.class, new PermissionManagerInternalImpl());
224 }
225
226 /**
227 * Creates and returns an initialized, internal service for use by other components.
228 * <p>
229 * The object returned is identical to the one returned by the LocalServices class using:
230 * {@code LocalServices.getService(PermissionManagerInternal.class);}
231 * <p>
232 * NOTE: The external lock is temporary and should be removed. This needs to be a
233 * lock created by the permission manager itself.
234 */
235 public static PermissionManagerInternal create(Context context,
236 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
237 @NonNull Object externalLock) {
238 final PermissionManagerInternal permMgrInt =
239 LocalServices.getService(PermissionManagerInternal.class);
240 if (permMgrInt != null) {
241 return permMgrInt;
242 }
243 new PermissionManagerService(context, defaultGrantCallback, externalLock);
244 return LocalServices.getService(PermissionManagerInternal.class);
245 }
246
247 @Nullable BasePermission getPermission(String permName) {
248 synchronized (mLock) {
249 return mSettings.getPermissionLocked(permName);
250 }
251 }
252
253 private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
254 if (!mUserManagerInt.exists(userId)) {
255 return PackageManager.PERMISSION_DENIED;
256 }
257
Patrick Baumann97b9b532018-04-11 14:51:30 +0000258 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
259 if (pkg != null && pkg.mExtras != null) {
260 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700261 return PackageManager.PERMISSION_DENIED;
262 }
Patrick Baumann97b9b532018-04-11 14:51:30 +0000263 final PackageSetting ps = (PackageSetting) pkg.mExtras;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700264 final boolean instantApp = ps.getInstantApp(userId);
265 final PermissionsState permissionsState = ps.getPermissionsState();
266 if (permissionsState.hasPermission(permName, userId)) {
267 if (instantApp) {
268 synchronized (mLock) {
269 BasePermission bp = mSettings.getPermissionLocked(permName);
270 if (bp != null && bp.isInstant()) {
271 return PackageManager.PERMISSION_GRANTED;
272 }
273 }
274 } else {
275 return PackageManager.PERMISSION_GRANTED;
276 }
277 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700278 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700279 return PackageManager.PERMISSION_GRANTED;
280 }
281 }
282
283 return PackageManager.PERMISSION_DENIED;
284 }
285
Todd Kennedy3c714492017-10-27 09:12:50 -0700286 private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
287 int callingUid) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700288 final int callingUserId = UserHandle.getUserId(callingUid);
289 final boolean isCallerInstantApp =
290 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
291 final boolean isUidInstantApp =
292 mPackageManagerInt.getInstantAppPackageName(uid) != null;
293 final int userId = UserHandle.getUserId(uid);
294 if (!mUserManagerInt.exists(userId)) {
295 return PackageManager.PERMISSION_DENIED;
296 }
297
Todd Kennedy3c714492017-10-27 09:12:50 -0700298 if (pkg != null) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700299 if (pkg.mSharedUserId != null) {
300 if (isCallerInstantApp) {
301 return PackageManager.PERMISSION_DENIED;
302 }
Todd Kennedy3c714492017-10-27 09:12:50 -0700303 } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
304 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700305 }
306 final PermissionsState permissionsState =
307 ((PackageSetting) pkg.mExtras).getPermissionsState();
308 if (permissionsState.hasPermission(permName, userId)) {
309 if (isUidInstantApp) {
310 if (mSettings.isPermissionInstant(permName)) {
311 return PackageManager.PERMISSION_GRANTED;
312 }
313 } else {
314 return PackageManager.PERMISSION_GRANTED;
315 }
316 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700317 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700318 return PackageManager.PERMISSION_GRANTED;
319 }
320 } else {
321 ArraySet<String> perms = mSystemPermissions.get(uid);
322 if (perms != null) {
323 if (perms.contains(permName)) {
324 return PackageManager.PERMISSION_GRANTED;
325 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700326 if (FULLER_PERMISSION_MAP.containsKey(permName)
327 && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700328 return PackageManager.PERMISSION_GRANTED;
329 }
330 }
331 }
332 return PackageManager.PERMISSION_DENIED;
333 }
334
Hongwei Wangf391b552018-04-06 13:52:46 -0700335 /**
336 * Returns {@code true} if the permission can be implied from another granted permission.
337 * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
338 * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
339 * it access to any implied permissions.
340 */
341 private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
342 String permName, int userId) {
343 return FULLER_PERMISSION_MAP.containsKey(permName)
344 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
345 }
346
Todd Kennedy460f28c2017-10-06 13:46:22 -0700347 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
348 int callingUid) {
349 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
350 return null;
351 }
352 synchronized (mLock) {
353 return PackageParser.generatePermissionGroupInfo(
354 mSettings.mPermissionGroups.get(groupName), flags);
355 }
356 }
357
358 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
359 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
360 return null;
361 }
362 synchronized (mLock) {
363 final int N = mSettings.mPermissionGroups.size();
364 final ArrayList<PermissionGroupInfo> out
365 = new ArrayList<PermissionGroupInfo>(N);
366 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
367 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
368 }
369 return out;
370 }
371 }
372
373 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700374 int callingUid) {
375 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
376 return null;
377 }
378 // reader
379 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700380 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700381 if (bp == null) {
382 return null;
383 }
384 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
385 bp.getProtectionLevel(), packageName, callingUid);
386 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
387 }
388 }
389
390 private List<PermissionInfo> getPermissionInfoByGroup(
391 String groupName, int flags, int callingUid) {
392 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
393 return null;
394 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700395 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700396 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
397 return null;
398 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700399 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
Todd Kennedyc8423932017-10-05 08:58:36 -0700400 for (BasePermission bp : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700401 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
402 if (pi != null) {
403 out.add(pi);
404 }
405 }
406 return out;
407 }
408 }
409
410 private int adjustPermissionProtectionFlagsLocked(
411 int protectionLevel, String packageName, int uid) {
412 // Signature permission flags area always reported
413 final int protectionLevelMasked = protectionLevel
414 & (PermissionInfo.PROTECTION_NORMAL
415 | PermissionInfo.PROTECTION_DANGEROUS
416 | PermissionInfo.PROTECTION_SIGNATURE);
417 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
418 return protectionLevel;
419 }
420 // System sees all flags.
421 final int appId = UserHandle.getAppId(uid);
422 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
423 || appId == Process.SHELL_UID) {
424 return protectionLevel;
425 }
426 // Normalize package name to handle renamed packages and static libs
427 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
428 if (pkg == null) {
429 return protectionLevel;
430 }
431 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
432 return protectionLevelMasked;
433 }
434 // Apps that target O see flags for all protection levels.
435 final PackageSetting ps = (PackageSetting) pkg.mExtras;
436 if (ps == null) {
437 return protectionLevel;
438 }
439 if (ps.getAppId() != appId) {
440 return protectionLevel;
441 }
442 return protectionLevel;
443 }
444
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700445 /**
446 * We might auto-grant permissions if any permission of the group is already granted. Hence if
447 * the group of a granted permission changes we need to revoke it to avoid having permissions of
448 * the new group auto-granted.
449 *
450 * @param newPackage The new package that was installed
451 * @param oldPackage The old package that was updated
452 * @param allPackageNames All package names
453 * @param permissionCallback Callback for permission changed
454 */
455 private void revokeRuntimePermissionsIfGroupChanged(
456 @NonNull PackageParser.Package newPackage,
457 @NonNull PackageParser.Package oldPackage,
458 @NonNull ArrayList<String> allPackageNames,
459 @NonNull PermissionCallback permissionCallback) {
460 final int numOldPackagePermissions = oldPackage.permissions.size();
461 final ArrayMap<String, String> oldPermissionNameToGroupName
462 = new ArrayMap<>(numOldPackagePermissions);
463
464 for (int i = 0; i < numOldPackagePermissions; i++) {
465 final PackageParser.Permission permission = oldPackage.permissions.get(i);
466
467 if (permission.group != null) {
468 oldPermissionNameToGroupName.put(permission.info.name,
469 permission.group.info.name);
470 }
471 }
472
473 final int numNewPackagePermissions = newPackage.permissions.size();
474 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
475 newPermissionNum++) {
476 final PackageParser.Permission newPermission =
477 newPackage.permissions.get(newPermissionNum);
478 final int newProtection = newPermission.info.getProtection();
479
480 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
481 final String permissionName = newPermission.info.name;
482 final String newPermissionGroupName =
483 newPermission.group == null ? null : newPermission.group.info.name;
484 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
485 permissionName);
486
487 if (newPermissionGroupName != null
488 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
489 final int[] userIds = mUserManagerInt.getUserIds();
490 final int numUserIds = userIds.length;
491 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
492 final int userId = userIds[userIdNum];
493
494 final int numPackages = allPackageNames.size();
495 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
496 final String packageName = allPackageNames.get(packageNum);
497
498 if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
499 userId) == PackageManager.PERMISSION_GRANTED) {
500 EventLog.writeEvent(0x534e4554, "72710897",
501 newPackage.applicationInfo.uid,
Koji Fukuiacae3ef2018-05-09 11:38:01 +0900502 "Revoking permission " + permissionName +
503 " from package " + packageName +
504 " as the group changed from " + oldPermissionGroupName +
505 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700506
507 try {
Hongming Jinae750fb2018-09-27 23:00:20 +0000508 revokeRuntimePermission(permissionName, packageName, false,
509 Process.SYSTEM_UID, userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700510 } catch (IllegalArgumentException e) {
511 Slog.e(TAG, "Could not revoke " + permissionName + " from "
512 + packageName, e);
513 }
514 }
515 }
516 }
517 }
518 }
519 }
520 }
521
Todd Kennedyc8423932017-10-05 08:58:36 -0700522 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
523 final int N = pkg.permissions.size();
524 for (int i=0; i<N; i++) {
525 PackageParser.Permission p = pkg.permissions.get(i);
526
527 // Assume by default that we did not install this permission into the system.
528 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
529
Todd Kennedyc8423932017-10-05 08:58:36 -0700530 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700531 // Now that permission groups have a special meaning, we ignore permission
532 // groups for legacy apps to prevent unexpected behavior. In particular,
533 // permissions for one app being granted to someone just because they happen
534 // to be in a group defined by another app (before this had no implications).
535 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
536 p.group = mSettings.mPermissionGroups.get(p.info.group);
537 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700538 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -0700539 && p.info.group != null && p.group == null) {
540 Slog.i(TAG, "Permission " + p.info.name + " from package "
541 + p.info.packageName + " in an unknown group " + p.info.group);
542 }
543 }
544
Todd Kennedyc8423932017-10-05 08:58:36 -0700545 if (p.tree) {
546 final BasePermission bp = BasePermission.createOrUpdate(
547 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
548 mSettings.getAllPermissionTreesLocked(), chatty);
549 mSettings.putPermissionTreeLocked(p.info.name, bp);
550 } else {
551 final BasePermission bp = BasePermission.createOrUpdate(
552 mSettings.getPermissionLocked(p.info.name),
553 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
554 mSettings.putPermissionLocked(p.info.name, bp);
555 }
556 }
557 }
558 }
559
Todd Kennedy460f28c2017-10-06 13:46:22 -0700560 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
561 final int N = pkg.permissionGroups.size();
562 StringBuilder r = null;
563 for (int i=0; i<N; i++) {
564 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
565 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
566 final String curPackageName = (cur == null) ? null : cur.info.packageName;
567 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
568 if (cur == null || isPackageUpdate) {
569 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700570 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700571 if (r == null) {
572 r = new StringBuilder(256);
573 } else {
574 r.append(' ');
575 }
576 if (isPackageUpdate) {
577 r.append("UPD:");
578 }
579 r.append(pg.info.name);
580 }
581 } else {
582 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
583 + pg.info.packageName + " ignored: original from "
584 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700585 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700586 if (r == null) {
587 r = new StringBuilder(256);
588 } else {
589 r.append(' ');
590 }
591 r.append("DUP:");
592 r.append(pg.info.name);
593 }
594 }
595 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700596 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700597 Log.d(TAG, " Permission Groups: " + r);
598 }
599
600 }
601
Hongming Jinae750fb2018-09-27 23:00:20 +0000602 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700603 synchronized (mLock) {
604 int N = pkg.permissions.size();
605 StringBuilder r = null;
606 for (int i=0; i<N; i++) {
607 PackageParser.Permission p = pkg.permissions.get(i);
608 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
609 if (bp == null) {
610 bp = mSettings.mPermissionTrees.get(p.info.name);
611 }
612 if (bp != null && bp.isPermission(p)) {
613 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700614 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700615 if (r == null) {
616 r = new StringBuilder(256);
617 } else {
618 r.append(' ');
619 }
620 r.append(p.info.name);
621 }
622 }
623 if (p.isAppOp()) {
624 ArraySet<String> appOpPkgs =
625 mSettings.mAppOpPermissionPackages.get(p.info.name);
626 if (appOpPkgs != null) {
627 appOpPkgs.remove(pkg.packageName);
628 }
629 }
630 }
631 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700632 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700633 }
634
635 N = pkg.requestedPermissions.size();
636 r = null;
637 for (int i=0; i<N; i++) {
638 String perm = pkg.requestedPermissions.get(i);
639 if (mSettings.isPermissionAppOp(perm)) {
640 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
641 if (appOpPkgs != null) {
642 appOpPkgs.remove(pkg.packageName);
643 if (appOpPkgs.isEmpty()) {
644 mSettings.mAppOpPermissionPackages.remove(perm);
645 }
646 }
647 }
648 }
649 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700650 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700651 }
652 }
653 }
654
655 private boolean addDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700656 PermissionInfo info, int callingUid, PermissionCallback callback) {
657 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
658 throw new SecurityException("Instant apps can't add permissions");
659 }
660 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
661 throw new SecurityException("Label must be specified in permission");
662 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700663 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700664 final boolean added;
665 final boolean changed;
666 synchronized (mLock) {
667 BasePermission bp = mSettings.getPermissionLocked(info.name);
668 added = bp == null;
669 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
670 if (added) {
671 enforcePermissionCapLocked(info, tree);
672 bp = new BasePermission(info.name, tree.getSourcePackageName(),
673 BasePermission.TYPE_DYNAMIC);
Svet Ganov2808cbc2018-05-09 15:27:43 -0700674 } else if (!bp.isDynamic()) {
675 throw new SecurityException("Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700676 + info.name);
677 }
678 changed = bp.addToTree(fixedLevel, info, tree);
679 if (added) {
680 mSettings.putPermissionLocked(info.name, bp);
681 }
682 }
683 if (changed && callback != null) {
684 callback.onPermissionChanged();
685 }
686 return added;
687 }
688
Todd Kennedyc8423932017-10-05 08:58:36 -0700689 private void removeDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700690 String permName, int callingUid, PermissionCallback callback) {
691 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
692 throw new SecurityException("Instant applications don't have access to this method");
693 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700694 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700695 synchronized (mLock) {
696 final BasePermission bp = mSettings.getPermissionLocked(permName);
697 if (bp == null) {
698 return;
699 }
700 if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600701 // TODO: switch this back to SecurityException
702 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700703 + permName);
704 }
705 mSettings.removePermissionLocked(permName);
706 if (callback != null) {
707 callback.onPermissionRemoved();
708 }
709 }
710 }
711
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -0700712 /**
713 * Restore the permission state for a package.
714 *
715 * <ul>
716 * <li>During boot the state gets restored from the disk</li>
717 * <li>During app update the state gets restored from the last version of the app</li>
718 * </ul>
719 *
720 * <p>This restores the permission state for all users.
721 *
722 * @param pkg the package the permissions belong to
723 * @param replace if the package is getting replaced (this might change the requested
724 * permissions of this package)
725 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
726 * @param callback Result call back
727 */
728 private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
729 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700730 // IMPORTANT: There are two types of permissions: install and runtime.
731 // Install time permissions are granted when the app is installed to
732 // all device users and users added in the future. Runtime permissions
733 // are granted at runtime explicitly to specific users. Normal and signature
734 // protected permissions are install time permissions. Dangerous permissions
735 // are install permissions if the app's target SDK is Lollipop MR1 or older,
736 // otherwise they are runtime permissions. This function does not manage
737 // runtime permissions except for the case an app targeting Lollipop MR1
738 // being upgraded to target a newer SDK, in which case dangerous permissions
739 // are transformed from install time to runtime ones.
740
741 final PackageSetting ps = (PackageSetting) pkg.mExtras;
742 if (ps == null) {
743 return;
744 }
745 final boolean isLegacySystemApp = mPackageManagerInt.isLegacySystemApp(pkg);
746
747 final PermissionsState permissionsState = ps.getPermissionsState();
748 PermissionsState origPermissions = permissionsState;
749
750 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
751
752 boolean runtimePermissionsRevoked = false;
753 int[] updatedUserIds = EMPTY_INT_ARRAY;
754
755 boolean changedInstallPermission = false;
756
757 if (replace) {
758 ps.setInstallPermissionsFixed(false);
759 if (!ps.isSharedUser()) {
760 origPermissions = new PermissionsState(permissionsState);
761 permissionsState.reset();
762 } else {
763 // We need to know only about runtime permission changes since the
764 // calling code always writes the install permissions state but
765 // the runtime ones are written only if changed. The only cases of
766 // changed runtime permissions here are promotion of an install to
767 // runtime and revocation of a runtime from a shared user.
768 synchronized (mLock) {
769 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
770 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
771 if (!ArrayUtils.isEmpty(updatedUserIds)) {
772 runtimePermissionsRevoked = true;
773 }
774 }
775 }
776 }
777
778 permissionsState.setGlobalGids(mGlobalGids);
779
780 synchronized (mLock) {
781 final int N = pkg.requestedPermissions.size();
782 for (int i = 0; i < N; i++) {
783 final String permName = pkg.requestedPermissions.get(i);
784 final BasePermission bp = mSettings.getPermissionLocked(permName);
785 final boolean appSupportsRuntimePermissions =
786 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
787
788 if (DEBUG_INSTALL) {
789 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
790 }
791
792 if (bp == null || bp.getSourcePackageSetting() == null) {
793 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
794 if (DEBUG_PERMISSIONS) {
795 Slog.i(TAG, "Unknown permission " + permName
796 + " in package " + pkg.packageName);
797 }
798 }
799 continue;
800 }
801
802 // Limit ephemeral apps to ephemeral allowed permissions.
803 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
804 if (DEBUG_PERMISSIONS) {
805 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
806 + " for package " + pkg.packageName);
807 }
808 continue;
809 }
810
811 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
812 if (DEBUG_PERMISSIONS) {
813 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
814 + " for package " + pkg.packageName);
815 }
816 continue;
817 }
818
819 final String perm = bp.getName();
820 boolean allowedSig = false;
821 int grant = GRANT_DENIED;
822
823 // Keep track of app op permissions.
824 if (bp.isAppOp()) {
825 mSettings.addAppOpPackage(perm, pkg.packageName);
826 }
827
828 if (bp.isNormal()) {
829 // For all apps normal permissions are install time ones.
830 grant = GRANT_INSTALL;
831 } else if (bp.isRuntime()) {
832 // If a permission review is required for legacy apps we represent
833 // their permissions as always granted runtime ones since we need
834 // to keep the review required permission flag per user while an
835 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700836 if (origPermissions.hasInstallPermission(bp.getName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700837 // For legacy apps that became modern, install becomes runtime.
838 grant = GRANT_UPGRADE;
839 } else if (isLegacySystemApp) {
840 // For legacy system apps, install becomes runtime.
841 // We cannot check hasInstallPermission() for system apps since those
842 // permissions were granted implicitly and not persisted pre-M.
843 grant = GRANT_UPGRADE;
844 } else {
845 // For modern apps keep runtime permissions unchanged.
846 grant = GRANT_RUNTIME;
847 }
848 } else if (bp.isSignature()) {
849 // For all apps signature permissions are install time ones.
850 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
851 if (allowedSig) {
852 grant = GRANT_INSTALL;
853 }
854 }
855
856 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -0700857 Slog.i(TAG, "Considering granting permission " + perm + " to package "
858 + pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700859 }
860
861 if (grant != GRANT_DENIED) {
862 if (!ps.isSystem() && ps.areInstallPermissionsFixed()) {
863 // If this is an existing, non-system package, then
864 // we can't add any new permissions to it.
865 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
866 // Except... if this is a permission that was added
867 // to the platform (note: need to only do this when
868 // updating the platform).
869 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
870 grant = GRANT_DENIED;
871 }
872 }
873 }
874
875 switch (grant) {
876 case GRANT_INSTALL: {
877 // Revoke this as runtime permission to handle the case of
878 // a runtime permission being downgraded to an install one.
879 // Also in permission review mode we keep dangerous permissions
880 // for legacy apps
881 for (int userId : UserManagerService.getInstance().getUserIds()) {
882 if (origPermissions.getRuntimePermissionState(
883 perm, userId) != null) {
884 // Revoke the runtime permission and clear the flags.
885 origPermissions.revokeRuntimePermission(bp, userId);
886 origPermissions.updatePermissionFlags(bp, userId,
887 PackageManager.MASK_PERMISSION_FLAGS, 0);
888 // If we revoked a permission permission, we have to write.
889 updatedUserIds = ArrayUtils.appendInt(
890 updatedUserIds, userId);
891 }
892 }
893 // Grant an install permission.
894 if (permissionsState.grantInstallPermission(bp) !=
895 PermissionsState.PERMISSION_OPERATION_FAILURE) {
896 changedInstallPermission = true;
897 }
898 } break;
899
900 case GRANT_RUNTIME: {
901 // Grant previously granted runtime permissions.
902 for (int userId : UserManagerService.getInstance().getUserIds()) {
903 final PermissionState permissionState = origPermissions
904 .getRuntimePermissionState(perm, userId);
905 int flags = permissionState != null
906 ? permissionState.getFlags() : 0;
907 if (origPermissions.hasRuntimePermission(perm, userId)) {
908 // Don't propagate the permission in a permission review
909 // mode if the former was revoked, i.e. marked to not
910 // propagate on upgrade. Note that in a permission review
911 // mode install permissions are represented as constantly
912 // granted runtime ones since we need to keep a per user
913 // state associated with the permission. Also the revoke
914 // on upgrade flag is no longer applicable and is reset.
915 final boolean revokeOnUpgrade = (flags & PackageManager
916 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
917 if (revokeOnUpgrade) {
918 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
919 // Since we changed the flags, we have to write.
920 updatedUserIds = ArrayUtils.appendInt(
921 updatedUserIds, userId);
922 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700923 if (!revokeOnUpgrade) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700924 if (permissionsState.grantRuntimePermission(bp, userId) ==
925 PermissionsState.PERMISSION_OPERATION_FAILURE) {
926 // If we cannot put the permission as it was,
927 // we have to write.
928 updatedUserIds = ArrayUtils.appendInt(
929 updatedUserIds, userId);
930 }
931 }
932
933 // If the app supports runtime permissions no need for a review.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700934 if (appSupportsRuntimePermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700935 && (flags & PackageManager
936 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
937 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
938 // Since we changed the flags, we have to write.
939 updatedUserIds = ArrayUtils.appendInt(
940 updatedUserIds, userId);
941 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700942 } else if (!appSupportsRuntimePermissions) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700943 // For legacy apps that need a permission review, every new
944 // runtime permission is granted but it is pending a review.
945 // We also need to review only platform defined runtime
946 // permissions as these are the only ones the platform knows
947 // how to disable the API to simulate revocation as legacy
948 // apps don't expect to run with revoked permissions.
949 if (PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName())) {
950 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
951 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
952 // We changed the flags, hence have to write.
953 updatedUserIds = ArrayUtils.appendInt(
954 updatedUserIds, userId);
955 }
956 }
957 if (permissionsState.grantRuntimePermission(bp, userId)
958 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
959 // We changed the permission, hence have to write.
960 updatedUserIds = ArrayUtils.appendInt(
961 updatedUserIds, userId);
962 }
963 }
964 // Propagate the permission flags.
965 permissionsState.updatePermissionFlags(bp, userId, flags, flags);
966 }
967 } break;
968
969 case GRANT_UPGRADE: {
970 // Grant runtime permissions for a previously held install permission.
971 final PermissionState permissionState = origPermissions
972 .getInstallPermissionState(perm);
973 final int flags =
974 (permissionState != null) ? permissionState.getFlags() : 0;
975
976 if (origPermissions.revokeInstallPermission(bp)
977 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
978 // We will be transferring the permission flags, so clear them.
979 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
980 PackageManager.MASK_PERMISSION_FLAGS, 0);
981 changedInstallPermission = true;
982 }
983
984 // If the permission is not to be promoted to runtime we ignore it and
985 // also its other flags as they are not applicable to install permissions.
986 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
987 for (int userId : currentUserIds) {
988 if (permissionsState.grantRuntimePermission(bp, userId) !=
989 PermissionsState.PERMISSION_OPERATION_FAILURE) {
990 // Transfer the permission flags.
991 permissionsState.updatePermissionFlags(bp, userId,
992 flags, flags);
993 // If we granted the permission, we have to write.
994 updatedUserIds = ArrayUtils.appendInt(
995 updatedUserIds, userId);
996 }
997 }
998 }
999 } break;
1000
1001 default: {
1002 if (packageOfInterest == null
1003 || packageOfInterest.equals(pkg.packageName)) {
1004 if (DEBUG_PERMISSIONS) {
1005 Slog.i(TAG, "Not granting permission " + perm
1006 + " to package " + pkg.packageName
1007 + " because it was previously installed without");
1008 }
1009 }
1010 } break;
1011 }
1012 } else {
1013 if (permissionsState.revokeInstallPermission(bp) !=
1014 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1015 // Also drop the permission flags.
1016 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1017 PackageManager.MASK_PERMISSION_FLAGS, 0);
1018 changedInstallPermission = true;
1019 Slog.i(TAG, "Un-granting permission " + perm
1020 + " from package " + pkg.packageName
1021 + " (protectionLevel=" + bp.getProtectionLevel()
1022 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1023 + ")");
1024 } else if (bp.isAppOp()) {
1025 // Don't print warning for app op permissions, since it is fine for them
1026 // not to be granted, there is a UI for the user to decide.
1027 if (DEBUG_PERMISSIONS
1028 && (packageOfInterest == null
1029 || packageOfInterest.equals(pkg.packageName))) {
1030 Slog.i(TAG, "Not granting permission " + perm
1031 + " to package " + pkg.packageName
1032 + " (protectionLevel=" + bp.getProtectionLevel()
1033 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1034 + ")");
1035 }
1036 }
1037 }
1038 }
1039
1040 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
1041 !ps.isSystem() || ps.isUpdatedSystem()) {
1042 // This is the first that we have heard about this package, so the
1043 // permissions we have now selected are fixed until explicitly
1044 // changed.
1045 ps.setInstallPermissionsFixed(true);
1046 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001047
1048 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
1049 updatedUserIds);
1050 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
1051 permissionsState, pkg, updatedUserIds);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001052 }
1053
1054 // Persist the runtime permissions state for users with changes. If permissions
1055 // were revoked because no app in the shared user declares them we have to
1056 // write synchronously to avoid losing runtime permissions state.
1057 if (callback != null) {
1058 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
1059 }
1060 }
1061
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001062 /**
1063 * Set app op for a app-op related to a permission.
1064 *
1065 * @param permission The permission the app-op belongs to
1066 * @param pkg The package the permission belongs to
1067 * @param userId The user to be changed
1068 * @param mode The new mode to set
1069 */
1070 private void setAppOpMode(@NonNull String permission, @NonNull PackageParser.Package pkg,
1071 @UserIdInt int userId, int mode) {
1072 AppOpsManagerInternal appOpsInternal = LocalServices.getService(
1073 AppOpsManagerInternal.class);
1074
1075 appOpsInternal.setMode(permissionToOpCode(permission),
1076 getUid(userId, getAppId(pkg.applicationInfo.uid)), pkg.packageName, mode,
1077 (pkg.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0);
1078 }
1079
1080 /**
1081 * Revoke permissions that are not implicit anymore and that have
1082 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
1083 *
1084 * @param ps The state of the permissions of the package
1085 * @param pkg The package that is currently looked at
1086 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
1087 * for a user is changed.
1088 *
1089 * @return The updated value of the {@code updatedUserIds} parameter
1090 */
1091 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
1092 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1093 @NonNull int[] updatedUserIds) {
1094 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1095
1096 String pkgName = pkg.packageName;
1097
1098 int[] users = UserManagerService.getInstance().getUserIds();
1099 int numUsers = users.length;
1100 for (int i = 0; i < numUsers; i++) {
1101 int userId = users[i];
1102
1103 for (String permission : ps.getPermissions(userId)) {
1104 if (!pkg.implicitPermissions.contains(permission)) {
1105 if (!ps.hasInstallPermission(permission)) {
1106 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
1107
1108 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
1109 BasePermission bp = mSettings.getPermissionLocked(permission);
1110
1111 ps.updatePermissionFlags(bp, userId,
1112 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
1113 | FLAG_PERMISSION_USER_FIXED | FLAG_PERMISSION_USER_SET,
1114 0);
1115 updatedUserIds = ArrayUtils.appendInt(updatedUserIds,
1116 userId);
1117
1118 if ((flags & (FLAG_PERMISSION_GRANTED_BY_DEFAULT
1119 | FLAG_PERMISSION_POLICY_FIXED | FLAG_PERMISSION_SYSTEM_FIXED))
1120 == 0) {
1121 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1122 if (permissionToOpCode(permission) != OP_NONE) {
1123 setAppOpMode(permission, pkg, userId, MODE_IGNORED);
1124
1125 if (DEBUG_PERMISSIONS) {
1126 Slog.i(TAG, "Revoking app-op "
1127 + permissionToOp(permission) + " for " + pkgName
1128 + " as it is now requested");
1129 }
1130 }
1131 } else {
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001132 int revokeResult = ps.revokeRuntimePermission(bp, userId);
1133 if (revokeResult
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001134 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
1135
1136 if (DEBUG_PERMISSIONS) {
1137 Slog.i(TAG, "Revoking runtime permission " + permission
1138 + " for " + pkgName
1139 + " as it is now requested");
1140 }
1141 }
1142 }
1143
1144 List<String> fgPerms = mBackgroundPermissions.get(permission);
1145 if (fgPerms != null) {
1146 int numFgPerms = fgPerms.size();
1147 for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) {
1148 String fgPerm = fgPerms.get(fgPermNum);
1149
1150 int mode = appOpsManager.unsafeCheckOpRaw(
1151 permissionToOp(fgPerm),
1152 getUid(userId, getAppId(pkg.applicationInfo.uid)),
1153 pkgName);
1154
1155 if (mode == MODE_ALLOWED) {
1156 setAppOpMode(fgPerm, pkg, userId, MODE_FOREGROUND);
1157 }
1158 }
1159 }
1160 }
1161 }
1162 }
1163 }
1164 }
1165 }
1166
1167 return updatedUserIds;
1168 }
1169
1170 /**
1171 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
1172 *
1173 * <p>A single new permission can be split off from several source permissions. In this case
1174 * the most leniant state is inherited.
1175 *
1176 * <p>Warning: This does not handle foreground / background permissions
1177 *
1178 * @param sourcePerms The permissions to inherit from
1179 * @param newPerm The permission to inherit to
1180 * @param ps The permission state of the package
1181 * @param pkg The package requesting the permissions
1182 * @param userId The user the permission belongs to
1183 */
1184 private void inheritPermissionStateToNewImplicitPermissionLocked(
1185 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
1186 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1187 @UserIdInt int userId) {
1188 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1189 String pkgName = pkg.packageName;
1190
1191 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1192 if (permissionToOp(newPerm) != null) {
1193 int mostLenientSourceMode = MODE_ERRORED;
1194
1195 // Find most lenient source permission state.
1196 int numSourcePerms = sourcePerms.size();
1197 for (int i = 0; i < numSourcePerms; i++) {
1198 String sourcePerm = sourcePerms.valueAt(i);
1199
1200 if (ps.hasRuntimePermission(sourcePerm, userId)) {
1201 String sourceOp = permissionToOp(sourcePerm);
1202
1203 if (sourceOp != null) {
1204 int mode = appOpsManager.unsafeCheckOpRaw(sourceOp,
1205 getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName);
1206
1207 if (mode == MODE_FOREGROUND) {
1208 throw new IllegalArgumentException("split permission" + sourcePerm
1209 + " has app-op state " + AppOpsManager.MODE_NAMES[mode]);
1210 }
1211
1212 // Leniency order: allowed > ignored > default
1213 if (mode == MODE_ALLOWED) {
1214 mostLenientSourceMode = MODE_ALLOWED;
1215 break;
1216 } else if (mode == MODE_IGNORED) {
1217 mostLenientSourceMode = MODE_IGNORED;
1218 } else if (mode == MODE_DEFAULT
1219 && mostLenientSourceMode != MODE_IGNORED) {
1220 mostLenientSourceMode = MODE_DEFAULT;
1221 }
1222 }
1223 }
1224 }
1225
1226 if (mostLenientSourceMode != MODE_ERRORED) {
1227 if (DEBUG_PERMISSIONS) {
1228 Slog.i(TAG, newPerm + " inherits app-ops state " + mostLenientSourceMode
1229 + " from " + sourcePerms + " for " + pkgName);
1230 }
1231
1232 setAppOpMode(newPerm, pkg, userId, mostLenientSourceMode);
1233 }
1234 }
1235 } else {
1236 boolean isGranted = false;
1237
1238 int numSourcePerm = sourcePerms.size();
1239 for (int i = 0; i < numSourcePerm; i++) {
1240 String sourcePerm = sourcePerms.valueAt(i);
1241 if (ps.hasRuntimePermission(sourcePerm, userId)
1242 && ps.getRuntimePermissionState(sourcePerm, userId).isGranted()) {
1243 isGranted = true;
1244 break;
Zimuzoc1537dc2018-11-15 21:36:21 +00001245 } else if (ps.hasInstallPermission(sourcePerm)) {
1246 isGranted = true;
1247 break;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001248 }
1249 }
1250
1251 if (isGranted) {
1252 if (DEBUG_PERMISSIONS) {
1253 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
1254 + " for " + pkgName);
1255 }
1256
1257 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
1258 }
1259 }
1260 }
1261
1262 /**
1263 * Set the state of a implicit permission that is seen for the first time.
1264 *
1265 * @param origPs The permission state of the package before the split
1266 * @param ps The new permission state
1267 * @param pkg The package the permission belongs to
1268 * @param updatedUserIds List of users for which the permission state has already been changed
1269 *
1270 * @return List of users for which the permission state has been changed
1271 */
1272 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
1273 @NonNull PermissionsState origPs,
1274 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1275 @NonNull int[] updatedUserIds) {
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001276 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1277
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001278 String pkgName = pkg.packageName;
1279 ArraySet<String> newImplicitPermissions = new ArraySet<>();
1280
1281 int numRequestedPerms = pkg.requestedPermissions.size();
1282 for (int i = 0; i < numRequestedPerms; i++) {
1283 BasePermission bp = mSettings.getPermissionLocked(pkg.requestedPermissions.get(i));
1284 if (bp != null) {
1285 String perm = bp.getName();
1286
1287 if (!origPs.hasRequestedPermission(perm) && pkg.implicitPermissions.contains(
1288 perm)) {
1289 newImplicitPermissions.add(perm);
1290
1291 if (DEBUG_PERMISSIONS) {
1292 Slog.i(TAG, perm + " is newly added for " + pkgName);
1293 }
1294 }
1295 }
1296 }
1297
1298 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
1299
1300 int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
1301 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
1302 PermissionManager.SplitPermissionInfo spi =
1303 PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
1304
1305 List<String> newPerms = spi.getNewPermissions();
1306 int numNewPerms = newPerms.size();
1307 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
1308 String newPerm = newPerms.get(newPermNum);
1309
1310 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
1311 if (splitPerms == null) {
1312 splitPerms = new ArraySet<>();
1313 newToSplitPerms.put(newPerm, splitPerms);
1314 }
1315
1316 splitPerms.add(spi.getSplitPermission());
1317 }
1318 }
1319
1320 int numNewImplicitPerms = newImplicitPermissions.size();
1321 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
1322 newImplicitPermNum++) {
1323 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
1324 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
1325
1326 if (sourcePerms != null) {
1327 if (!ps.hasInstallPermission(newPerm)) {
1328 BasePermission bp = mSettings.getPermissionLocked(newPerm);
1329
1330 int[] users = UserManagerService.getInstance().getUserIds();
1331 int numUsers = users.length;
1332 for (int userNum = 0; userNum < numUsers; userNum++) {
1333 int userId = users[userNum];
1334
1335 ps.updatePermissionFlags(bp, userId,
1336 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
1337 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
1338 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1339
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001340 // SPECIAL BEHAVIOR for background location. Foreground only by default.
1341 if (newPerm.equals(ACCESS_BACKGROUND_LOCATION)) {
1342 int numSourcePerms = sourcePerms.size();
1343 for (int sourcePermNum = 0; sourcePermNum < numSourcePerms;
1344 sourcePermNum++) {
1345 String sourcePerm = sourcePerms.valueAt(sourcePermNum);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001346
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001347 if (appOpsManager.unsafeCheckOpNoThrow(permissionToOp(sourcePerm),
1348 getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName)
1349 == MODE_ALLOWED) {
1350 setAppOpMode(sourcePerm, pkg, userId, MODE_FOREGROUND);
1351 }
1352 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001353 } else {
Zimuzoc1537dc2018-11-15 21:36:21 +00001354 boolean inheritsFromInstallPerm = false;
1355 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
1356 sourcePermNum++) {
1357 if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
1358 inheritsFromInstallPerm = true;
1359 break;
1360 }
1361 }
1362
1363 if (!origPs.hasRequestedPermission(sourcePerms)
1364 && !inheritsFromInstallPerm) {
1365 // Both permissions are new so nothing to inherit.
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001366 if (DEBUG_PERMISSIONS) {
1367 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
1368 + " for " + pkgName
1369 + " as split permission is also new");
1370 }
1371
1372 break;
1373 } else {
Zimuzoc1537dc2018-11-15 21:36:21 +00001374 // Inherit from new install or existing runtime permissions
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001375 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
1376 newPerm, ps, pkg, userId);
1377 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001378 }
1379 }
1380 }
1381 }
1382 }
1383
1384 return updatedUserIds;
1385 }
1386
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001387 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
1388 boolean allowed = false;
1389 final int NP = PackageParser.NEW_PERMISSIONS.length;
1390 for (int ip=0; ip<NP; ip++) {
1391 final PackageParser.NewPermissionInfo npi
1392 = PackageParser.NEW_PERMISSIONS[ip];
1393 if (npi.name.equals(perm)
1394 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1395 allowed = true;
1396 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1397 + pkg.packageName);
1398 break;
1399 }
1400 }
1401 return allowed;
1402 }
1403
1404 /**
1405 * Determines whether a package is whitelisted for a particular privapp permission.
1406 *
1407 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1408 *
1409 * <p>This handles parent/child apps.
1410 */
1411 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001412 ArraySet<String> wlPermissions = null;
1413 if (pkg.isVendor()) {
1414 wlPermissions =
1415 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1416 } else if (pkg.isProduct()) {
1417 wlPermissions =
1418 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001419 } else if (pkg.isProductServices()) {
1420 wlPermissions =
1421 SystemConfig.getInstance().getProductServicesPrivAppPermissions(
1422 pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001423 } else {
1424 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1425 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001426 // Let's check if this package is whitelisted...
1427 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1428 // If it's not, we'll also tail-recurse to the parent.
1429 return whitelisted ||
1430 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1431 }
1432
1433 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1434 BasePermission bp, PermissionsState origPermissions) {
1435 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09001436 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1437 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001438 boolean privappPermissionsDisable =
1439 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1440 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1441 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1442 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1443 && !platformPackage && platformPermission) {
1444 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001445 // Only report violations for apps on system image
1446 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1447 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001448 ArraySet<String> deniedPermissions = null;
1449 if (pkg.isVendor()) {
1450 deniedPermissions = SystemConfig.getInstance()
1451 .getVendorPrivAppDenyPermissions(pkg.packageName);
1452 } else if (pkg.isProduct()) {
1453 deniedPermissions = SystemConfig.getInstance()
1454 .getProductPrivAppDenyPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001455 } else if (pkg.isProductServices()) {
1456 deniedPermissions = SystemConfig.getInstance()
1457 .getProductServicesPrivAppDenyPermissions(pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001458 } else {
1459 deniedPermissions = SystemConfig.getInstance()
1460 .getPrivAppDenyPermissions(pkg.packageName);
1461 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001462 final boolean permissionViolation =
1463 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07001464 if (permissionViolation) {
1465 Slog.w(TAG, "Privileged permission " + perm + " for package "
1466 + pkg.packageName + " - not in privapp-permissions whitelist");
1467
1468 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1469 if (mPrivappPermissionsViolations == null) {
1470 mPrivappPermissionsViolations = new ArraySet<>();
1471 }
1472 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001473 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001474 } else {
1475 return false;
1476 }
1477 }
1478 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1479 return false;
1480 }
1481 }
1482 }
1483 final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1484 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1485 final PackageParser.Package systemPackage =
1486 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08001487
1488 // check if the package is allow to use this signature permission. A package is allowed to
1489 // use a signature permission if:
1490 // - it has the same set of signing certificates as the source package
1491 // - or its signing certificate was rotated from the source package's certificate
1492 // - or its signing certificate is a previous signing certificate of the defining
1493 // package, and the defining package still trusts the old certificate for permissions
1494 // - or it shares the above relationships with the system package
1495 boolean allowed =
1496 pkg.mSigningDetails.hasAncestorOrSelf(
1497 bp.getSourcePackageSetting().getSigningDetails())
1498 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1499 pkg.mSigningDetails,
1500 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1501 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1502 || systemPackage.mSigningDetails.checkCapability(
1503 pkg.mSigningDetails,
1504 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001505 if (!allowed && (privilegedPermission || oemPermission)) {
1506 if (pkg.isSystem()) {
1507 // For updated system applications, a privileged/oem permission
1508 // is granted only if it had been defined by the original application.
1509 if (pkg.isUpdatedSystemApp()) {
1510 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001511 mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001512 final PackageSetting disabledPs =
1513 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1514 if (disabledPs != null
1515 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1516 // If the original was granted this permission, we take
1517 // that grant decision as read and propagate it to the
1518 // update.
1519 if ((privilegedPermission && disabledPs.isPrivileged())
1520 || (oemPermission && disabledPs.isOem()
1521 && canGrantOemPermission(disabledPs, perm))) {
1522 allowed = true;
1523 }
1524 } else {
1525 // The system apk may have been updated with an older
1526 // version of the one on the data partition, but which
1527 // granted a new system permission that it didn't have
1528 // before. In this case we do want to allow the app to
1529 // now get the new permission if the ancestral apk is
1530 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001531 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001532 && isPackageRequestingPermission(disabledPkg, perm)
1533 && ((privilegedPermission && disabledPs.isPrivileged())
1534 || (oemPermission && disabledPs.isOem()
1535 && canGrantOemPermission(disabledPs, perm)))) {
1536 allowed = true;
1537 }
1538 // Also if a privileged parent package on the system image or any of
1539 // its children requested a privileged/oem permission, the updated child
1540 // packages can also get the permission.
1541 if (pkg.parentPackage != null) {
1542 final PackageParser.Package disabledParentPkg = mPackageManagerInt
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001543 .getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001544 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1545 ? (PackageSetting) disabledParentPkg.mExtras : null;
1546 if (disabledParentPkg != null
1547 && ((privilegedPermission && disabledParentPs.isPrivileged())
1548 || (oemPermission && disabledParentPs.isOem()))) {
1549 if (isPackageRequestingPermission(disabledParentPkg, perm)
1550 && canGrantOemPermission(disabledParentPs, perm)) {
1551 allowed = true;
1552 } else if (disabledParentPkg.childPackages != null) {
1553 for (PackageParser.Package disabledChildPkg
1554 : disabledParentPkg.childPackages) {
1555 final PackageSetting disabledChildPs =
1556 (disabledChildPkg != null)
1557 ? (PackageSetting) disabledChildPkg.mExtras
1558 : null;
1559 if (isPackageRequestingPermission(disabledChildPkg, perm)
1560 && canGrantOemPermission(
1561 disabledChildPs, perm)) {
1562 allowed = true;
1563 break;
1564 }
1565 }
1566 }
1567 }
1568 }
1569 }
1570 } else {
1571 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1572 allowed = (privilegedPermission && pkg.isPrivileged())
1573 || (oemPermission && pkg.isOem()
1574 && canGrantOemPermission(ps, perm));
1575 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001576 // In any case, don't grant a privileged permission to privileged vendor apps, if
1577 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1578 // flag.
1579 if (allowed && privilegedPermission &&
1580 !vendorPrivilegedPermission && pkg.isVendor()) {
1581 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1582 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1583 allowed = false;
1584 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001585 }
1586 }
1587 if (!allowed) {
1588 if (!allowed
1589 && bp.isPre23()
1590 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1591 // If this was a previously normal/dangerous permission that got moved
1592 // to a system permission as part of the runtime permission redesign, then
1593 // we still want to blindly grant it to old apps.
1594 allowed = true;
1595 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001596 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1597 // need a separate flag anymore. Hence we need to check which
1598 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001599 if (!allowed && bp.isInstaller()
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001600 && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1601 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
1602 || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1603 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
1604 UserHandle.USER_SYSTEM)))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001605 // If this permission is to be granted to the system installer and
1606 // this app is an installer, then it gets the permission.
1607 allowed = true;
1608 }
1609 if (!allowed && bp.isVerifier()
1610 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1611 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1612 // If this permission is to be granted to the system verifier and
1613 // this app is a verifier, then it gets the permission.
1614 allowed = true;
1615 }
1616 if (!allowed && bp.isPreInstalled()
1617 && pkg.isSystem()) {
1618 // Any pre-installed system app is allowed to get this permission.
1619 allowed = true;
1620 }
1621 if (!allowed && bp.isDevelopment()) {
1622 // For development permissions, a development permission
1623 // is granted only if it was already granted.
1624 allowed = origPermissions.hasInstallPermission(perm);
1625 }
1626 if (!allowed && bp.isSetup()
1627 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1628 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1629 // If this permission is to be granted to the system setup wizard and
1630 // this app is a setup wizard, then it gets the permission.
1631 allowed = true;
1632 }
Makoto Onuki700feef2018-02-15 10:59:41 -08001633 if (!allowed && bp.isSystemTextClassifier()
1634 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1635 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1636 UserHandle.USER_SYSTEM))) {
1637 // Special permissions for the system default text classifier.
1638 allowed = true;
1639 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001640 }
1641 return allowed;
1642 }
1643
1644 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1645 if (!ps.isOem()) {
1646 return false;
1647 }
1648 // all oem permissions must explicitly be granted or denied
1649 final Boolean granted =
1650 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1651 if (granted == null) {
1652 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1653 + ps.name + " must be explicitly declared granted or not");
1654 }
1655 return Boolean.TRUE == granted;
1656 }
1657
1658 private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001659 // Permission review applies only to apps not supporting the new permission model.
1660 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1661 return false;
1662 }
1663
1664 // Legacy apps have the permission and get user consent on launch.
1665 if (pkg == null || pkg.mExtras == null) {
1666 return false;
1667 }
1668 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1669 final PermissionsState permissionsState = ps.getPermissionsState();
1670 return permissionsState.isPermissionReviewRequired(userId);
1671 }
1672
1673 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1674 final int permCount = pkg.requestedPermissions.size();
1675 for (int j = 0; j < permCount; j++) {
1676 String requestedPermission = pkg.requestedPermissions.get(j);
1677 if (permission.equals(requestedPermission)) {
1678 return true;
1679 }
1680 }
1681 return false;
1682 }
1683
Andreas Gampea36dc622018-02-05 17:19:22 -08001684 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07001685 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1686 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1687 if (pkg.parentPackage == null) {
1688 return;
1689 }
1690 if (pkg.requestedPermissions == null) {
1691 return;
1692 }
1693 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001694 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001695 if (disabledPkg == null || disabledPkg.mExtras == null) {
1696 return;
1697 }
1698 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1699 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1700 return;
1701 }
1702 final int permCount = pkg.requestedPermissions.size();
1703 for (int i = 0; i < permCount; i++) {
1704 String permission = pkg.requestedPermissions.get(i);
1705 BasePermission bp = mSettings.getPermissionLocked(permission);
1706 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1707 continue;
1708 }
1709 for (int userId : mUserManagerInt.getUserIds()) {
1710 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1711 grantRuntimePermission(
1712 permission, pkg.packageName, false, callingUid, userId, callback);
1713 }
1714 }
1715 }
1716 }
1717
1718 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1719 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1720 for (int userId : userIds) {
1721 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1722 callback);
1723 }
1724 }
1725
1726 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1727 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1728 PackageSetting ps = (PackageSetting) pkg.mExtras;
1729 if (ps == null) {
1730 return;
1731 }
1732
1733 PermissionsState permissionsState = ps.getPermissionsState();
1734
1735 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1736 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1737
1738 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1739 >= Build.VERSION_CODES.M;
1740
1741 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
1742
1743 for (String permission : pkg.requestedPermissions) {
1744 final BasePermission bp;
1745 synchronized (mLock) {
1746 bp = mSettings.getPermissionLocked(permission);
1747 }
1748 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1749 && (!instantApp || bp.isInstant())
1750 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
1751 && (grantedPermissions == null
1752 || ArrayUtils.contains(grantedPermissions, permission))) {
1753 final int flags = permissionsState.getPermissionFlags(permission, userId);
1754 if (supportsRuntimePermissions) {
1755 // Installer cannot change immutable permissions.
1756 if ((flags & immutableFlags) == 0) {
1757 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
1758 userId, callback);
1759 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001760 } else {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001761 // In permission review mode we clear the review flag when we
1762 // are asked to install the app with all permissions granted.
1763 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1764 updatePermissionFlags(permission, pkg.packageName,
1765 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
1766 userId, callback);
1767 }
1768 }
1769 }
1770 }
1771 }
1772
1773 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
1774 int callingUid, final int userId, PermissionCallback callback) {
1775 if (!mUserManagerInt.exists(userId)) {
1776 Log.e(TAG, "No such user:" + userId);
1777 return;
1778 }
1779
1780 mContext.enforceCallingOrSelfPermission(
1781 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1782 "grantRuntimePermission");
1783
1784 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001785 true, // requireFullPermission
1786 true, // checkShell
1787 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001788 "grantRuntimePermission");
1789
1790 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1791 if (pkg == null || pkg.mExtras == null) {
1792 throw new IllegalArgumentException("Unknown package: " + packageName);
1793 }
1794 final BasePermission bp;
1795 synchronized(mLock) {
1796 bp = mSettings.getPermissionLocked(permName);
1797 }
1798 if (bp == null) {
1799 throw new IllegalArgumentException("Unknown permission: " + permName);
1800 }
1801 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1802 throw new IllegalArgumentException("Unknown package: " + packageName);
1803 }
1804
1805 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1806
1807 // If a permission review is required for legacy apps we represent
1808 // their permissions as always granted runtime ones since we need
1809 // to keep the review required permission flag per user while an
1810 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001811 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07001812 && bp.isRuntime()) {
1813 return;
1814 }
1815
1816 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1817
1818 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1819 final PermissionsState permissionsState = ps.getPermissionsState();
1820
1821 final int flags = permissionsState.getPermissionFlags(permName, userId);
1822 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1823 throw new SecurityException("Cannot grant system fixed permission "
1824 + permName + " for package " + packageName);
1825 }
1826 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1827 throw new SecurityException("Cannot grant policy fixed permission "
1828 + permName + " for package " + packageName);
1829 }
1830
1831 if (bp.isDevelopment()) {
1832 // Development permissions must be handled specially, since they are not
1833 // normal runtime permissions. For now they apply to all users.
1834 if (permissionsState.grantInstallPermission(bp) !=
1835 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1836 if (callback != null) {
1837 callback.onInstallPermissionGranted();
1838 }
1839 }
1840 return;
1841 }
1842
1843 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1844 throw new SecurityException("Cannot grant non-ephemeral permission"
1845 + permName + " for package " + packageName);
1846 }
1847
1848 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1849 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1850 return;
1851 }
1852
1853 final int result = permissionsState.grantRuntimePermission(bp, userId);
1854 switch (result) {
1855 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
1856 return;
1857 }
1858
1859 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1860 if (callback != null) {
1861 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
1862 }
1863 }
1864 break;
1865 }
1866
1867 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07001868 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001869 }
1870
1871 if (callback != null) {
1872 callback.onPermissionGranted(uid, userId);
1873 }
1874
1875 // Only need to do this if user is initialized. Otherwise it's a new user
1876 // and there are no processes running as the user yet and there's no need
1877 // to make an expensive call to remount processes for the changed permissions.
1878 if (READ_EXTERNAL_STORAGE.equals(permName)
1879 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1880 final long token = Binder.clearCallingIdentity();
1881 try {
1882 if (mUserManagerInt.isUserInitialized(userId)) {
1883 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1884 StorageManagerInternal.class);
1885 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1886 }
1887 } finally {
1888 Binder.restoreCallingIdentity(token);
1889 }
1890 }
1891
1892 }
Hongming Jinae750fb2018-09-27 23:00:20 +00001893
1894 private void revokeRuntimePermission(String permName, String packageName,
1895 boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001896 if (!mUserManagerInt.exists(userId)) {
1897 Log.e(TAG, "No such user:" + userId);
1898 return;
1899 }
1900
1901 mContext.enforceCallingOrSelfPermission(
1902 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1903 "revokeRuntimePermission");
1904
1905 enforceCrossUserPermission(Binder.getCallingUid(), userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001906 true, // requireFullPermission
1907 true, // checkShell
1908 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001909 "revokeRuntimePermission");
1910
1911 final int appId;
1912
1913 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1914 if (pkg == null || pkg.mExtras == null) {
1915 throw new IllegalArgumentException("Unknown package: " + packageName);
1916 }
1917 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
1918 throw new IllegalArgumentException("Unknown package: " + packageName);
1919 }
Hongming Jinae750fb2018-09-27 23:00:20 +00001920 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001921 if (bp == null) {
1922 throw new IllegalArgumentException("Unknown permission: " + permName);
1923 }
1924
1925 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1926
1927 // If a permission review is required for legacy apps we represent
1928 // their permissions as always granted runtime ones since we need
1929 // to keep the review required permission flag per user while an
1930 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001931 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07001932 && bp.isRuntime()) {
1933 return;
1934 }
1935
1936 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1937 final PermissionsState permissionsState = ps.getPermissionsState();
1938
1939 final int flags = permissionsState.getPermissionFlags(permName, userId);
Nathan Haroldd66b9f32018-03-14 19:55:38 -07001940 // Only the system may revoke SYSTEM_FIXED permissions.
1941 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1942 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1943 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07001944 + permName + " for package " + packageName);
1945 }
1946 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1947 throw new SecurityException("Cannot revoke policy fixed permission "
1948 + permName + " for package " + packageName);
1949 }
1950
1951 if (bp.isDevelopment()) {
1952 // Development permissions must be handled specially, since they are not
1953 // normal runtime permissions. For now they apply to all users.
1954 if (permissionsState.revokeInstallPermission(bp) !=
1955 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1956 if (callback != null) {
1957 callback.onInstallPermissionRevoked();
1958 }
1959 }
1960 return;
1961 }
1962
1963 if (permissionsState.revokeRuntimePermission(bp, userId) ==
1964 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1965 return;
1966 }
1967
1968 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07001969 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001970 }
1971
1972 if (callback != null) {
1973 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1974 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
1975 }
1976 }
1977
Andreas Gampea36dc622018-02-05 17:19:22 -08001978 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001979 private int[] revokeUnusedSharedUserPermissionsLocked(
1980 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001981 // Collect all used permissions in the UID
1982 final ArraySet<String> usedPermissions = new ArraySet<>();
1983 final List<PackageParser.Package> pkgList = suSetting.getPackages();
1984 if (pkgList == null || pkgList.size() == 0) {
1985 return EmptyArray.INT;
1986 }
1987 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07001988 if (pkg.requestedPermissions == null) {
1989 continue;
1990 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07001991 final int requestedPermCount = pkg.requestedPermissions.size();
1992 for (int j = 0; j < requestedPermCount; j++) {
1993 String permission = pkg.requestedPermissions.get(j);
1994 BasePermission bp = mSettings.getPermissionLocked(permission);
1995 if (bp != null) {
1996 usedPermissions.add(permission);
1997 }
1998 }
1999 }
2000
2001 PermissionsState permissionsState = suSetting.getPermissionsState();
2002 // Prune install permissions
2003 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
2004 final int installPermCount = installPermStates.size();
2005 for (int i = installPermCount - 1; i >= 0; i--) {
2006 PermissionState permissionState = installPermStates.get(i);
2007 if (!usedPermissions.contains(permissionState.getName())) {
2008 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2009 if (bp != null) {
2010 permissionsState.revokeInstallPermission(bp);
2011 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2012 PackageManager.MASK_PERMISSION_FLAGS, 0);
2013 }
2014 }
2015 }
2016
2017 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
2018
2019 // Prune runtime permissions
2020 for (int userId : allUserIds) {
2021 List<PermissionState> runtimePermStates = permissionsState
2022 .getRuntimePermissionStates(userId);
2023 final int runtimePermCount = runtimePermStates.size();
2024 for (int i = runtimePermCount - 1; i >= 0; i--) {
2025 PermissionState permissionState = runtimePermStates.get(i);
2026 if (!usedPermissions.contains(permissionState.getName())) {
2027 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2028 if (bp != null) {
2029 permissionsState.revokeRuntimePermission(bp, userId);
2030 permissionsState.updatePermissionFlags(bp, userId,
2031 PackageManager.MASK_PERMISSION_FLAGS, 0);
2032 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
2033 runtimePermissionChangedUserIds, userId);
2034 }
2035 }
2036 }
2037 }
2038
2039 return runtimePermissionChangedUserIds;
2040 }
2041
Todd Kennedyc8423932017-10-05 08:58:36 -07002042 private String[] getAppOpPermissionPackages(String permName) {
2043 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
2044 return null;
2045 }
2046 synchronized (mLock) {
2047 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
2048 if (pkgs == null) {
2049 return null;
2050 }
2051 return pkgs.toArray(new String[pkgs.size()]);
2052 }
2053 }
2054
2055 private int getPermissionFlags(
2056 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002057 if (!mUserManagerInt.exists(userId)) {
2058 return 0;
2059 }
2060
2061 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
2062
2063 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002064 true, // requireFullPermission
2065 false, // checkShell
2066 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002067 "getPermissionFlags");
2068
2069 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2070 if (pkg == null || pkg.mExtras == null) {
2071 return 0;
2072 }
2073 synchronized (mLock) {
2074 if (mSettings.getPermissionLocked(permName) == null) {
2075 return 0;
2076 }
2077 }
2078 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2079 return 0;
2080 }
2081 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2082 PermissionsState permissionsState = ps.getPermissionsState();
2083 return permissionsState.getPermissionFlags(permName, userId);
2084 }
2085
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002086 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
2087 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
2088 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
2089
2090 private void updatePermissions(String packageName, PackageParser.Package pkg,
2091 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
2092 PermissionCallback callback) {
2093 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
2094 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
2095 updatePermissions(
2096 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
2097 if (pkg != null && pkg.childPackages != null) {
2098 for (PackageParser.Package childPkg : pkg.childPackages) {
2099 updatePermissions(childPkg.packageName, childPkg,
2100 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
2101 }
2102 }
2103 }
2104
2105 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2106 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2107 final int flags = UPDATE_PERMISSIONS_ALL |
2108 (sdkUpdated
2109 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
2110 : 0);
2111 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
2112 }
2113
2114 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
2115 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
2116 PermissionCallback callback) {
2117 // TODO: Most of the methods exposing BasePermission internals [source package name,
2118 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
2119 // have package settings, we should make note of it elsewhere [map between
2120 // source package name and BasePermission] and cycle through that here. Then we
2121 // define a single method on BasePermission that takes a PackageSetting, changing
2122 // package name and a package.
2123 // NOTE: With this approach, we also don't need to tree trees differently than
2124 // normal permissions. Today, we need two separate loops because these BasePermission
2125 // objects are stored separately.
2126 // Make sure there are no dangling permission trees.
2127 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
2128
2129 // Make sure all dynamic permissions have been assigned to a package,
2130 // and make sure there are no dangling permissions.
2131 flags = updatePermissions(changingPkgName, changingPkg, flags);
2132
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002133 synchronized (mLock) {
2134 if (mBackgroundPermissions == null) {
2135 // Cache background -> foreground permission mapping.
2136 // Only system declares background permissions, hence mapping does never change.
2137 mBackgroundPermissions = new ArrayMap<>();
2138 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Philip P. Moltmann798bf9a2018-11-08 17:07:19 -08002139 if (bp.perm != null && bp.perm.info != null
2140 && bp.perm.info.backgroundPermission != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002141 String fgPerm = bp.name;
2142 String bgPerm = bp.perm.info.backgroundPermission;
2143
2144 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
2145 if (fgPerms == null) {
2146 fgPerms = new ArrayList<>();
2147 mBackgroundPermissions.put(bgPerm, fgPerms);
2148 }
2149
2150 fgPerms.add(fgPerm);
2151 }
2152 }
2153 }
2154 }
2155
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002156 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002157 // Now update the permissions for all packages, in particular
2158 // replace the granted permissions of the system packages.
2159 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
2160 for (PackageParser.Package pkg : allPackages) {
2161 if (pkg != changingPkg) {
2162 // Only replace for packages on requested volume
2163 final String volumeUuid = getVolumeUuidForPackage(pkg);
2164 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
2165 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002166 restorePermissionState(pkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002167 }
2168 }
2169 }
2170
2171 if (changingPkg != null) {
2172 // Only replace for packages on requested volume
2173 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
2174 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
2175 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002176 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002177 }
2178 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2179 }
2180
2181 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002182 Set<BasePermission> needsUpdate = null;
2183 synchronized (mLock) {
2184 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
2185 while (it.hasNext()) {
2186 final BasePermission bp = it.next();
2187 if (bp.isDynamic()) {
2188 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
2189 }
2190 if (bp.getSourcePackageSetting() != null) {
2191 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002192 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002193 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2194 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002195 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002196 it.remove();
2197 }
2198 continue;
2199 }
2200 if (needsUpdate == null) {
2201 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
2202 }
2203 needsUpdate.add(bp);
2204 }
2205 }
2206 if (needsUpdate != null) {
2207 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002208 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002209 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2210 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002211 if (sourcePkg != null && sourcePkg.mExtras != null) {
2212 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002213 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002214 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002215 }
2216 continue;
2217 }
2218 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
2219 + " from package " + bp.getSourcePackageName());
2220 mSettings.removePermissionLocked(bp.getName());
2221 }
2222 }
2223 }
2224 return flags;
2225 }
2226
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002227 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002228 int flags) {
2229 Set<BasePermission> needsUpdate = null;
2230 synchronized (mLock) {
2231 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
2232 while (it.hasNext()) {
2233 final BasePermission bp = it.next();
2234 if (bp.getSourcePackageSetting() != null) {
2235 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002236 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002237 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2238 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002239 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002240 it.remove();
2241 }
2242 continue;
2243 }
2244 if (needsUpdate == null) {
2245 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
2246 }
2247 needsUpdate.add(bp);
2248 }
2249 }
2250 if (needsUpdate != null) {
2251 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002252 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002253 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2254 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002255 if (sourcePkg != null && sourcePkg.mExtras != null) {
2256 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002257 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002258 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002259 }
2260 continue;
2261 }
2262 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
2263 + " from package " + bp.getSourcePackageName());
2264 mSettings.removePermissionLocked(bp.getName());
2265 }
2266 }
2267 }
2268 return flags;
2269 }
2270
Todd Kennedy0eb97382017-10-03 16:57:22 -07002271 private void updatePermissionFlags(String permName, String packageName, int flagMask,
2272 int flagValues, int callingUid, int userId, PermissionCallback callback) {
2273 if (!mUserManagerInt.exists(userId)) {
2274 return;
2275 }
2276
2277 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
2278
2279 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002280 true, // requireFullPermission
2281 true, // checkShell
2282 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002283 "updatePermissionFlags");
2284
2285 // Only the system can change these flags and nothing else.
2286 if (callingUid != Process.SYSTEM_UID) {
2287 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2288 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2289 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2290 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2291 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2292 }
2293
2294 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2295 if (pkg == null || pkg.mExtras == null) {
2296 throw new IllegalArgumentException("Unknown package: " + packageName);
2297 }
2298 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2299 throw new IllegalArgumentException("Unknown package: " + packageName);
2300 }
2301
2302 final BasePermission bp;
2303 synchronized (mLock) {
2304 bp = mSettings.getPermissionLocked(permName);
2305 }
2306 if (bp == null) {
2307 throw new IllegalArgumentException("Unknown permission: " + permName);
2308 }
2309
2310 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2311 final PermissionsState permissionsState = ps.getPermissionsState();
2312 final boolean hadState =
2313 permissionsState.getRuntimePermissionState(permName, userId) != null;
2314 final boolean permissionUpdated =
2315 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
2316 if (permissionUpdated && callback != null) {
2317 // Install and runtime permissions are stored in different places,
2318 // so figure out what permission changed and persist the change.
2319 if (permissionsState.getInstallPermissionState(permName) != null) {
2320 callback.onInstallPermissionUpdated();
2321 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
2322 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002323 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002324 }
2325 }
2326 }
2327
2328 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2329 int userId, Collection<Package> packages, PermissionCallback callback) {
2330 if (!mUserManagerInt.exists(userId)) {
2331 return false;
2332 }
2333
2334 enforceGrantRevokeRuntimePermissionPermissions(
2335 "updatePermissionFlagsForAllApps");
2336 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002337 true, // requireFullPermission
2338 true, // checkShell
2339 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002340 "updatePermissionFlagsForAllApps");
2341
2342 // Only the system can change system fixed flags.
2343 if (callingUid != Process.SYSTEM_UID) {
2344 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2345 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2346 }
2347
2348 boolean changed = false;
2349 for (PackageParser.Package pkg : packages) {
2350 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2351 if (ps == null) {
2352 continue;
2353 }
2354 PermissionsState permissionsState = ps.getPermissionsState();
2355 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
2356 userId, flagMask, flagValues);
2357 }
2358 return changed;
2359 }
2360
2361 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2362 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2363 != PackageManager.PERMISSION_GRANTED
2364 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2365 != PackageManager.PERMISSION_GRANTED) {
2366 throw new SecurityException(message + " requires "
2367 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2368 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
2369 }
2370 }
2371
2372 /**
2373 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2374 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2375 * @param checkShell whether to prevent shell from access if there's a debugging restriction
2376 * @param message the message to log on security exception
2377 */
2378 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002379 boolean requireFullPermission, boolean checkShell,
2380 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002381 if (userId < 0) {
2382 throw new IllegalArgumentException("Invalid userId " + userId);
2383 }
2384 if (checkShell) {
2385 PackageManagerServiceUtils.enforceShellRestriction(
2386 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2387 }
Todd Kennedyef9acb62018-05-29 15:18:06 -07002388 if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07002389 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002390 if (requireFullPermission) {
2391 mContext.enforceCallingOrSelfPermission(
2392 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2393 } else {
2394 try {
2395 mContext.enforceCallingOrSelfPermission(
2396 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2397 } catch (SecurityException se) {
2398 mContext.enforceCallingOrSelfPermission(
2399 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2400 }
2401 }
2402 }
2403 }
2404
Andreas Gampea71bee82018-07-20 12:55:36 -07002405 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002406 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2407 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07002408 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002409 size += tree.calculateFootprint(perm);
2410 }
2411 return size;
2412 }
2413
Andreas Gampea71bee82018-07-20 12:55:36 -07002414 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002415 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2416 // We calculate the max size of permissions defined by this uid and throw
2417 // if that plus the size of 'info' would exceed our stated maximum.
2418 if (tree.getUid() != Process.SYSTEM_UID) {
2419 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2420 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2421 throw new SecurityException("Permission tree size cap exceeded");
2422 }
2423 }
2424 }
2425
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002426 private void systemReady() {
2427 mSystemReady = true;
2428 if (mPrivappPermissionsViolations != null) {
2429 throw new IllegalStateException("Signature|privileged permissions not in "
2430 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2431 }
2432 }
2433
2434 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2435 if (pkg == null) {
2436 return StorageManager.UUID_PRIVATE_INTERNAL;
2437 }
2438 if (pkg.isExternal()) {
2439 if (TextUtils.isEmpty(pkg.volumeUuid)) {
2440 return StorageManager.UUID_PRIMARY_PHYSICAL;
2441 } else {
2442 return pkg.volumeUuid;
2443 }
2444 } else {
2445 return StorageManager.UUID_PRIVATE_INTERNAL;
2446 }
2447 }
2448
Todd Kennedyc8423932017-10-05 08:58:36 -07002449 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2450 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2451 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2452 return true;
2453 }
2454 }
2455 return false;
2456 }
2457
Todd Kennedy0eb97382017-10-03 16:57:22 -07002458 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002459 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07002460 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002461 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07002462 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002463 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07002464 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002465 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2466 final LogMaker log = new LogMaker(action);
2467 log.setPackageName(packageName);
2468 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002469
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002470 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002471 }
2472
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002473 /**
2474 * Get the mapping of background permissions to their foreground permissions.
2475 *
2476 * <p>Only initialized in the system server.
2477 *
2478 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
2479 */
2480 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
2481 return mBackgroundPermissions;
2482 }
2483
Todd Kennedy0eb97382017-10-03 16:57:22 -07002484 private class PermissionManagerInternalImpl extends PermissionManagerInternal {
2485 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002486 public void systemReady() {
2487 PermissionManagerService.this.systemReady();
2488 }
2489 @Override
2490 public boolean isPermissionsReviewRequired(Package pkg, int userId) {
2491 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
2492 }
2493 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002494 public void revokeRuntimePermissionsIfGroupChanged(
2495 @NonNull PackageParser.Package newPackage,
2496 @NonNull PackageParser.Package oldPackage,
2497 @NonNull ArrayList<String> allPackageNames,
2498 @NonNull PermissionCallback permissionCallback) {
2499 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
2500 oldPackage, allPackageNames, permissionCallback);
2501 }
2502 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002503 public void addAllPermissions(Package pkg, boolean chatty) {
2504 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002505 }
2506 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002507 public void addAllPermissionGroups(Package pkg, boolean chatty) {
2508 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
2509 }
2510 @Override
Hongming Jinae750fb2018-09-27 23:00:20 +00002511 public void removeAllPermissions(Package pkg, boolean chatty) {
2512 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07002513 }
2514 @Override
2515 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07002516 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002517 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
2518 }
2519 @Override
2520 public void removeDynamicPermission(String permName, int callingUid,
2521 PermissionCallback callback) {
2522 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002523 }
2524 @Override
2525 public void grantRuntimePermission(String permName, String packageName,
2526 boolean overridePolicy, int callingUid, int userId,
2527 PermissionCallback callback) {
2528 PermissionManagerService.this.grantRuntimePermission(
2529 permName, packageName, overridePolicy, callingUid, userId, callback);
2530 }
2531 @Override
2532 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2533 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2534 PermissionManagerService.this.grantRequestedRuntimePermissions(
2535 pkg, userIds, grantedPermissions, callingUid, callback);
2536 }
2537 @Override
2538 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
2539 int callingUid, PermissionCallback callback) {
2540 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
2541 pkg, callingUid, callback);
2542 }
2543 @Override
2544 public void revokeRuntimePermission(String permName, String packageName,
2545 boolean overridePolicy, int callingUid, int userId,
2546 PermissionCallback callback) {
2547 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
Hongming Jinae750fb2018-09-27 23:00:20 +00002548 overridePolicy, callingUid, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002549 }
2550 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002551 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
2552 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2553 PermissionManagerService.this.updatePermissions(
2554 packageName, pkg, replaceGrant, allPackages, callback);
2555 }
2556 @Override
2557 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2558 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2559 PermissionManagerService.this.updateAllPermissions(
2560 volumeUuid, sdkUpdated, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002561 }
2562 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002563 public String[] getAppOpPermissionPackages(String permName) {
2564 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
2565 }
2566 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002567 public int getPermissionFlags(String permName, String packageName, int callingUid,
2568 int userId) {
2569 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
2570 callingUid, userId);
2571 }
2572 @Override
2573 public void updatePermissionFlags(String permName, String packageName, int flagMask,
2574 int flagValues, int callingUid, int userId, PermissionCallback callback) {
2575 PermissionManagerService.this.updatePermissionFlags(
2576 permName, packageName, flagMask, flagValues, callingUid, userId, callback);
2577 }
2578 @Override
2579 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2580 int userId, Collection<Package> packages, PermissionCallback callback) {
2581 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
2582 flagMask, flagValues, callingUid, userId, packages, callback);
2583 }
2584 @Override
2585 public void enforceCrossUserPermission(int callingUid, int userId,
2586 boolean requireFullPermission, boolean checkShell, String message) {
2587 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002588 requireFullPermission, checkShell, false, message);
2589 }
2590 @Override
2591 public void enforceCrossUserPermission(int callingUid, int userId,
2592 boolean requireFullPermission, boolean checkShell,
2593 boolean requirePermissionWhenSameUser, String message) {
2594 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
2595 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002596 }
2597 @Override
2598 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2599 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
2600 }
2601 @Override
2602 public int checkPermission(String permName, String packageName, int callingUid,
2603 int userId) {
2604 return PermissionManagerService.this.checkPermission(
2605 permName, packageName, callingUid, userId);
2606 }
2607 @Override
Todd Kennedy3c714492017-10-27 09:12:50 -07002608 public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
2609 int callingUid) {
2610 return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
Todd Kennedy3bc94722017-10-10 09:55:53 -07002611 }
2612 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002613 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
2614 int callingUid) {
2615 return PermissionManagerService.this.getPermissionGroupInfo(
2616 groupName, flags, callingUid);
2617 }
2618 @Override
2619 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
2620 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
2621 }
2622 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002623 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
2624 int callingUid) {
2625 return PermissionManagerService.this.getPermissionInfo(
2626 permName, packageName, flags, callingUid);
2627 }
2628 @Override
2629 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
2630 int callingUid) {
2631 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
2632 }
2633 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002634 public PermissionSettings getPermissionSettings() {
2635 return mSettings;
2636 }
2637 @Override
2638 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
2639 return mDefaultPermissionGrantPolicy;
2640 }
2641 @Override
2642 public BasePermission getPermissionTEMP(String permName) {
2643 synchronized (PermissionManagerService.this.mLock) {
2644 return mSettings.getPermissionLocked(permName);
2645 }
2646 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002647 }
2648}