blob: abe4f5ed44ad20bba8a82526e78c07da098be808 [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
19import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Todd Kennedy3bc94722017-10-10 09:55:53 -070021import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070022import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
23import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
24import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
25import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
26import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
27import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Todd Kennedy0eb97382017-10-03 16:57:22 -070028
29import android.Manifest;
30import android.annotation.NonNull;
31import android.annotation.Nullable;
32import android.app.AppOpsManager;
33import android.content.Context;
34import android.content.pm.PackageManager;
35import android.content.pm.PackageManagerInternal;
36import android.content.pm.PackageParser;
Todd Kennedy460f28c2017-10-06 13:46:22 -070037import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070038import android.content.pm.PermissionInfo;
39import android.content.pm.PackageParser.Package;
40import android.os.Binder;
41import android.os.Build;
42import android.os.Handler;
43import android.os.HandlerThread;
44import android.os.Process;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070045import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070046import android.os.UserHandle;
47import android.os.UserManager;
48import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070049import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070050import android.os.storage.StorageManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070051import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070052import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.Log;
55import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -070056import android.util.SparseArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -070057
58import com.android.internal.R;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070059import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -070060import com.android.internal.logging.MetricsLogger;
61import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070062import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -070063import com.android.internal.util.ArrayUtils;
64import com.android.server.FgThread;
65import com.android.server.LocalServices;
66import com.android.server.ServiceThread;
67import com.android.server.SystemConfig;
68import com.android.server.Watchdog;
69import com.android.server.pm.PackageManagerService;
70import com.android.server.pm.PackageManagerServiceUtils;
71import com.android.server.pm.PackageSetting;
72import com.android.server.pm.ProcessLoggingHandler;
73import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -070074import com.android.server.pm.UserManagerService;
Todd Kennedy0eb97382017-10-03 16:57:22 -070075import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
76import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
77import com.android.server.pm.permission.PermissionsState.PermissionState;
78
79import libcore.util.EmptyArray;
80
81import java.util.ArrayList;
82import java.util.Arrays;
83import java.util.Collection;
84import java.util.Iterator;
85import java.util.List;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070086import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -070087import java.util.Set;
Todd Kennedy0eb97382017-10-03 16:57:22 -070088
89/**
90 * Manages all permissions and handles permissions related tasks.
91 */
92public class PermissionManagerService {
93 private static final String TAG = "PackageManager";
94
95 /** All dangerous permission names in the same order as the events in MetricsEvent */
96 private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
97 Manifest.permission.READ_CALENDAR,
98 Manifest.permission.WRITE_CALENDAR,
99 Manifest.permission.CAMERA,
100 Manifest.permission.READ_CONTACTS,
101 Manifest.permission.WRITE_CONTACTS,
102 Manifest.permission.GET_ACCOUNTS,
103 Manifest.permission.ACCESS_FINE_LOCATION,
104 Manifest.permission.ACCESS_COARSE_LOCATION,
105 Manifest.permission.RECORD_AUDIO,
106 Manifest.permission.READ_PHONE_STATE,
107 Manifest.permission.CALL_PHONE,
108 Manifest.permission.READ_CALL_LOG,
109 Manifest.permission.WRITE_CALL_LOG,
110 Manifest.permission.ADD_VOICEMAIL,
111 Manifest.permission.USE_SIP,
112 Manifest.permission.PROCESS_OUTGOING_CALLS,
113 Manifest.permission.READ_CELL_BROADCASTS,
114 Manifest.permission.BODY_SENSORS,
115 Manifest.permission.SEND_SMS,
116 Manifest.permission.RECEIVE_SMS,
117 Manifest.permission.READ_SMS,
118 Manifest.permission.RECEIVE_WAP_PUSH,
119 Manifest.permission.RECEIVE_MMS,
120 Manifest.permission.READ_EXTERNAL_STORAGE,
121 Manifest.permission.WRITE_EXTERNAL_STORAGE,
122 Manifest.permission.READ_PHONE_NUMBERS,
123 Manifest.permission.ANSWER_PHONE_CALLS);
124
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700125 /** Permission grant: not grant the permission. */
126 private static final int GRANT_DENIED = 1;
127 /** Permission grant: grant the permission as an install permission. */
128 private static final int GRANT_INSTALL = 2;
129 /** Permission grant: grant the permission as a runtime one. */
130 private static final int GRANT_RUNTIME = 3;
131 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
132 private static final int GRANT_UPGRADE = 4;
133
134 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
135 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
136 /** Empty array to avoid allocations */
137 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700138
139 /** Lock to protect internal data access */
140 private final Object mLock;
141
142 /** Internal connection to the package manager */
143 private final PackageManagerInternal mPackageManagerInt;
144
145 /** Internal connection to the user manager */
146 private final UserManagerInternal mUserManagerInt;
147
148 /** Default permission policy to provide proper behaviour out-of-the-box */
149 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
150
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700151 /**
152 * Built-in permissions. Read from system configuration files. Mapping is from
153 * UID to permission name.
154 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700155 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700156
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700157 /** Built-in group IDs given to all packages. Read from system configuration files. */
158 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700159
160 private final HandlerThread mHandlerThread;
161 private final Handler mHandler;
162 private final Context mContext;
163
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700164 /** Internal storage for permissions and related settings */
165 @GuardedBy("mLock")
166 private final PermissionSettings mSettings;
167
168 @GuardedBy("mLock")
169 private ArraySet<String> mPrivappPermissionsViolations;
170
171 @GuardedBy("mLock")
172 private boolean mSystemReady;
173
Todd Kennedy0eb97382017-10-03 16:57:22 -0700174 PermissionManagerService(Context context,
175 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
176 @NonNull Object externalLock) {
177 mContext = context;
178 mLock = externalLock;
179 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
180 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
181 mSettings = new PermissionSettings(context, mLock);
182
183 mHandlerThread = new ServiceThread(TAG,
184 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
185 mHandlerThread.start();
186 mHandler = new Handler(mHandlerThread.getLooper());
187 Watchdog.getInstance().addThread(mHandler);
188
189 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
190 context, mHandlerThread.getLooper(), defaultGrantCallback, this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700191 SystemConfig systemConfig = SystemConfig.getInstance();
192 mSystemPermissions = systemConfig.getSystemPermissions();
193 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700194
195 // propagate permission configuration
196 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
197 SystemConfig.getInstance().getPermissions();
198 synchronized (mLock) {
199 for (int i=0; i<permConfig.size(); i++) {
200 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
201 BasePermission bp = mSettings.getPermissionLocked(perm.name);
202 if (bp == null) {
203 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
204 mSettings.putPermissionLocked(perm.name, bp);
205 }
206 if (perm.gids != null) {
207 bp.setGids(perm.gids, perm.perUser);
208 }
209 }
210 }
211
212 LocalServices.addService(
213 PermissionManagerInternal.class, new PermissionManagerInternalImpl());
214 }
215
216 /**
217 * Creates and returns an initialized, internal service for use by other components.
218 * <p>
219 * The object returned is identical to the one returned by the LocalServices class using:
220 * {@code LocalServices.getService(PermissionManagerInternal.class);}
221 * <p>
222 * NOTE: The external lock is temporary and should be removed. This needs to be a
223 * lock created by the permission manager itself.
224 */
225 public static PermissionManagerInternal create(Context context,
226 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
227 @NonNull Object externalLock) {
228 final PermissionManagerInternal permMgrInt =
229 LocalServices.getService(PermissionManagerInternal.class);
230 if (permMgrInt != null) {
231 return permMgrInt;
232 }
233 new PermissionManagerService(context, defaultGrantCallback, externalLock);
234 return LocalServices.getService(PermissionManagerInternal.class);
235 }
236
237 @Nullable BasePermission getPermission(String permName) {
238 synchronized (mLock) {
239 return mSettings.getPermissionLocked(permName);
240 }
241 }
242
243 private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
244 if (!mUserManagerInt.exists(userId)) {
245 return PackageManager.PERMISSION_DENIED;
246 }
247
248 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
249 if (pkg != null && pkg.mExtras != null) {
250 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
251 return PackageManager.PERMISSION_DENIED;
252 }
253 final PackageSetting ps = (PackageSetting) pkg.mExtras;
254 final boolean instantApp = ps.getInstantApp(userId);
255 final PermissionsState permissionsState = ps.getPermissionsState();
256 if (permissionsState.hasPermission(permName, userId)) {
257 if (instantApp) {
258 synchronized (mLock) {
259 BasePermission bp = mSettings.getPermissionLocked(permName);
260 if (bp != null && bp.isInstant()) {
261 return PackageManager.PERMISSION_GRANTED;
262 }
263 }
264 } else {
265 return PackageManager.PERMISSION_GRANTED;
266 }
267 }
268 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
269 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
270 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
271 return PackageManager.PERMISSION_GRANTED;
272 }
273 }
274
275 return PackageManager.PERMISSION_DENIED;
276 }
277
Todd Kennedy3bc94722017-10-10 09:55:53 -0700278 private int checkUidPermission(String permName, int uid, int callingUid) {
279 final int callingUserId = UserHandle.getUserId(callingUid);
280 final boolean isCallerInstantApp =
281 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
282 final boolean isUidInstantApp =
283 mPackageManagerInt.getInstantAppPackageName(uid) != null;
284 final int userId = UserHandle.getUserId(uid);
285 if (!mUserManagerInt.exists(userId)) {
286 return PackageManager.PERMISSION_DENIED;
287 }
288
289 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
290 if (packages != null && packages.length > 0) {
291 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packages[0]);
292 if (pkg.mSharedUserId != null) {
293 if (isCallerInstantApp) {
294 return PackageManager.PERMISSION_DENIED;
295 }
296 } else {
297 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
298 return PackageManager.PERMISSION_DENIED;
299 }
300 }
301 final PermissionsState permissionsState =
302 ((PackageSetting) pkg.mExtras).getPermissionsState();
303 if (permissionsState.hasPermission(permName, userId)) {
304 if (isUidInstantApp) {
305 if (mSettings.isPermissionInstant(permName)) {
306 return PackageManager.PERMISSION_GRANTED;
307 }
308 } else {
309 return PackageManager.PERMISSION_GRANTED;
310 }
311 }
312 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
313 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
314 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
315 return PackageManager.PERMISSION_GRANTED;
316 }
317 } else {
318 ArraySet<String> perms = mSystemPermissions.get(uid);
319 if (perms != null) {
320 if (perms.contains(permName)) {
321 return PackageManager.PERMISSION_GRANTED;
322 }
323 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
324 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
325 return PackageManager.PERMISSION_GRANTED;
326 }
327 }
328 }
329 return PackageManager.PERMISSION_DENIED;
330 }
331
Todd Kennedy460f28c2017-10-06 13:46:22 -0700332 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
333 int callingUid) {
334 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
335 return null;
336 }
337 synchronized (mLock) {
338 return PackageParser.generatePermissionGroupInfo(
339 mSettings.mPermissionGroups.get(groupName), flags);
340 }
341 }
342
343 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
344 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
345 return null;
346 }
347 synchronized (mLock) {
348 final int N = mSettings.mPermissionGroups.size();
349 final ArrayList<PermissionGroupInfo> out
350 = new ArrayList<PermissionGroupInfo>(N);
351 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
352 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
353 }
354 return out;
355 }
356 }
357
358 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700359 int callingUid) {
360 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
361 return null;
362 }
363 // reader
364 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700365 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700366 if (bp == null) {
367 return null;
368 }
369 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
370 bp.getProtectionLevel(), packageName, callingUid);
371 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
372 }
373 }
374
375 private List<PermissionInfo> getPermissionInfoByGroup(
376 String groupName, int flags, int callingUid) {
377 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
378 return null;
379 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700380 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700381 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
382 return null;
383 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700384 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
Todd Kennedyc8423932017-10-05 08:58:36 -0700385 for (BasePermission bp : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700386 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
387 if (pi != null) {
388 out.add(pi);
389 }
390 }
391 return out;
392 }
393 }
394
395 private int adjustPermissionProtectionFlagsLocked(
396 int protectionLevel, String packageName, int uid) {
397 // Signature permission flags area always reported
398 final int protectionLevelMasked = protectionLevel
399 & (PermissionInfo.PROTECTION_NORMAL
400 | PermissionInfo.PROTECTION_DANGEROUS
401 | PermissionInfo.PROTECTION_SIGNATURE);
402 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
403 return protectionLevel;
404 }
405 // System sees all flags.
406 final int appId = UserHandle.getAppId(uid);
407 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
408 || appId == Process.SHELL_UID) {
409 return protectionLevel;
410 }
411 // Normalize package name to handle renamed packages and static libs
412 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
413 if (pkg == null) {
414 return protectionLevel;
415 }
416 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
417 return protectionLevelMasked;
418 }
419 // Apps that target O see flags for all protection levels.
420 final PackageSetting ps = (PackageSetting) pkg.mExtras;
421 if (ps == null) {
422 return protectionLevel;
423 }
424 if (ps.getAppId() != appId) {
425 return protectionLevel;
426 }
427 return protectionLevel;
428 }
429
Todd Kennedyc8423932017-10-05 08:58:36 -0700430 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
431 final int N = pkg.permissions.size();
432 for (int i=0; i<N; i++) {
433 PackageParser.Permission p = pkg.permissions.get(i);
434
435 // Assume by default that we did not install this permission into the system.
436 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
437
Todd Kennedyc8423932017-10-05 08:58:36 -0700438 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700439 // Now that permission groups have a special meaning, we ignore permission
440 // groups for legacy apps to prevent unexpected behavior. In particular,
441 // permissions for one app being granted to someone just because they happen
442 // to be in a group defined by another app (before this had no implications).
443 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
444 p.group = mSettings.mPermissionGroups.get(p.info.group);
445 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700446 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -0700447 && p.info.group != null && p.group == null) {
448 Slog.i(TAG, "Permission " + p.info.name + " from package "
449 + p.info.packageName + " in an unknown group " + p.info.group);
450 }
451 }
452
Todd Kennedyc8423932017-10-05 08:58:36 -0700453 if (p.tree) {
454 final BasePermission bp = BasePermission.createOrUpdate(
455 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
456 mSettings.getAllPermissionTreesLocked(), chatty);
457 mSettings.putPermissionTreeLocked(p.info.name, bp);
458 } else {
459 final BasePermission bp = BasePermission.createOrUpdate(
460 mSettings.getPermissionLocked(p.info.name),
461 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
462 mSettings.putPermissionLocked(p.info.name, bp);
463 }
464 }
465 }
466 }
467
Todd Kennedy460f28c2017-10-06 13:46:22 -0700468 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
469 final int N = pkg.permissionGroups.size();
470 StringBuilder r = null;
471 for (int i=0; i<N; i++) {
472 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
473 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
474 final String curPackageName = (cur == null) ? null : cur.info.packageName;
475 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
476 if (cur == null || isPackageUpdate) {
477 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700478 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700479 if (r == null) {
480 r = new StringBuilder(256);
481 } else {
482 r.append(' ');
483 }
484 if (isPackageUpdate) {
485 r.append("UPD:");
486 }
487 r.append(pg.info.name);
488 }
489 } else {
490 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
491 + pg.info.packageName + " ignored: original from "
492 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700493 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700494 if (r == null) {
495 r = new StringBuilder(256);
496 } else {
497 r.append(' ');
498 }
499 r.append("DUP:");
500 r.append(pg.info.name);
501 }
502 }
503 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700504 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700505 Log.d(TAG, " Permission Groups: " + r);
506 }
507
508 }
509
Todd Kennedyc8423932017-10-05 08:58:36 -0700510 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
511 synchronized (mLock) {
512 int N = pkg.permissions.size();
513 StringBuilder r = null;
514 for (int i=0; i<N; i++) {
515 PackageParser.Permission p = pkg.permissions.get(i);
516 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
517 if (bp == null) {
518 bp = mSettings.mPermissionTrees.get(p.info.name);
519 }
520 if (bp != null && bp.isPermission(p)) {
521 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700522 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700523 if (r == null) {
524 r = new StringBuilder(256);
525 } else {
526 r.append(' ');
527 }
528 r.append(p.info.name);
529 }
530 }
531 if (p.isAppOp()) {
532 ArraySet<String> appOpPkgs =
533 mSettings.mAppOpPermissionPackages.get(p.info.name);
534 if (appOpPkgs != null) {
535 appOpPkgs.remove(pkg.packageName);
536 }
537 }
538 }
539 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700540 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700541 }
542
543 N = pkg.requestedPermissions.size();
544 r = null;
545 for (int i=0; i<N; i++) {
546 String perm = pkg.requestedPermissions.get(i);
547 if (mSettings.isPermissionAppOp(perm)) {
548 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
549 if (appOpPkgs != null) {
550 appOpPkgs.remove(pkg.packageName);
551 if (appOpPkgs.isEmpty()) {
552 mSettings.mAppOpPermissionPackages.remove(perm);
553 }
554 }
555 }
556 }
557 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700558 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700559 }
560 }
561 }
562
563 private boolean addDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700564 PermissionInfo info, int callingUid, PermissionCallback callback) {
565 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
566 throw new SecurityException("Instant apps can't add permissions");
567 }
568 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
569 throw new SecurityException("Label must be specified in permission");
570 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700571 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700572 final boolean added;
573 final boolean changed;
574 synchronized (mLock) {
575 BasePermission bp = mSettings.getPermissionLocked(info.name);
576 added = bp == null;
577 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
578 if (added) {
579 enforcePermissionCapLocked(info, tree);
580 bp = new BasePermission(info.name, tree.getSourcePackageName(),
581 BasePermission.TYPE_DYNAMIC);
582 } else if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600583 // TODO: switch this back to SecurityException
584 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700585 + info.name);
586 }
587 changed = bp.addToTree(fixedLevel, info, tree);
588 if (added) {
589 mSettings.putPermissionLocked(info.name, bp);
590 }
591 }
592 if (changed && callback != null) {
593 callback.onPermissionChanged();
594 }
595 return added;
596 }
597
Todd Kennedyc8423932017-10-05 08:58:36 -0700598 private void removeDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700599 String permName, int callingUid, PermissionCallback callback) {
600 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
601 throw new SecurityException("Instant applications don't have access to this method");
602 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700603 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700604 synchronized (mLock) {
605 final BasePermission bp = mSettings.getPermissionLocked(permName);
606 if (bp == null) {
607 return;
608 }
609 if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600610 // TODO: switch this back to SecurityException
611 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700612 + permName);
613 }
614 mSettings.removePermissionLocked(permName);
615 if (callback != null) {
616 callback.onPermissionRemoved();
617 }
618 }
619 }
620
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700621 private void grantPermissions(PackageParser.Package pkg, boolean replace,
622 String packageOfInterest, PermissionCallback callback) {
623 // IMPORTANT: There are two types of permissions: install and runtime.
624 // Install time permissions are granted when the app is installed to
625 // all device users and users added in the future. Runtime permissions
626 // are granted at runtime explicitly to specific users. Normal and signature
627 // protected permissions are install time permissions. Dangerous permissions
628 // are install permissions if the app's target SDK is Lollipop MR1 or older,
629 // otherwise they are runtime permissions. This function does not manage
630 // runtime permissions except for the case an app targeting Lollipop MR1
631 // being upgraded to target a newer SDK, in which case dangerous permissions
632 // are transformed from install time to runtime ones.
633
634 final PackageSetting ps = (PackageSetting) pkg.mExtras;
635 if (ps == null) {
636 return;
637 }
638 final boolean isLegacySystemApp = mPackageManagerInt.isLegacySystemApp(pkg);
639
640 final PermissionsState permissionsState = ps.getPermissionsState();
641 PermissionsState origPermissions = permissionsState;
642
643 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
644
645 boolean runtimePermissionsRevoked = false;
646 int[] updatedUserIds = EMPTY_INT_ARRAY;
647
648 boolean changedInstallPermission = false;
649
650 if (replace) {
651 ps.setInstallPermissionsFixed(false);
652 if (!ps.isSharedUser()) {
653 origPermissions = new PermissionsState(permissionsState);
654 permissionsState.reset();
655 } else {
656 // We need to know only about runtime permission changes since the
657 // calling code always writes the install permissions state but
658 // the runtime ones are written only if changed. The only cases of
659 // changed runtime permissions here are promotion of an install to
660 // runtime and revocation of a runtime from a shared user.
661 synchronized (mLock) {
662 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
663 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
664 if (!ArrayUtils.isEmpty(updatedUserIds)) {
665 runtimePermissionsRevoked = true;
666 }
667 }
668 }
669 }
670
671 permissionsState.setGlobalGids(mGlobalGids);
672
673 synchronized (mLock) {
674 final int N = pkg.requestedPermissions.size();
675 for (int i = 0; i < N; i++) {
676 final String permName = pkg.requestedPermissions.get(i);
677 final BasePermission bp = mSettings.getPermissionLocked(permName);
678 final boolean appSupportsRuntimePermissions =
679 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
680
681 if (DEBUG_INSTALL) {
682 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
683 }
684
685 if (bp == null || bp.getSourcePackageSetting() == null) {
686 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
687 if (DEBUG_PERMISSIONS) {
688 Slog.i(TAG, "Unknown permission " + permName
689 + " in package " + pkg.packageName);
690 }
691 }
692 continue;
693 }
694
695 // Limit ephemeral apps to ephemeral allowed permissions.
696 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
697 if (DEBUG_PERMISSIONS) {
698 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
699 + " for package " + pkg.packageName);
700 }
701 continue;
702 }
703
704 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
705 if (DEBUG_PERMISSIONS) {
706 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
707 + " for package " + pkg.packageName);
708 }
709 continue;
710 }
711
712 final String perm = bp.getName();
713 boolean allowedSig = false;
714 int grant = GRANT_DENIED;
715
716 // Keep track of app op permissions.
717 if (bp.isAppOp()) {
718 mSettings.addAppOpPackage(perm, pkg.packageName);
719 }
720
721 if (bp.isNormal()) {
722 // For all apps normal permissions are install time ones.
723 grant = GRANT_INSTALL;
724 } else if (bp.isRuntime()) {
725 // If a permission review is required for legacy apps we represent
726 // their permissions as always granted runtime ones since we need
727 // to keep the review required permission flag per user while an
728 // install permission's state is shared across all users.
729 if (!appSupportsRuntimePermissions && !mSettings.mPermissionReviewRequired) {
730 // For legacy apps dangerous permissions are install time ones.
731 grant = GRANT_INSTALL;
732 } else if (origPermissions.hasInstallPermission(bp.getName())) {
733 // For legacy apps that became modern, install becomes runtime.
734 grant = GRANT_UPGRADE;
735 } else if (isLegacySystemApp) {
736 // For legacy system apps, install becomes runtime.
737 // We cannot check hasInstallPermission() for system apps since those
738 // permissions were granted implicitly and not persisted pre-M.
739 grant = GRANT_UPGRADE;
740 } else {
741 // For modern apps keep runtime permissions unchanged.
742 grant = GRANT_RUNTIME;
743 }
744 } else if (bp.isSignature()) {
745 // For all apps signature permissions are install time ones.
746 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
747 if (allowedSig) {
748 grant = GRANT_INSTALL;
749 }
750 }
751
752 if (DEBUG_PERMISSIONS) {
753 Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
754 }
755
756 if (grant != GRANT_DENIED) {
757 if (!ps.isSystem() && ps.areInstallPermissionsFixed()) {
758 // If this is an existing, non-system package, then
759 // we can't add any new permissions to it.
760 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
761 // Except... if this is a permission that was added
762 // to the platform (note: need to only do this when
763 // updating the platform).
764 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
765 grant = GRANT_DENIED;
766 }
767 }
768 }
769
770 switch (grant) {
771 case GRANT_INSTALL: {
772 // Revoke this as runtime permission to handle the case of
773 // a runtime permission being downgraded to an install one.
774 // Also in permission review mode we keep dangerous permissions
775 // for legacy apps
776 for (int userId : UserManagerService.getInstance().getUserIds()) {
777 if (origPermissions.getRuntimePermissionState(
778 perm, userId) != null) {
779 // Revoke the runtime permission and clear the flags.
780 origPermissions.revokeRuntimePermission(bp, userId);
781 origPermissions.updatePermissionFlags(bp, userId,
782 PackageManager.MASK_PERMISSION_FLAGS, 0);
783 // If we revoked a permission permission, we have to write.
784 updatedUserIds = ArrayUtils.appendInt(
785 updatedUserIds, userId);
786 }
787 }
788 // Grant an install permission.
789 if (permissionsState.grantInstallPermission(bp) !=
790 PermissionsState.PERMISSION_OPERATION_FAILURE) {
791 changedInstallPermission = true;
792 }
793 } break;
794
795 case GRANT_RUNTIME: {
796 // Grant previously granted runtime permissions.
797 for (int userId : UserManagerService.getInstance().getUserIds()) {
798 final PermissionState permissionState = origPermissions
799 .getRuntimePermissionState(perm, userId);
800 int flags = permissionState != null
801 ? permissionState.getFlags() : 0;
802 if (origPermissions.hasRuntimePermission(perm, userId)) {
803 // Don't propagate the permission in a permission review
804 // mode if the former was revoked, i.e. marked to not
805 // propagate on upgrade. Note that in a permission review
806 // mode install permissions are represented as constantly
807 // granted runtime ones since we need to keep a per user
808 // state associated with the permission. Also the revoke
809 // on upgrade flag is no longer applicable and is reset.
810 final boolean revokeOnUpgrade = (flags & PackageManager
811 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
812 if (revokeOnUpgrade) {
813 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
814 // Since we changed the flags, we have to write.
815 updatedUserIds = ArrayUtils.appendInt(
816 updatedUserIds, userId);
817 }
818 if (!mSettings.mPermissionReviewRequired || !revokeOnUpgrade) {
819 if (permissionsState.grantRuntimePermission(bp, userId) ==
820 PermissionsState.PERMISSION_OPERATION_FAILURE) {
821 // If we cannot put the permission as it was,
822 // we have to write.
823 updatedUserIds = ArrayUtils.appendInt(
824 updatedUserIds, userId);
825 }
826 }
827
828 // If the app supports runtime permissions no need for a review.
829 if (mSettings.mPermissionReviewRequired
830 && appSupportsRuntimePermissions
831 && (flags & PackageManager
832 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
833 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
834 // Since we changed the flags, we have to write.
835 updatedUserIds = ArrayUtils.appendInt(
836 updatedUserIds, userId);
837 }
838 } else if (mSettings.mPermissionReviewRequired
839 && !appSupportsRuntimePermissions) {
840 // For legacy apps that need a permission review, every new
841 // runtime permission is granted but it is pending a review.
842 // We also need to review only platform defined runtime
843 // permissions as these are the only ones the platform knows
844 // how to disable the API to simulate revocation as legacy
845 // apps don't expect to run with revoked permissions.
846 if (PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName())) {
847 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
848 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
849 // We changed the flags, hence have to write.
850 updatedUserIds = ArrayUtils.appendInt(
851 updatedUserIds, userId);
852 }
853 }
854 if (permissionsState.grantRuntimePermission(bp, userId)
855 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
856 // We changed the permission, hence have to write.
857 updatedUserIds = ArrayUtils.appendInt(
858 updatedUserIds, userId);
859 }
860 }
861 // Propagate the permission flags.
862 permissionsState.updatePermissionFlags(bp, userId, flags, flags);
863 }
864 } break;
865
866 case GRANT_UPGRADE: {
867 // Grant runtime permissions for a previously held install permission.
868 final PermissionState permissionState = origPermissions
869 .getInstallPermissionState(perm);
870 final int flags =
871 (permissionState != null) ? permissionState.getFlags() : 0;
872
873 if (origPermissions.revokeInstallPermission(bp)
874 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
875 // We will be transferring the permission flags, so clear them.
876 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
877 PackageManager.MASK_PERMISSION_FLAGS, 0);
878 changedInstallPermission = true;
879 }
880
881 // If the permission is not to be promoted to runtime we ignore it and
882 // also its other flags as they are not applicable to install permissions.
883 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
884 for (int userId : currentUserIds) {
885 if (permissionsState.grantRuntimePermission(bp, userId) !=
886 PermissionsState.PERMISSION_OPERATION_FAILURE) {
887 // Transfer the permission flags.
888 permissionsState.updatePermissionFlags(bp, userId,
889 flags, flags);
890 // If we granted the permission, we have to write.
891 updatedUserIds = ArrayUtils.appendInt(
892 updatedUserIds, userId);
893 }
894 }
895 }
896 } break;
897
898 default: {
899 if (packageOfInterest == null
900 || packageOfInterest.equals(pkg.packageName)) {
901 if (DEBUG_PERMISSIONS) {
902 Slog.i(TAG, "Not granting permission " + perm
903 + " to package " + pkg.packageName
904 + " because it was previously installed without");
905 }
906 }
907 } break;
908 }
909 } else {
910 if (permissionsState.revokeInstallPermission(bp) !=
911 PermissionsState.PERMISSION_OPERATION_FAILURE) {
912 // Also drop the permission flags.
913 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
914 PackageManager.MASK_PERMISSION_FLAGS, 0);
915 changedInstallPermission = true;
916 Slog.i(TAG, "Un-granting permission " + perm
917 + " from package " + pkg.packageName
918 + " (protectionLevel=" + bp.getProtectionLevel()
919 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
920 + ")");
921 } else if (bp.isAppOp()) {
922 // Don't print warning for app op permissions, since it is fine for them
923 // not to be granted, there is a UI for the user to decide.
924 if (DEBUG_PERMISSIONS
925 && (packageOfInterest == null
926 || packageOfInterest.equals(pkg.packageName))) {
927 Slog.i(TAG, "Not granting permission " + perm
928 + " to package " + pkg.packageName
929 + " (protectionLevel=" + bp.getProtectionLevel()
930 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
931 + ")");
932 }
933 }
934 }
935 }
936
937 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
938 !ps.isSystem() || ps.isUpdatedSystem()) {
939 // This is the first that we have heard about this package, so the
940 // permissions we have now selected are fixed until explicitly
941 // changed.
942 ps.setInstallPermissionsFixed(true);
943 }
944 }
945
946 // Persist the runtime permissions state for users with changes. If permissions
947 // were revoked because no app in the shared user declares them we have to
948 // write synchronously to avoid losing runtime permissions state.
949 if (callback != null) {
950 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
951 }
952 }
953
954 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
955 boolean allowed = false;
956 final int NP = PackageParser.NEW_PERMISSIONS.length;
957 for (int ip=0; ip<NP; ip++) {
958 final PackageParser.NewPermissionInfo npi
959 = PackageParser.NEW_PERMISSIONS[ip];
960 if (npi.name.equals(perm)
961 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
962 allowed = true;
963 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
964 + pkg.packageName);
965 break;
966 }
967 }
968 return allowed;
969 }
970
971 /**
972 * Determines whether a package is whitelisted for a particular privapp permission.
973 *
974 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
975 *
976 * <p>This handles parent/child apps.
977 */
978 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
979 ArraySet<String> wlPermissions = SystemConfig.getInstance()
980 .getPrivAppPermissions(pkg.packageName);
981 // Let's check if this package is whitelisted...
982 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
983 // If it's not, we'll also tail-recurse to the parent.
984 return whitelisted ||
985 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
986 }
987
988 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
989 BasePermission bp, PermissionsState origPermissions) {
990 boolean oemPermission = bp.isOEM();
991 boolean privilegedPermission = bp.isPrivileged();
992 boolean privappPermissionsDisable =
993 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
994 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
995 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
996 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
997 && !platformPackage && platformPermission) {
998 if (!hasPrivappWhitelistEntry(perm, pkg)) {
999 Slog.w(TAG, "Privileged permission " + perm + " for package "
1000 + pkg.packageName + " - not in privapp-permissions whitelist");
1001 // Only report violations for apps on system image
1002 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1003 // it's only a reportable violation if the permission isn't explicitly denied
1004 final ArraySet<String> deniedPermissions = SystemConfig.getInstance()
1005 .getPrivAppDenyPermissions(pkg.packageName);
1006 final boolean permissionViolation =
1007 deniedPermissions == null || !deniedPermissions.contains(perm);
1008 if (permissionViolation
1009 && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1010 if (mPrivappPermissionsViolations == null) {
1011 mPrivappPermissionsViolations = new ArraySet<>();
1012 }
1013 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
1014 } else {
1015 return false;
1016 }
1017 }
1018 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1019 return false;
1020 }
1021 }
1022 }
1023 final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1024 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1025 final PackageParser.Package systemPackage =
1026 mPackageManagerInt.getPackage(systemPackageName);
1027 boolean allowed = (PackageManagerService.compareSignatures(
1028 bp.getSourceSignatures(), pkg.mSignatures)
1029 == PackageManager.SIGNATURE_MATCH)
1030 || (PackageManagerService.compareSignatures(
1031 systemPackage.mSignatures, pkg.mSignatures)
1032 == PackageManager.SIGNATURE_MATCH);
1033 if (!allowed && (privilegedPermission || oemPermission)) {
1034 if (pkg.isSystem()) {
1035 // For updated system applications, a privileged/oem permission
1036 // is granted only if it had been defined by the original application.
1037 if (pkg.isUpdatedSystemApp()) {
1038 final PackageParser.Package disabledPkg =
1039 mPackageManagerInt.getDisabledPackage(pkg.packageName);
1040 final PackageSetting disabledPs =
1041 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1042 if (disabledPs != null
1043 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1044 // If the original was granted this permission, we take
1045 // that grant decision as read and propagate it to the
1046 // update.
1047 if ((privilegedPermission && disabledPs.isPrivileged())
1048 || (oemPermission && disabledPs.isOem()
1049 && canGrantOemPermission(disabledPs, perm))) {
1050 allowed = true;
1051 }
1052 } else {
1053 // The system apk may have been updated with an older
1054 // version of the one on the data partition, but which
1055 // granted a new system permission that it didn't have
1056 // before. In this case we do want to allow the app to
1057 // now get the new permission if the ancestral apk is
1058 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001059 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001060 && isPackageRequestingPermission(disabledPkg, perm)
1061 && ((privilegedPermission && disabledPs.isPrivileged())
1062 || (oemPermission && disabledPs.isOem()
1063 && canGrantOemPermission(disabledPs, perm)))) {
1064 allowed = true;
1065 }
1066 // Also if a privileged parent package on the system image or any of
1067 // its children requested a privileged/oem permission, the updated child
1068 // packages can also get the permission.
1069 if (pkg.parentPackage != null) {
1070 final PackageParser.Package disabledParentPkg = mPackageManagerInt
1071 .getDisabledPackage(pkg.parentPackage.packageName);
1072 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1073 ? (PackageSetting) disabledParentPkg.mExtras : null;
1074 if (disabledParentPkg != null
1075 && ((privilegedPermission && disabledParentPs.isPrivileged())
1076 || (oemPermission && disabledParentPs.isOem()))) {
1077 if (isPackageRequestingPermission(disabledParentPkg, perm)
1078 && canGrantOemPermission(disabledParentPs, perm)) {
1079 allowed = true;
1080 } else if (disabledParentPkg.childPackages != null) {
1081 for (PackageParser.Package disabledChildPkg
1082 : disabledParentPkg.childPackages) {
1083 final PackageSetting disabledChildPs =
1084 (disabledChildPkg != null)
1085 ? (PackageSetting) disabledChildPkg.mExtras
1086 : null;
1087 if (isPackageRequestingPermission(disabledChildPkg, perm)
1088 && canGrantOemPermission(
1089 disabledChildPs, perm)) {
1090 allowed = true;
1091 break;
1092 }
1093 }
1094 }
1095 }
1096 }
1097 }
1098 } else {
1099 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1100 allowed = (privilegedPermission && pkg.isPrivileged())
1101 || (oemPermission && pkg.isOem()
1102 && canGrantOemPermission(ps, perm));
1103 }
1104 }
1105 }
1106 if (!allowed) {
1107 if (!allowed
1108 && bp.isPre23()
1109 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1110 // If this was a previously normal/dangerous permission that got moved
1111 // to a system permission as part of the runtime permission redesign, then
1112 // we still want to blindly grant it to old apps.
1113 allowed = true;
1114 }
1115 if (!allowed && bp.isInstaller()
1116 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1117 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))) {
1118 // If this permission is to be granted to the system installer and
1119 // this app is an installer, then it gets the permission.
1120 allowed = true;
1121 }
1122 if (!allowed && bp.isVerifier()
1123 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1124 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1125 // If this permission is to be granted to the system verifier and
1126 // this app is a verifier, then it gets the permission.
1127 allowed = true;
1128 }
1129 if (!allowed && bp.isPreInstalled()
1130 && pkg.isSystem()) {
1131 // Any pre-installed system app is allowed to get this permission.
1132 allowed = true;
1133 }
1134 if (!allowed && bp.isDevelopment()) {
1135 // For development permissions, a development permission
1136 // is granted only if it was already granted.
1137 allowed = origPermissions.hasInstallPermission(perm);
1138 }
1139 if (!allowed && bp.isSetup()
1140 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1141 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1142 // If this permission is to be granted to the system setup wizard and
1143 // this app is a setup wizard, then it gets the permission.
1144 allowed = true;
1145 }
1146 }
1147 return allowed;
1148 }
1149
1150 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1151 if (!ps.isOem()) {
1152 return false;
1153 }
1154 // all oem permissions must explicitly be granted or denied
1155 final Boolean granted =
1156 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1157 if (granted == null) {
1158 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1159 + ps.name + " must be explicitly declared granted or not");
1160 }
1161 return Boolean.TRUE == granted;
1162 }
1163
1164 private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
1165 if (!mSettings.mPermissionReviewRequired) {
1166 return false;
1167 }
1168
1169 // Permission review applies only to apps not supporting the new permission model.
1170 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1171 return false;
1172 }
1173
1174 // Legacy apps have the permission and get user consent on launch.
1175 if (pkg == null || pkg.mExtras == null) {
1176 return false;
1177 }
1178 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1179 final PermissionsState permissionsState = ps.getPermissionsState();
1180 return permissionsState.isPermissionReviewRequired(userId);
1181 }
1182
1183 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1184 final int permCount = pkg.requestedPermissions.size();
1185 for (int j = 0; j < permCount; j++) {
1186 String requestedPermission = pkg.requestedPermissions.get(j);
1187 if (permission.equals(requestedPermission)) {
1188 return true;
1189 }
1190 }
1191 return false;
1192 }
1193
Todd Kennedy0eb97382017-10-03 16:57:22 -07001194 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1195 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1196 if (pkg.parentPackage == null) {
1197 return;
1198 }
1199 if (pkg.requestedPermissions == null) {
1200 return;
1201 }
1202 final PackageParser.Package disabledPkg =
1203 mPackageManagerInt.getDisabledPackage(pkg.parentPackage.packageName);
1204 if (disabledPkg == null || disabledPkg.mExtras == null) {
1205 return;
1206 }
1207 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1208 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1209 return;
1210 }
1211 final int permCount = pkg.requestedPermissions.size();
1212 for (int i = 0; i < permCount; i++) {
1213 String permission = pkg.requestedPermissions.get(i);
1214 BasePermission bp = mSettings.getPermissionLocked(permission);
1215 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1216 continue;
1217 }
1218 for (int userId : mUserManagerInt.getUserIds()) {
1219 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1220 grantRuntimePermission(
1221 permission, pkg.packageName, false, callingUid, userId, callback);
1222 }
1223 }
1224 }
1225 }
1226
1227 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1228 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1229 for (int userId : userIds) {
1230 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1231 callback);
1232 }
1233 }
1234
1235 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1236 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1237 PackageSetting ps = (PackageSetting) pkg.mExtras;
1238 if (ps == null) {
1239 return;
1240 }
1241
1242 PermissionsState permissionsState = ps.getPermissionsState();
1243
1244 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1245 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1246
1247 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1248 >= Build.VERSION_CODES.M;
1249
1250 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
1251
1252 for (String permission : pkg.requestedPermissions) {
1253 final BasePermission bp;
1254 synchronized (mLock) {
1255 bp = mSettings.getPermissionLocked(permission);
1256 }
1257 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1258 && (!instantApp || bp.isInstant())
1259 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
1260 && (grantedPermissions == null
1261 || ArrayUtils.contains(grantedPermissions, permission))) {
1262 final int flags = permissionsState.getPermissionFlags(permission, userId);
1263 if (supportsRuntimePermissions) {
1264 // Installer cannot change immutable permissions.
1265 if ((flags & immutableFlags) == 0) {
1266 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
1267 userId, callback);
1268 }
1269 } else if (mSettings.mPermissionReviewRequired) {
1270 // In permission review mode we clear the review flag when we
1271 // are asked to install the app with all permissions granted.
1272 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1273 updatePermissionFlags(permission, pkg.packageName,
1274 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
1275 userId, callback);
1276 }
1277 }
1278 }
1279 }
1280 }
1281
1282 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
1283 int callingUid, final int userId, PermissionCallback callback) {
1284 if (!mUserManagerInt.exists(userId)) {
1285 Log.e(TAG, "No such user:" + userId);
1286 return;
1287 }
1288
1289 mContext.enforceCallingOrSelfPermission(
1290 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1291 "grantRuntimePermission");
1292
1293 enforceCrossUserPermission(callingUid, userId,
1294 true /* requireFullPermission */, true /* checkShell */,
1295 "grantRuntimePermission");
1296
1297 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1298 if (pkg == null || pkg.mExtras == null) {
1299 throw new IllegalArgumentException("Unknown package: " + packageName);
1300 }
1301 final BasePermission bp;
1302 synchronized(mLock) {
1303 bp = mSettings.getPermissionLocked(permName);
1304 }
1305 if (bp == null) {
1306 throw new IllegalArgumentException("Unknown permission: " + permName);
1307 }
1308 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1309 throw new IllegalArgumentException("Unknown package: " + packageName);
1310 }
1311
1312 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1313
1314 // If a permission review is required for legacy apps we represent
1315 // their permissions as always granted runtime ones since we need
1316 // to keep the review required permission flag per user while an
1317 // install permission's state is shared across all users.
1318 if (mSettings.mPermissionReviewRequired
1319 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
1320 && bp.isRuntime()) {
1321 return;
1322 }
1323
1324 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1325
1326 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1327 final PermissionsState permissionsState = ps.getPermissionsState();
1328
1329 final int flags = permissionsState.getPermissionFlags(permName, userId);
1330 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1331 throw new SecurityException("Cannot grant system fixed permission "
1332 + permName + " for package " + packageName);
1333 }
1334 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1335 throw new SecurityException("Cannot grant policy fixed permission "
1336 + permName + " for package " + packageName);
1337 }
1338
1339 if (bp.isDevelopment()) {
1340 // Development permissions must be handled specially, since they are not
1341 // normal runtime permissions. For now they apply to all users.
1342 if (permissionsState.grantInstallPermission(bp) !=
1343 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1344 if (callback != null) {
1345 callback.onInstallPermissionGranted();
1346 }
1347 }
1348 return;
1349 }
1350
1351 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1352 throw new SecurityException("Cannot grant non-ephemeral permission"
1353 + permName + " for package " + packageName);
1354 }
1355
1356 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1357 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1358 return;
1359 }
1360
1361 final int result = permissionsState.grantRuntimePermission(bp, userId);
1362 switch (result) {
1363 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
1364 return;
1365 }
1366
1367 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1368 if (callback != null) {
1369 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
1370 }
1371 }
1372 break;
1373 }
1374
1375 if (bp.isRuntime()) {
1376 logPermissionGranted(mContext, permName, packageName);
1377 }
1378
1379 if (callback != null) {
1380 callback.onPermissionGranted(uid, userId);
1381 }
1382
1383 // Only need to do this if user is initialized. Otherwise it's a new user
1384 // and there are no processes running as the user yet and there's no need
1385 // to make an expensive call to remount processes for the changed permissions.
1386 if (READ_EXTERNAL_STORAGE.equals(permName)
1387 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1388 final long token = Binder.clearCallingIdentity();
1389 try {
1390 if (mUserManagerInt.isUserInitialized(userId)) {
1391 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1392 StorageManagerInternal.class);
1393 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1394 }
1395 } finally {
1396 Binder.restoreCallingIdentity(token);
1397 }
1398 }
1399
1400 }
1401
1402 private void revokeRuntimePermission(String permName, String packageName,
1403 boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) {
1404 if (!mUserManagerInt.exists(userId)) {
1405 Log.e(TAG, "No such user:" + userId);
1406 return;
1407 }
1408
1409 mContext.enforceCallingOrSelfPermission(
1410 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1411 "revokeRuntimePermission");
1412
1413 enforceCrossUserPermission(Binder.getCallingUid(), userId,
1414 true /* requireFullPermission */, true /* checkShell */,
1415 "revokeRuntimePermission");
1416
1417 final int appId;
1418
1419 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1420 if (pkg == null || pkg.mExtras == null) {
1421 throw new IllegalArgumentException("Unknown package: " + packageName);
1422 }
1423 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
1424 throw new IllegalArgumentException("Unknown package: " + packageName);
1425 }
1426 final BasePermission bp = mSettings.getPermissionLocked(permName);
1427 if (bp == null) {
1428 throw new IllegalArgumentException("Unknown permission: " + permName);
1429 }
1430
1431 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1432
1433 // If a permission review is required for legacy apps we represent
1434 // their permissions as always granted runtime ones since we need
1435 // to keep the review required permission flag per user while an
1436 // install permission's state is shared across all users.
1437 if (mSettings.mPermissionReviewRequired
1438 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
1439 && bp.isRuntime()) {
1440 return;
1441 }
1442
1443 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1444 final PermissionsState permissionsState = ps.getPermissionsState();
1445
1446 final int flags = permissionsState.getPermissionFlags(permName, userId);
1447 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1448 throw new SecurityException("Cannot revoke system fixed permission "
1449 + permName + " for package " + packageName);
1450 }
1451 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1452 throw new SecurityException("Cannot revoke policy fixed permission "
1453 + permName + " for package " + packageName);
1454 }
1455
1456 if (bp.isDevelopment()) {
1457 // Development permissions must be handled specially, since they are not
1458 // normal runtime permissions. For now they apply to all users.
1459 if (permissionsState.revokeInstallPermission(bp) !=
1460 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1461 if (callback != null) {
1462 callback.onInstallPermissionRevoked();
1463 }
1464 }
1465 return;
1466 }
1467
1468 if (permissionsState.revokeRuntimePermission(bp, userId) ==
1469 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1470 return;
1471 }
1472
1473 if (bp.isRuntime()) {
1474 logPermissionRevoked(mContext, permName, packageName);
1475 }
1476
1477 if (callback != null) {
1478 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1479 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
1480 }
1481 }
1482
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001483 private int[] revokeUnusedSharedUserPermissionsLocked(
1484 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001485 // Collect all used permissions in the UID
1486 final ArraySet<String> usedPermissions = new ArraySet<>();
1487 final List<PackageParser.Package> pkgList = suSetting.getPackages();
1488 if (pkgList == null || pkgList.size() == 0) {
1489 return EmptyArray.INT;
1490 }
1491 for (PackageParser.Package pkg : pkgList) {
1492 final int requestedPermCount = pkg.requestedPermissions.size();
1493 for (int j = 0; j < requestedPermCount; j++) {
1494 String permission = pkg.requestedPermissions.get(j);
1495 BasePermission bp = mSettings.getPermissionLocked(permission);
1496 if (bp != null) {
1497 usedPermissions.add(permission);
1498 }
1499 }
1500 }
1501
1502 PermissionsState permissionsState = suSetting.getPermissionsState();
1503 // Prune install permissions
1504 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
1505 final int installPermCount = installPermStates.size();
1506 for (int i = installPermCount - 1; i >= 0; i--) {
1507 PermissionState permissionState = installPermStates.get(i);
1508 if (!usedPermissions.contains(permissionState.getName())) {
1509 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1510 if (bp != null) {
1511 permissionsState.revokeInstallPermission(bp);
1512 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1513 PackageManager.MASK_PERMISSION_FLAGS, 0);
1514 }
1515 }
1516 }
1517
1518 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
1519
1520 // Prune runtime permissions
1521 for (int userId : allUserIds) {
1522 List<PermissionState> runtimePermStates = permissionsState
1523 .getRuntimePermissionStates(userId);
1524 final int runtimePermCount = runtimePermStates.size();
1525 for (int i = runtimePermCount - 1; i >= 0; i--) {
1526 PermissionState permissionState = runtimePermStates.get(i);
1527 if (!usedPermissions.contains(permissionState.getName())) {
1528 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1529 if (bp != null) {
1530 permissionsState.revokeRuntimePermission(bp, userId);
1531 permissionsState.updatePermissionFlags(bp, userId,
1532 PackageManager.MASK_PERMISSION_FLAGS, 0);
1533 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
1534 runtimePermissionChangedUserIds, userId);
1535 }
1536 }
1537 }
1538 }
1539
1540 return runtimePermissionChangedUserIds;
1541 }
1542
Todd Kennedyc8423932017-10-05 08:58:36 -07001543 private String[] getAppOpPermissionPackages(String permName) {
1544 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
1545 return null;
1546 }
1547 synchronized (mLock) {
1548 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
1549 if (pkgs == null) {
1550 return null;
1551 }
1552 return pkgs.toArray(new String[pkgs.size()]);
1553 }
1554 }
1555
1556 private int getPermissionFlags(
1557 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001558 if (!mUserManagerInt.exists(userId)) {
1559 return 0;
1560 }
1561
1562 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
1563
1564 enforceCrossUserPermission(callingUid, userId,
1565 true /* requireFullPermission */, false /* checkShell */,
1566 "getPermissionFlags");
1567
1568 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1569 if (pkg == null || pkg.mExtras == null) {
1570 return 0;
1571 }
1572 synchronized (mLock) {
1573 if (mSettings.getPermissionLocked(permName) == null) {
1574 return 0;
1575 }
1576 }
1577 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1578 return 0;
1579 }
1580 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1581 PermissionsState permissionsState = ps.getPermissionsState();
1582 return permissionsState.getPermissionFlags(permName, userId);
1583 }
1584
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001585 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
1586 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
1587 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
1588
1589 private void updatePermissions(String packageName, PackageParser.Package pkg,
1590 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
1591 PermissionCallback callback) {
1592 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
1593 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
1594 updatePermissions(
1595 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
1596 if (pkg != null && pkg.childPackages != null) {
1597 for (PackageParser.Package childPkg : pkg.childPackages) {
1598 updatePermissions(childPkg.packageName, childPkg,
1599 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
1600 }
1601 }
1602 }
1603
1604 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
1605 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
1606 final int flags = UPDATE_PERMISSIONS_ALL |
1607 (sdkUpdated
1608 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
1609 : 0);
1610 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
1611 }
1612
1613 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
1614 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
1615 PermissionCallback callback) {
1616 // TODO: Most of the methods exposing BasePermission internals [source package name,
1617 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
1618 // have package settings, we should make note of it elsewhere [map between
1619 // source package name and BasePermission] and cycle through that here. Then we
1620 // define a single method on BasePermission that takes a PackageSetting, changing
1621 // package name and a package.
1622 // NOTE: With this approach, we also don't need to tree trees differently than
1623 // normal permissions. Today, we need two separate loops because these BasePermission
1624 // objects are stored separately.
1625 // Make sure there are no dangling permission trees.
1626 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
1627
1628 // Make sure all dynamic permissions have been assigned to a package,
1629 // and make sure there are no dangling permissions.
1630 flags = updatePermissions(changingPkgName, changingPkg, flags);
1631
1632 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
1633 // Now update the permissions for all packages, in particular
1634 // replace the granted permissions of the system packages.
1635 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
1636 for (PackageParser.Package pkg : allPackages) {
1637 if (pkg != changingPkg) {
1638 // Only replace for packages on requested volume
1639 final String volumeUuid = getVolumeUuidForPackage(pkg);
1640 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
1641 && Objects.equals(replaceVolumeUuid, volumeUuid);
1642 grantPermissions(pkg, replace, changingPkgName, callback);
1643 }
1644 }
1645 }
1646
1647 if (changingPkg != null) {
1648 // Only replace for packages on requested volume
1649 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
1650 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
1651 && Objects.equals(replaceVolumeUuid, volumeUuid);
1652 grantPermissions(changingPkg, replace, changingPkgName, callback);
1653 }
1654 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1655 }
1656
1657 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001658 Set<BasePermission> needsUpdate = null;
1659 synchronized (mLock) {
1660 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
1661 while (it.hasNext()) {
1662 final BasePermission bp = it.next();
1663 if (bp.isDynamic()) {
1664 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
1665 }
1666 if (bp.getSourcePackageSetting() != null) {
1667 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001668 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001669 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
1670 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001671 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07001672 it.remove();
1673 }
1674 continue;
1675 }
1676 if (needsUpdate == null) {
1677 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
1678 }
1679 needsUpdate.add(bp);
1680 }
1681 }
1682 if (needsUpdate != null) {
1683 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001684 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07001685 mPackageManagerInt.getPackage(bp.getSourcePackageName());
1686 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001687 if (sourcePkg != null && sourcePkg.mExtras != null) {
1688 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07001689 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001690 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07001691 }
1692 continue;
1693 }
1694 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
1695 + " from package " + bp.getSourcePackageName());
1696 mSettings.removePermissionLocked(bp.getName());
1697 }
1698 }
1699 }
1700 return flags;
1701 }
1702
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001703 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07001704 int flags) {
1705 Set<BasePermission> needsUpdate = null;
1706 synchronized (mLock) {
1707 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
1708 while (it.hasNext()) {
1709 final BasePermission bp = it.next();
1710 if (bp.getSourcePackageSetting() != null) {
1711 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001712 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001713 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
1714 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001715 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07001716 it.remove();
1717 }
1718 continue;
1719 }
1720 if (needsUpdate == null) {
1721 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
1722 }
1723 needsUpdate.add(bp);
1724 }
1725 }
1726 if (needsUpdate != null) {
1727 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001728 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07001729 mPackageManagerInt.getPackage(bp.getSourcePackageName());
1730 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001731 if (sourcePkg != null && sourcePkg.mExtras != null) {
1732 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07001733 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001734 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07001735 }
1736 continue;
1737 }
1738 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
1739 + " from package " + bp.getSourcePackageName());
1740 mSettings.removePermissionLocked(bp.getName());
1741 }
1742 }
1743 }
1744 return flags;
1745 }
1746
Todd Kennedy0eb97382017-10-03 16:57:22 -07001747 private void updatePermissionFlags(String permName, String packageName, int flagMask,
1748 int flagValues, int callingUid, int userId, PermissionCallback callback) {
1749 if (!mUserManagerInt.exists(userId)) {
1750 return;
1751 }
1752
1753 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
1754
1755 enforceCrossUserPermission(callingUid, userId,
1756 true /* requireFullPermission */, true /* checkShell */,
1757 "updatePermissionFlags");
1758
1759 // Only the system can change these flags and nothing else.
1760 if (callingUid != Process.SYSTEM_UID) {
1761 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1762 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1763 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1764 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1765 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
1766 }
1767
1768 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1769 if (pkg == null || pkg.mExtras == null) {
1770 throw new IllegalArgumentException("Unknown package: " + packageName);
1771 }
1772 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1773 throw new IllegalArgumentException("Unknown package: " + packageName);
1774 }
1775
1776 final BasePermission bp;
1777 synchronized (mLock) {
1778 bp = mSettings.getPermissionLocked(permName);
1779 }
1780 if (bp == null) {
1781 throw new IllegalArgumentException("Unknown permission: " + permName);
1782 }
1783
1784 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1785 final PermissionsState permissionsState = ps.getPermissionsState();
1786 final boolean hadState =
1787 permissionsState.getRuntimePermissionState(permName, userId) != null;
1788 final boolean permissionUpdated =
1789 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
1790 if (permissionUpdated && callback != null) {
1791 // Install and runtime permissions are stored in different places,
1792 // so figure out what permission changed and persist the change.
1793 if (permissionsState.getInstallPermissionState(permName) != null) {
1794 callback.onInstallPermissionUpdated();
1795 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
1796 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001797 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001798 }
1799 }
1800 }
1801
1802 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
1803 int userId, Collection<Package> packages, PermissionCallback callback) {
1804 if (!mUserManagerInt.exists(userId)) {
1805 return false;
1806 }
1807
1808 enforceGrantRevokeRuntimePermissionPermissions(
1809 "updatePermissionFlagsForAllApps");
1810 enforceCrossUserPermission(callingUid, userId,
1811 true /* requireFullPermission */, true /* checkShell */,
1812 "updatePermissionFlagsForAllApps");
1813
1814 // Only the system can change system fixed flags.
1815 if (callingUid != Process.SYSTEM_UID) {
1816 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1817 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1818 }
1819
1820 boolean changed = false;
1821 for (PackageParser.Package pkg : packages) {
1822 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1823 if (ps == null) {
1824 continue;
1825 }
1826 PermissionsState permissionsState = ps.getPermissionsState();
1827 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
1828 userId, flagMask, flagValues);
1829 }
1830 return changed;
1831 }
1832
1833 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
1834 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
1835 != PackageManager.PERMISSION_GRANTED
1836 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
1837 != PackageManager.PERMISSION_GRANTED) {
1838 throw new SecurityException(message + " requires "
1839 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
1840 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
1841 }
1842 }
1843
1844 /**
1845 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
1846 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
1847 * @param checkShell whether to prevent shell from access if there's a debugging restriction
1848 * @param message the message to log on security exception
1849 */
1850 private void enforceCrossUserPermission(int callingUid, int userId,
1851 boolean requireFullPermission, boolean checkShell, String message) {
1852 if (userId < 0) {
1853 throw new IllegalArgumentException("Invalid userId " + userId);
1854 }
1855 if (checkShell) {
1856 PackageManagerServiceUtils.enforceShellRestriction(
1857 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
1858 }
1859 if (userId == UserHandle.getUserId(callingUid)) return;
1860 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
1861 if (requireFullPermission) {
1862 mContext.enforceCallingOrSelfPermission(
1863 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
1864 } else {
1865 try {
1866 mContext.enforceCallingOrSelfPermission(
1867 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
1868 } catch (SecurityException se) {
1869 mContext.enforceCallingOrSelfPermission(
1870 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
1871 }
1872 }
1873 }
1874 }
1875
1876 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
1877 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07001878 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001879 size += tree.calculateFootprint(perm);
1880 }
1881 return size;
1882 }
1883
1884 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
1885 // We calculate the max size of permissions defined by this uid and throw
1886 // if that plus the size of 'info' would exceed our stated maximum.
1887 if (tree.getUid() != Process.SYSTEM_UID) {
1888 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
1889 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
1890 throw new SecurityException("Permission tree size cap exceeded");
1891 }
1892 }
1893 }
1894
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001895 private void systemReady() {
1896 mSystemReady = true;
1897 if (mPrivappPermissionsViolations != null) {
1898 throw new IllegalStateException("Signature|privileged permissions not in "
1899 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
1900 }
1901 }
1902
1903 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
1904 if (pkg == null) {
1905 return StorageManager.UUID_PRIVATE_INTERNAL;
1906 }
1907 if (pkg.isExternal()) {
1908 if (TextUtils.isEmpty(pkg.volumeUuid)) {
1909 return StorageManager.UUID_PRIMARY_PHYSICAL;
1910 } else {
1911 return pkg.volumeUuid;
1912 }
1913 } else {
1914 return StorageManager.UUID_PRIVATE_INTERNAL;
1915 }
1916 }
1917
Todd Kennedyc8423932017-10-05 08:58:36 -07001918 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
1919 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
1920 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
1921 return true;
1922 }
1923 }
1924 return false;
1925 }
1926
Todd Kennedy0eb97382017-10-03 16:57:22 -07001927 /**
1928 * Get the first event id for the permission.
1929 *
1930 * <p>There are four events for each permission: <ul>
1931 * <li>Request permission: first id + 0</li>
1932 * <li>Grant permission: first id + 1</li>
1933 * <li>Request for permission denied: first id + 2</li>
1934 * <li>Revoke permission: first id + 3</li>
1935 * </ul></p>
1936 *
1937 * @param name name of the permission
1938 *
1939 * @return The first event id for the permission
1940 */
1941 private static int getBaseEventId(@NonNull String name) {
1942 int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
1943
1944 if (eventIdIndex == -1) {
1945 if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
1946 || Build.IS_USER) {
1947 Log.i(TAG, "Unknown permission " + name);
1948
1949 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
1950 } else {
1951 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
1952 //
1953 // Also update
1954 // - EventLogger#ALL_DANGEROUS_PERMISSIONS
1955 // - metrics_constants.proto
1956 throw new IllegalStateException("Unknown permission " + name);
1957 }
1958 }
1959
1960 return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
1961 }
1962
1963 /**
1964 * Log that a permission was revoked.
1965 *
1966 * @param context Context of the caller
1967 * @param name name of the permission
1968 * @param packageName package permission if for
1969 */
1970 private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
1971 @NonNull String packageName) {
1972 MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
1973 }
1974
1975 /**
1976 * Log that a permission request was granted.
1977 *
1978 * @param context Context of the caller
1979 * @param name name of the permission
1980 * @param packageName package permission if for
1981 */
1982 private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
1983 @NonNull String packageName) {
1984 MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
1985 }
1986
1987 private class PermissionManagerInternalImpl extends PermissionManagerInternal {
1988 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001989 public void systemReady() {
1990 PermissionManagerService.this.systemReady();
1991 }
1992 @Override
1993 public boolean isPermissionsReviewRequired(Package pkg, int userId) {
1994 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
1995 }
1996 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07001997 public void addAllPermissions(Package pkg, boolean chatty) {
1998 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001999 }
2000 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002001 public void addAllPermissionGroups(Package pkg, boolean chatty) {
2002 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
2003 }
2004 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002005 public void removeAllPermissions(Package pkg, boolean chatty) {
2006 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
2007 }
2008 @Override
2009 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07002010 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002011 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
2012 }
2013 @Override
2014 public void removeDynamicPermission(String permName, int callingUid,
2015 PermissionCallback callback) {
2016 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002017 }
2018 @Override
2019 public void grantRuntimePermission(String permName, String packageName,
2020 boolean overridePolicy, int callingUid, int userId,
2021 PermissionCallback callback) {
2022 PermissionManagerService.this.grantRuntimePermission(
2023 permName, packageName, overridePolicy, callingUid, userId, callback);
2024 }
2025 @Override
2026 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2027 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2028 PermissionManagerService.this.grantRequestedRuntimePermissions(
2029 pkg, userIds, grantedPermissions, callingUid, callback);
2030 }
2031 @Override
2032 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
2033 int callingUid, PermissionCallback callback) {
2034 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
2035 pkg, callingUid, callback);
2036 }
2037 @Override
2038 public void revokeRuntimePermission(String permName, String packageName,
2039 boolean overridePolicy, int callingUid, int userId,
2040 PermissionCallback callback) {
2041 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
2042 overridePolicy, callingUid, userId, callback);
2043 }
2044 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002045 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
2046 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2047 PermissionManagerService.this.updatePermissions(
2048 packageName, pkg, replaceGrant, allPackages, callback);
2049 }
2050 @Override
2051 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2052 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2053 PermissionManagerService.this.updateAllPermissions(
2054 volumeUuid, sdkUpdated, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002055 }
2056 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002057 public String[] getAppOpPermissionPackages(String permName) {
2058 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
2059 }
2060 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002061 public int getPermissionFlags(String permName, String packageName, int callingUid,
2062 int userId) {
2063 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
2064 callingUid, userId);
2065 }
2066 @Override
2067 public void updatePermissionFlags(String permName, String packageName, int flagMask,
2068 int flagValues, int callingUid, int userId, PermissionCallback callback) {
2069 PermissionManagerService.this.updatePermissionFlags(
2070 permName, packageName, flagMask, flagValues, callingUid, userId, callback);
2071 }
2072 @Override
2073 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2074 int userId, Collection<Package> packages, PermissionCallback callback) {
2075 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
2076 flagMask, flagValues, callingUid, userId, packages, callback);
2077 }
2078 @Override
2079 public void enforceCrossUserPermission(int callingUid, int userId,
2080 boolean requireFullPermission, boolean checkShell, String message) {
2081 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
2082 requireFullPermission, checkShell, message);
2083 }
2084 @Override
2085 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2086 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
2087 }
2088 @Override
2089 public int checkPermission(String permName, String packageName, int callingUid,
2090 int userId) {
2091 return PermissionManagerService.this.checkPermission(
2092 permName, packageName, callingUid, userId);
2093 }
2094 @Override
Todd Kennedy3bc94722017-10-10 09:55:53 -07002095 public int checkUidPermission(String permName, int uid, int callingUid) {
2096 return PermissionManagerService.this.checkUidPermission(permName, uid, callingUid);
2097 }
2098 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002099 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
2100 int callingUid) {
2101 return PermissionManagerService.this.getPermissionGroupInfo(
2102 groupName, flags, callingUid);
2103 }
2104 @Override
2105 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
2106 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
2107 }
2108 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002109 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
2110 int callingUid) {
2111 return PermissionManagerService.this.getPermissionInfo(
2112 permName, packageName, flags, callingUid);
2113 }
2114 @Override
2115 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
2116 int callingUid) {
2117 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
2118 }
2119 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002120 public PermissionSettings getPermissionSettings() {
2121 return mSettings;
2122 }
2123 @Override
2124 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
2125 return mDefaultPermissionGrantPolicy;
2126 }
2127 @Override
2128 public BasePermission getPermissionTEMP(String permName) {
2129 synchronized (PermissionManagerService.this.mLock) {
2130 return mSettings.getPermissionLocked(permName);
2131 }
2132 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002133 }
2134}