1cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root/* 2cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * Copyright (C) 2011 The Android Open Source Project 3cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * 4cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * you may not use this file except in compliance with the License. 6cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * You may obtain a copy of the License at 7cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * 8cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * http://www.apache.org/licenses/LICENSE-2.0 9cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * 10cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * Unless required by applicable law or agreed to in writing, software 11cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * See the License for the specific language governing permissions and 14cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * limitations under the License. 15cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root */ 16cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 17cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootpackage com.android.server.pm; 18cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 190eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedyimport android.annotation.Nullable; 20d1cf49904ba79c70446f27b51e3d736bb1324009Jeff Vander Stoepimport android.content.pm.ApplicationInfo; 210eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedyimport android.content.pm.PackageParser; 22d6759d46f96fe2c8955751b0fe8037d6c8a75464Yi Jinimport android.service.pm.PackageServiceDumpProto; 239f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkeyimport android.util.ArraySet; 24d6759d46f96fe2c8955751b0fe8037d6c8a75464Yi Jinimport android.util.proto.ProtoOutputStream; 25cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 260eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedyimport java.util.ArrayList; 270eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedyimport java.util.Collection; 280eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedyimport java.util.List; 290eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy 30cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root/** 31cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * Settings data for a particular shared user ID we know about. 32cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root */ 330eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedypublic final class SharedUserSetting extends SettingBase { 34cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root final String name; 35cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 36cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root int userId; 37cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 38dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver // flags that are associated with this uid, regardless of any package flags 39dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver int uidFlags; 40b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin int uidPrivateFlags; 41dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver 42cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep // The lowest targetSdkVersion of all apps in the sharedUserSetting, used to assign seinfo so 43cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep // that all apps within the sharedUser run in the same selinux context. 44cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep int seInfoTargetSdkVersion; 45cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep 469f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey final ArraySet<PackageSetting> packages = new ArraySet<PackageSetting>(); 47cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 48cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root final PackageSignatures signatures = new PackageSignatures(); 49ad8a0da6a7b92e244953460068aebd4b40a5614eBryan Henry Boolean signaturesChanged; 50cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 51b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin SharedUserSetting(String _name, int _pkgFlags, int _pkgPrivateFlags) { 52b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin super(_pkgFlags, _pkgPrivateFlags); 53dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver uidFlags = _pkgFlags; 54b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin uidPrivateFlags = _pkgPrivateFlags; 55cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root name = _name; 56dfd822be8fff9aeb6bd0c2098708a79380fc0729Joel Galenson seInfoTargetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 57cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 58cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 59cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root @Override 60cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root public String toString() { 61cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return "SharedUserSetting{" + Integer.toHexString(System.identityHashCode(this)) + " " 62cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root + name + "/" + userId + "}"; 63cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 64dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver 65d6759d46f96fe2c8955751b0fe8037d6c8a75464Yi Jin public void writeToProto(ProtoOutputStream proto, long fieldId) { 66d6759d46f96fe2c8955751b0fe8037d6c8a75464Yi Jin long token = proto.start(fieldId); 67d6759d46f96fe2c8955751b0fe8037d6c8a75464Yi Jin proto.write(PackageServiceDumpProto.SharedUserProto.USER_ID, userId); 68d6759d46f96fe2c8955751b0fe8037d6c8a75464Yi Jin proto.write(PackageServiceDumpProto.SharedUserProto.NAME, name); 69d6759d46f96fe2c8955751b0fe8037d6c8a75464Yi Jin proto.end(token); 70d6759d46f96fe2c8955751b0fe8037d6c8a75464Yi Jin } 71d6759d46f96fe2c8955751b0fe8037d6c8a75464Yi Jin 72dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver void removePackage(PackageSetting packageSetting) { 73dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver if (packages.remove(packageSetting)) { 74dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver // recalculate the pkgFlags for this shared user if needed 75dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver if ((this.pkgFlags & packageSetting.pkgFlags) != 0) { 76dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver int aggregatedFlags = uidFlags; 77dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver for (PackageSetting ps : packages) { 78dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver aggregatedFlags |= ps.pkgFlags; 79dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver } 80dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver setFlags(aggregatedFlags); 81dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver } 82b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin if ((this.pkgPrivateFlags & packageSetting.pkgPrivateFlags) != 0) { 83b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin int aggregatedPrivateFlags = uidPrivateFlags; 84b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin for (PackageSetting ps : packages) { 85b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin aggregatedPrivateFlags |= ps.pkgPrivateFlags; 86b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin } 87b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin setPrivateFlags(aggregatedPrivateFlags); 88b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin } 89dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver } 90dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver } 91dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver 92dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver void addPackage(PackageSetting packageSetting) { 93cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep // If this is the first package added to this shared user, temporarily (until next boot) use 94cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep // its targetSdkVersion when assigning seInfo for the shared user. 95cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep if ((packages.size() == 0) && (packageSetting.pkg != null)) { 96cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep seInfoTargetSdkVersion = packageSetting.pkg.applicationInfo.targetSdkVersion; 97cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep } 98dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver if (packages.add(packageSetting)) { 99dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver setFlags(this.pkgFlags | packageSetting.pkgFlags); 100b9f8a5204a1b0b3919fa921e858d04124c582828Alex Klyubin setPrivateFlags(this.pkgPrivateFlags | packageSetting.pkgPrivateFlags); 101dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver } 102dd72c9ed558158f889a8cdfed8a108553ba5a562Ben Gruver } 1030eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy 1040eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy public @Nullable List<PackageParser.Package> getPackages() { 1050eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy if (packages == null || packages.size() == 0) { 1060eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy return null; 1070eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy } 1080eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy final ArrayList<PackageParser.Package> pkgList = new ArrayList<>(packages.size()); 1090eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy for (PackageSetting ps : packages) { 1100a4c63f958d133f15398900a26668d1e2661f783Jeff Vander Stoep if ((ps == null) || (ps.pkg == null)) { 1110eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy continue; 1120eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy } 1130eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy pkgList.add(ps.pkg); 1140eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy } 1150eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy return pkgList; 1160eb9738d1708d9aa7846782046e6828ffc9fe901Todd Kennedy } 117d1cf49904ba79c70446f27b51e3d736bb1324009Jeff Vander Stoep 118d1cf49904ba79c70446f27b51e3d736bb1324009Jeff Vander Stoep public boolean isPrivileged() { 119d1cf49904ba79c70446f27b51e3d736bb1324009Jeff Vander Stoep return (this.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 120d1cf49904ba79c70446f27b51e3d736bb1324009Jeff Vander Stoep } 121cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep 122cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep /** 123cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep * Determine the targetSdkVersion for a sharedUser and update pkg.applicationInfo.seInfo 124cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep * to ensure that all apps within the sharedUser share an SELinux domain. Use the lowest 125cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep * targetSdkVersion of all apps within the shared user, which corresponds to the least 126cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep * restrictive selinux domain. 127cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep */ 128cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep public void fixSeInfoLocked() { 129cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep final List<PackageParser.Package> pkgList = getPackages(); 13054807bb15b1a853ce09bf2ffce4f84f36cc37245Jeff Vander Stoep if (pkgList == null || pkgList.size() == 0) { 13154807bb15b1a853ce09bf2ffce4f84f36cc37245Jeff Vander Stoep return; 13254807bb15b1a853ce09bf2ffce4f84f36cc37245Jeff Vander Stoep } 133cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep 134cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep for (PackageParser.Package pkg : pkgList) { 135cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep if (pkg.applicationInfo.targetSdkVersion < seInfoTargetSdkVersion) { 136cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep seInfoTargetSdkVersion = pkg.applicationInfo.targetSdkVersion; 137cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep } 138cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep } 139cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep for (PackageParser.Package pkg : pkgList) { 140cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep final boolean isPrivileged = isPrivileged() | pkg.isPrivileged(); 141cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged, 142cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep pkg.applicationInfo.targetSandboxVersion, seInfoTargetSdkVersion); 143cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep } 144cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep } 145cab3639dcb609b70012744029508f7b19e09c24dJeff Vander Stoep 146cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root} 147