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