1 /*
2 * Copyright (C) 2020 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
17 #include "src/profiling/common/producer_support.h"
18
19 #include <stdio.h>
20
21 #include "perfetto/ext/base/file_utils.h"
22 #include "perfetto/ext/base/string_utils.h"
23 #include "perfetto/ext/base/temp_file.h"
24 #include "perfetto/ext/base/utils.h"
25 #include "perfetto/tracing/core/data_source_config.h"
26 #include "test/gtest_and_gmock.h"
27
28 namespace perfetto {
29 namespace profiling {
30 namespace {
31
ShellInitiator()32 DataSourceConfig ShellInitiator() {
33 DataSourceConfig ds_config;
34 ds_config.set_session_initiator(
35 DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
36 return ds_config;
37 }
38
TrustedInitiator()39 DataSourceConfig TrustedInitiator() {
40 DataSourceConfig ds_config;
41 ds_config.set_session_initiator(
42 DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM);
43 return ds_config;
44 }
45
46 // pkgName - package name
47 // userId - application-specific user id
48 // debugFlag - 0 or 1 if the package is debuggable.
49 // dataPath - path to package's data path
50 // seinfo - seinfo label for the app (assigned at install time)
51 // gids - supplementary gids this app launches with
52 // profileableFromShellFlag - 0 or 1 if the package is profileable from shell.
53 // longVersionCode - integer version of the package.
54 // profileable - 0 or 1 if the package is profileable by the platform.
55 // packageInstaller - the package that installed this app, or @system, @product
56 // or @null.
PackageListLine(unsigned long uid,bool debuggable,bool profileable_from_shell,bool profileable,const char * installer)57 std::string PackageListLine(unsigned long uid,
58 bool debuggable,
59 bool profileable_from_shell,
60 bool profileable,
61 const char* installer) {
62 base::StackString<256> ss(
63 "com.package.name %lu %d /data/user/0/com.package.name "
64 "platform:privapp:targetSdkVersion=29 1065,3003 %d 500 %d %s\n",
65 uid, debuggable, profileable_from_shell, profileable, installer);
66 return ss.ToStdString();
67 }
68
TEST(CanProfileAndroidTest,DebuggableBuild)69 TEST(CanProfileAndroidTest, DebuggableBuild) {
70 unsigned pkg_uid = 10001;
71 std::string content = PackageListLine(
72 pkg_uid, /*debuggable=*/false, /*profileable_from_shell=*/false,
73 /*profileable=*/false, /*installer=*/"@system");
74 auto tmp = base::TempFile::Create();
75 base::WriteAll(tmp.fd(), content.c_str(), content.size());
76
77 // non-app UIDs can be profiled
78 EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), /*uid=*/200,
79 /*installed_by=*/{}, "userdebug", tmp.path()));
80 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), /*uid=*/200,
81 /*installed_by=*/{}, "userdebug", tmp.path()));
82
83 // app UIDs can be profiled, regardless of manifest
84 EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), pkg_uid, /*installed_by=*/{},
85 "userdebug", tmp.path()));
86 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), pkg_uid,
87 /*installed_by=*/{}, "userdebug", tmp.path()));
88 }
89
TEST(CanProfileAndroidTest,DebuggableApp)90 TEST(CanProfileAndroidTest, DebuggableApp) {
91 unsigned uid = 10001;
92 std::string content = PackageListLine(
93 uid, /*debuggable=*/true, /*profileable_from_shell=*/false,
94 /*profileable=*/false, /*installer=*/"@system");
95 auto tmp = base::TempFile::Create();
96 base::WriteAll(tmp.fd(), content.c_str(), content.size());
97
98 // Debuggable apps can always be profiled (without installer constraint)
99 EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), uid, /*installed_by=*/{},
100 "user", tmp.path()));
101 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid, /*installed_by=*/{},
102 "user", tmp.path()));
103 }
104
TEST(CanProfileAndroidTest,NonProfileableApp)105 TEST(CanProfileAndroidTest, NonProfileableApp) {
106 unsigned uid = 10002;
107 std::string content = PackageListLine(
108 uid, /*debuggable=*/false, /*profileable_from_shell=*/false,
109 /*profileable=*/false, /*installer=*/"@system");
110 auto tmp = base::TempFile::Create();
111 base::WriteAll(tmp.fd(), content.c_str(), content.size());
112
113 // Opted out packages cannot be profiled
114 EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid, /*installed_by=*/{},
115 "user", tmp.path()));
116 EXPECT_FALSE(CanProfileAndroid(TrustedInitiator(), uid, /*installed_by=*/{},
117 "user", tmp.path()));
118 }
119
TEST(CanProfileAndroidTest,ProfileableApp)120 TEST(CanProfileAndroidTest, ProfileableApp) {
121 unsigned uid = 10004;
122 std::string content = PackageListLine(
123 uid, /*debuggable=*/false, /*profileable_from_shell=*/false,
124 /*profileable=*/true, /*installer=*/"@system");
125 auto tmp = base::TempFile::Create();
126 base::WriteAll(tmp.fd(), content.c_str(), content.size());
127
128 // Only profileable by the platform
129 EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid, /*installed_by=*/{},
130 "user", tmp.path()));
131 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid, /*installed_by=*/{},
132 "user", tmp.path()));
133 }
134
TEST(CanProfileAndroidTest,ProfileableFromShellApp)135 TEST(CanProfileAndroidTest, ProfileableFromShellApp) {
136 unsigned uid = 10001;
137 std::string content = PackageListLine(
138 uid, /*debuggable=*/false, /*profileable_from_shell=*/true,
139 /*profileable=*/true, /*installer=*/"@system");
140 auto tmp = base::TempFile::Create();
141 base::WriteAll(tmp.fd(), content.c_str(), content.size());
142
143 EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), uid, /*installed_by=*/{},
144 "user", tmp.path()));
145 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid, /*installed_by=*/{},
146 "user", tmp.path()));
147 }
148
149 // As ProfileableApp, but with a user profile offset
TEST(CanProfileAndroidTest,UserProfileUidOffset)150 TEST(CanProfileAndroidTest, UserProfileUidOffset) {
151 unsigned u0_uid = 10199;
152 std::string content = PackageListLine(
153 u0_uid, /*debuggable=*/false, /*profileable_from_shell=*/false,
154 /*profileable=*/true, /*installer=*/"@system");
155 auto tmp = base::TempFile::Create();
156 base::WriteAll(tmp.fd(), content.c_str(), content.size());
157
158 // Only profileable by the platform
159 EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), u0_uid, /*installed_by=*/{},
160 "user", tmp.path()));
161 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), u0_uid, /*installed_by=*/{},
162 "user", tmp.path()));
163 unsigned u10_uid = 1010199;
164 EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), u10_uid, /*installed_by=*/{},
165 "user", tmp.path()));
166 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), u10_uid,
167 /*installed_by=*/{}, "user", tmp.path()));
168 }
169
170 // As ProfileableFromShellApp, but with installer constraints
TEST(CanProfileAndroidTest,InstallerPackageConstraint)171 TEST(CanProfileAndroidTest, InstallerPackageConstraint) {
172 unsigned uid_installed_by_system = 10001;
173 unsigned uid_installed_by_store = 10003;
174 std::string content =
175 PackageListLine(uid_installed_by_system, /*debuggable=*/false,
176 /*profileable_from_shell=*/true,
177 /*profileable=*/true, /*installer=*/"@system");
178 content += PackageListLine( //
179 uid_installed_by_store, /*debuggable=*/false,
180 /*profileable_from_shell=*/true,
181 /*profileable=*/true, /*installer=*/"com.installer.package");
182 auto tmp = base::TempFile::Create();
183 base::WriteAll(tmp.fd(), content.c_str(), content.size());
184
185 // Can profile if installer in the list (and other checks pass)
186 // @system installer:
187 EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), uid_installed_by_system,
188 /*installed_by=*/{"@product", "@system"},
189 "user", tmp.path()));
190 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid_installed_by_system,
191 /*installed_by=*/{"@product", "@system"},
192 "user", tmp.path()));
193 EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid_installed_by_system,
194 /*installed_by=*/{"@product"}, "user",
195 tmp.path()));
196 EXPECT_FALSE(CanProfileAndroid(TrustedInitiator(), uid_installed_by_system,
197 /*installed_by=*/{"@product"}, "user",
198 tmp.path()));
199
200 // com.installer.package installer:
201 EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), uid_installed_by_store,
202 /*installed_by=*/{"com.installer.package"},
203 "user", tmp.path()));
204 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid_installed_by_store,
205 /*installed_by=*/{"com.installer.package"},
206 "user", tmp.path()));
207 EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid_installed_by_store,
208 /*installed_by=*/{"@product"}, "user",
209 tmp.path()));
210 EXPECT_FALSE(CanProfileAndroid(TrustedInitiator(), uid_installed_by_store,
211 /*installed_by=*/{"@product"}, "user",
212 tmp.path()));
213 }
214
TEST(CanProfileAndroidTest,AppSandboxProcess)215 TEST(CanProfileAndroidTest, AppSandboxProcess) {
216 unsigned uid_profileable_app = 10004;
217 unsigned uid_nonprofileable_app = 10007;
218 std::string content =
219 PackageListLine(uid_profileable_app, /*debuggable=*/false,
220 /*profileable_from_shell=*/true,
221 /*profileable=*/true, /*installer=*/"@system");
222 content += //
223 PackageListLine(uid_nonprofileable_app, /*debuggable=*/false,
224 /*profileable_from_shell=*/false,
225 /*profileable=*/false, /*installer=*/"@system");
226 auto tmp = base::TempFile::Create();
227 base::WriteAll(tmp.fd(), content.c_str(), content.size());
228
229 // Sandbox profileable if the app is profileable
230 unsigned uid_profileable_sandbox = 20004;
231 EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), uid_profileable_sandbox,
232 /*installed_by=*/{}, "user", tmp.path()));
233 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid_profileable_sandbox,
234 /*installed_by=*/{}, "user", tmp.path()));
235
236 unsigned uid_nonprofileable_sandbox = 20007;
237 EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid_nonprofileable_sandbox,
238 /*installed_by=*/{}, "user", tmp.path()));
239 EXPECT_FALSE(CanProfileAndroid(TrustedInitiator(), uid_nonprofileable_sandbox,
240 /*installed_by=*/{}, "user", tmp.path()));
241 }
242
TEST(CanProfileAndroidTest,IsolatedProcess)243 TEST(CanProfileAndroidTest, IsolatedProcess) {
244 {
245 // Packages list with only profileable packages
246 unsigned uid_app = 10199;
247 std::string content =
248 PackageListLine(10003, /*debuggable=*/false,
249 /*profileable_from_shell=*/true,
250 /*profileable=*/true, /*installer=*/"@system");
251 content += //
252 PackageListLine(uid_app, /*debuggable=*/false,
253 /*profileable_from_shell=*/false,
254 /*profileable=*/true, /*installer=*/"@system");
255 content += //
256 PackageListLine(10008, /*debuggable=*/true,
257 /*profileable_from_shell=*/true,
258 /*profileable=*/true, /*installer=*/"@system");
259 auto tmp = base::TempFile::Create();
260 base::WriteAll(tmp.fd(), content.c_str(), content.size());
261
262 // Any isolated process is thus profileable by trusted initiators
263 unsigned uid_isolated = 90100;
264 EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid_isolated,
265 /*installed_by=*/{}, "user", tmp.path()));
266 EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid_isolated,
267 /*installed_by=*/{}, "user", tmp.path()));
268 }
269 {
270 // Packages list with an opted out package
271 unsigned uid_app = 10199;
272 std::string content =
273 PackageListLine(10003, /*debuggable=*/false,
274 /*profileable_from_shell=*/true,
275 /*profileable=*/true, /*installer=*/"@system");
276 content += //
277 PackageListLine(uid_app, /*debuggable=*/false,
278 /*profileable_from_shell=*/false,
279 /*profileable=*/true, /*installer=*/"@system");
280 content += //
281 PackageListLine(10008, /*debuggable=*/false,
282 /*profileable_from_shell=*/false,
283 /*profileable=*/false, /*installer=*/"@system");
284 auto tmp = base::TempFile::Create();
285 base::WriteAll(tmp.fd(), content.c_str(), content.size());
286
287 // Conservatively conclude that an isolated process is not profileable
288 unsigned uid_isolated = 90100;
289 EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid_isolated,
290 /*installed_by=*/{}, "user", tmp.path()));
291 EXPECT_FALSE(CanProfileAndroid(TrustedInitiator(), uid_isolated,
292 /*installed_by=*/{}, "user", tmp.path()));
293 }
294 }
295
296 } // namespace
297 } // namespace profiling
298 } // namespace perfetto
299