xref: /aosp_15_r20/external/perfetto/src/profiling/common/producer_support_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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