blob: d67144e8ce3943bf25ace4ba7bb6fb4cb9fb6758 [file] [log] [blame]
Kenny Rootcf0b38c2011-03-22 14:17:59 -07001/*
2 * Copyright (C) 2011 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;
18
Todd Kennedy0eb97382017-10-03 16:57:22 -070019import android.annotation.Nullable;
Jeff Vander Stoepd1cf4992018-01-11 16:09:58 -080020import android.content.pm.ApplicationInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070021import android.content.pm.PackageParser;
Sudheer Shankad68bd602018-11-13 17:43:39 -080022import android.os.storage.StorageManager;
Yi Jind6759d42017-10-12 15:08:49 -070023import android.service.pm.PackageServiceDumpProto;
Jeff Sharkey9f837a92014-10-24 12:07:24 -070024import android.util.ArraySet;
Yi Jind6759d42017-10-12 15:08:49 -070025import android.util.proto.ProtoOutputStream;
Kenny Rootcf0b38c2011-03-22 14:17:59 -070026
Sudheer Shanka12783cb2018-10-18 08:53:02 -070027import com.android.internal.util.ArrayUtils;
28
29import libcore.util.EmptyArray;
30
Todd Kennedy0eb97382017-10-03 16:57:22 -070031import java.util.ArrayList;
Todd Kennedy0eb97382017-10-03 16:57:22 -070032import java.util.List;
33
Kenny Rootcf0b38c2011-03-22 14:17:59 -070034/**
35 * Settings data for a particular shared user ID we know about.
36 */
Todd Kennedy0eb97382017-10-03 16:57:22 -070037public final class SharedUserSetting extends SettingBase {
Kenny Rootcf0b38c2011-03-22 14:17:59 -070038 final String name;
39
40 int userId;
41
Ben Gruverdd72c9e2013-08-06 12:34:17 -070042 // flags that are associated with this uid, regardless of any package flags
43 int uidFlags;
Alex Klyubinb9f8a522015-02-03 11:12:59 -080044 int uidPrivateFlags;
Ben Gruverdd72c9e2013-08-06 12:34:17 -070045
Jeff Vander Stoepcab36392018-03-06 15:52:22 -080046 // The lowest targetSdkVersion of all apps in the sharedUserSetting, used to assign seinfo so
47 // that all apps within the sharedUser run in the same selinux context.
48 int seInfoTargetSdkVersion;
49
Jeff Sharkey9f837a92014-10-24 12:07:24 -070050 final ArraySet<PackageSetting> packages = new ArraySet<PackageSetting>();
Kenny Rootcf0b38c2011-03-22 14:17:59 -070051
52 final PackageSignatures signatures = new PackageSignatures();
Bryan Henryad8a0da2018-05-06 13:36:17 -070053 Boolean signaturesChanged;
Kenny Rootcf0b38c2011-03-22 14:17:59 -070054
Alex Klyubinb9f8a522015-02-03 11:12:59 -080055 SharedUserSetting(String _name, int _pkgFlags, int _pkgPrivateFlags) {
56 super(_pkgFlags, _pkgPrivateFlags);
Ben Gruverdd72c9e2013-08-06 12:34:17 -070057 uidFlags = _pkgFlags;
Alex Klyubinb9f8a522015-02-03 11:12:59 -080058 uidPrivateFlags = _pkgPrivateFlags;
Kenny Rootcf0b38c2011-03-22 14:17:59 -070059 name = _name;
Joel Galensondfd822b2018-04-03 10:46:24 -070060 seInfoTargetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
Kenny Rootcf0b38c2011-03-22 14:17:59 -070061 }
62
63 @Override
64 public String toString() {
65 return "SharedUserSetting{" + Integer.toHexString(System.identityHashCode(this)) + " "
66 + name + "/" + userId + "}";
67 }
Ben Gruverdd72c9e2013-08-06 12:34:17 -070068
Yi Jind6759d42017-10-12 15:08:49 -070069 public void writeToProto(ProtoOutputStream proto, long fieldId) {
70 long token = proto.start(fieldId);
Kweku Adams87c60a02018-06-13 12:13:52 -070071 proto.write(PackageServiceDumpProto.SharedUserProto.UID, userId);
Yi Jind6759d42017-10-12 15:08:49 -070072 proto.write(PackageServiceDumpProto.SharedUserProto.NAME, name);
73 proto.end(token);
74 }
75
Patrick4ccae942018-07-17 09:15:55 -070076 boolean removePackage(PackageSetting packageSetting) {
77 if (!packages.remove(packageSetting)) {
78 return false;
Ben Gruverdd72c9e2013-08-06 12:34:17 -070079 }
Patrick4ccae942018-07-17 09:15:55 -070080 // recalculate the pkgFlags for this shared user if needed
81 if ((this.pkgFlags & packageSetting.pkgFlags) != 0) {
82 int aggregatedFlags = uidFlags;
83 for (PackageSetting ps : packages) {
84 aggregatedFlags |= ps.pkgFlags;
85 }
86 setFlags(aggregatedFlags);
87 }
88 if ((this.pkgPrivateFlags & packageSetting.pkgPrivateFlags) != 0) {
89 int aggregatedPrivateFlags = uidPrivateFlags;
90 for (PackageSetting ps : packages) {
91 aggregatedPrivateFlags |= ps.pkgPrivateFlags;
92 }
93 setPrivateFlags(aggregatedPrivateFlags);
94 }
95 return true;
Ben Gruverdd72c9e2013-08-06 12:34:17 -070096 }
97
98 void addPackage(PackageSetting packageSetting) {
Jeff Vander Stoepcab36392018-03-06 15:52:22 -080099 // If this is the first package added to this shared user, temporarily (until next boot) use
100 // its targetSdkVersion when assigning seInfo for the shared user.
101 if ((packages.size() == 0) && (packageSetting.pkg != null)) {
102 seInfoTargetSdkVersion = packageSetting.pkg.applicationInfo.targetSdkVersion;
103 }
Ben Gruverdd72c9e2013-08-06 12:34:17 -0700104 if (packages.add(packageSetting)) {
105 setFlags(this.pkgFlags | packageSetting.pkgFlags);
Alex Klyubinb9f8a522015-02-03 11:12:59 -0800106 setPrivateFlags(this.pkgPrivateFlags | packageSetting.pkgPrivateFlags);
Ben Gruverdd72c9e2013-08-06 12:34:17 -0700107 }
108 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700109
110 public @Nullable List<PackageParser.Package> getPackages() {
111 if (packages == null || packages.size() == 0) {
112 return null;
113 }
114 final ArrayList<PackageParser.Package> pkgList = new ArrayList<>(packages.size());
115 for (PackageSetting ps : packages) {
Jeff Vander Stoep0a4c63f2018-03-06 13:28:29 -0800116 if ((ps == null) || (ps.pkg == null)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700117 continue;
118 }
119 pkgList.add(ps.pkg);
120 }
121 return pkgList;
122 }
Jeff Vander Stoepd1cf4992018-01-11 16:09:58 -0800123
124 public boolean isPrivileged() {
125 return (this.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
126 }
Jeff Vander Stoepcab36392018-03-06 15:52:22 -0800127
128 /**
129 * Determine the targetSdkVersion for a sharedUser and update pkg.applicationInfo.seInfo
130 * to ensure that all apps within the sharedUser share an SELinux domain. Use the lowest
131 * targetSdkVersion of all apps within the shared user, which corresponds to the least
132 * restrictive selinux domain.
133 */
134 public void fixSeInfoLocked() {
135 final List<PackageParser.Package> pkgList = getPackages();
Jeff Vander Stoep54807bb2018-03-08 09:49:33 -0800136 if (pkgList == null || pkgList.size() == 0) {
137 return;
138 }
Jeff Vander Stoepcab36392018-03-06 15:52:22 -0800139
140 for (PackageParser.Package pkg : pkgList) {
141 if (pkg.applicationInfo.targetSdkVersion < seInfoTargetSdkVersion) {
142 seInfoTargetSdkVersion = pkg.applicationInfo.targetSdkVersion;
143 }
144 }
145 for (PackageParser.Package pkg : pkgList) {
146 final boolean isPrivileged = isPrivileged() | pkg.isPrivileged();
147 pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
148 pkg.applicationInfo.targetSandboxVersion, seInfoTargetSdkVersion);
149 }
150 }
151
Sudheer Shanka12783cb2018-10-18 08:53:02 -0700152 /** Returns userIds which doesn't have any packages with this sharedUserId */
153 public int[] getNotInstalledUserIds() {
154 int[] excludedUserIds = null;
155 for (PackageSetting ps : packages) {
156 final int[] userIds = ps.getNotInstalledUserIds();
157 if (excludedUserIds == null) {
158 excludedUserIds = userIds;
159 } else {
160 for (int userId : excludedUserIds) {
161 if (!ArrayUtils.contains(userIds, userId)) {
162 excludedUserIds = ArrayUtils.removeInt(excludedUserIds, userId);
163 }
164 }
165 }
166 }
167 return excludedUserIds == null ? EmptyArray.INT : excludedUserIds;
168 }
169
Sudheer Shankad68bd602018-11-13 17:43:39 -0800170 public String getStorageSandboxName() {
171 return StorageManager.SHARED_SANDBOX_PREFIX + name;
Sudheer Shanka12783cb2018-10-18 08:53:02 -0700172 }
173
Patrick4ccae942018-07-17 09:15:55 -0700174 /** Updates all fields in this shared user setting from another. */
175 public SharedUserSetting updateFrom(SharedUserSetting sharedUser) {
176 copyFrom(sharedUser);
177 this.userId = sharedUser.userId;
178 this.uidFlags = sharedUser.uidFlags;
179 this.uidPrivateFlags = sharedUser.uidPrivateFlags;
180 this.seInfoTargetSdkVersion = sharedUser.seInfoTargetSdkVersion;
181 this.packages.clear();
182 this.packages.addAll(sharedUser.packages);
183 this.signaturesChanged = sharedUser.signaturesChanged;
184 return this;
185 }
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700186}