xref: /aosp_15_r20/external/perfetto/src/trace_redaction/find_package_uid_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 
2 /*
3  * Copyright (C) 2024 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <cstdint>
19 #include <string>
20 
21 #include "src/base/test/status_matchers.h"
22 #include "src/trace_redaction/find_package_uid.h"
23 #include "test/gtest_and_gmock.h"
24 
25 #include "protos/perfetto/trace/android/packages_list.gen.h"
26 #include "protos/perfetto/trace/ps/process_tree.gen.h"
27 #include "protos/perfetto/trace/trace_packet.gen.h"
28 
29 namespace perfetto::trace_redaction {
30 
31 namespace {
32 
33 // packet {
34 //   trusted_uid: 9999
35 //   trusted_packet_sequence_id: 2
36 //   previous_packet_dropped: true
37 //   packages_list {
38 //     packages {
39 //       name: "com.shannon.qualifiednetworksservice"
40 //       uid: 10201
41 //       debuggable: false
42 //       profileable_from_shell: false
43 //       version_code: 131
44 //     }
45 //     packages {
46 //       name: "com.google.android.uvexposurereporter"
47 //       uid: 10205
48 //       debuggable: false
49 //       profileable_from_shell: false
50 //       version_code: 34
51 //     }
52 //     packages {
53 //       name: "com.android.internal.display.cutout.emulation.noCutout"
54 //       uid: 10007
55 //       debuggable: false
56 //       profileable_from_shell: false
57 //       version_code: 1
58 //     }
59 //     packages {
60 //       name: "com.google.android.networkstack.tethering"
61 //       uid: 1073
62 //       debuggable: false
63 //       profileable_from_shell: false
64 //       version_code: 34
65 //     }
66 //     packages {
67 //       name: "com.amazon.mShop.android.shopping"
68 //       uid: 10303
69 //       debuggable: false
70 //       profileable_from_shell: false
71 //       version_code: 1241261011
72 //     }
73 //   }
74 //   trusted_pid: 1085
75 //   first_packet_on_sequence: true
76 // }
77 //
78 // packet {
79 //   process_tree {
80 //     processes {
81 //       pid: 23022
82 //       ppid: 1
83 //       cmdline: "/vendor/bin/hw/wpa_supplicant"
84 //       cmdline: "-O/data/vendor/wifi/wpa/sockets"
85 //       cmdline: "-dd"
86 //       cmdline: "-g@android:wpa_wlan0"
87 //       uid: 1010
88 //     }
89 //     threads {
90 //       tid: 6382
91 //       tgid: 18176
92 //     }
93 //     threads {
94 //      tid: 18419
95 //       tgid: 18176
96 //     }
97 //     threads {
98 //       tid: 18434
99 //       tgid: 18176
100 //     }
101 //     collection_end_timestamp: 333724398314653
102 //   }
103 //   trusted_uid: 9999
104 //   timestamp: 333724396714922
105 //   trusted_packet_sequence_id: 3
106 //   trusted_pid: 1085
107 // }
108 
AddPackage(const std::string & name,uint64_t uid,int version_code,protos::gen::PackagesList * list)109 void AddPackage(const std::string& name,
110                 uint64_t uid,
111                 int version_code,
112                 protos::gen::PackagesList* list) {
113   auto* pkg = list->add_packages();
114   pkg->set_name(name);
115   pkg->set_uid(uid);
116   pkg->set_version_code(version_code);
117 }
118 
AddProcess(protos::gen::ProcessTree * process_tree)119 void AddProcess(protos::gen::ProcessTree* process_tree) {
120   auto* p0 = process_tree->add_processes();
121   p0->set_pid(23022);
122   p0->set_ppid(1);
123   p0->add_cmdline("/vendor/bin/hw/wpa_supplicant");
124   p0->add_cmdline("-O/data/vendor/wifi/wpa/sockets");
125   p0->add_cmdline("-dd");
126   p0->add_cmdline("-g@android:wpa_wlan0");
127   p0->set_uid(1010);
128 }
129 
AddThread(int32_t tid,int32_t ttid,protos::gen::ProcessTree * process_tree)130 void AddThread(int32_t tid,
131                int32_t ttid,
132                protos::gen::ProcessTree* process_tree) {
133   auto* thread = process_tree->add_threads();
134   thread->set_tid(tid);
135   thread->set_tgid(ttid);
136 }
137 
CreatePackageListPacket()138 std::string CreatePackageListPacket() {
139   protos::gen::TracePacket packet;
140   packet.set_trusted_uid(9999);
141   packet.set_trusted_packet_sequence_id(2);
142   packet.set_previous_packet_dropped(true);
143   packet.set_trusted_pid(1085);
144   packet.set_first_packet_on_sequence(true);
145 
146   auto* package_list = packet.mutable_packages_list();
147 
148   AddPackage("com.shannon.qualifiednetworksservice", 10201, 131, package_list);
149   AddPackage("com.google.android.uvexposurereporter", 10205, 34, package_list);
150   AddPackage("com.android.internal.display.cutout.emulation.noCutout", 10007, 1,
151              package_list);
152   AddPackage("com.google.android.networkstack.tethering", 1073, 34,
153              package_list);
154   AddPackage("com.amazon.mShop.android.shopping", 10303, 1241261011,
155              package_list);
156 
157   return packet.SerializeAsString();
158 }
159 
CreateProcessTreePacket()160 std::string CreateProcessTreePacket() {
161   protos::gen::TracePacket packet;
162   packet.set_trusted_uid(9999);
163   packet.set_timestamp(333724396714922);
164   packet.set_trusted_packet_sequence_id(3);
165   packet.set_trusted_pid(1085);
166 
167   auto* tree = packet.mutable_process_tree();
168   tree->set_collection_end_timestamp(333724398314653);
169 
170   AddProcess(tree);
171   AddThread(6382, 18176, tree);
172   AddThread(18419, 18176, tree);
173   AddThread(18434, 18176, tree);
174 
175   return packet.SerializeAsString();
176 }
177 }  // namespace
178 
TEST(FindPackageUidTest,FindsUidInPackageList)179 TEST(FindPackageUidTest, FindsUidInPackageList) {
180   const auto packet = CreatePackageListPacket();
181 
182   Context context;
183   context.package_name = "com.google.android.uvexposurereporter";
184 
185   const FindPackageUid find;
186 
187   const auto decoder = protos::pbzero::TracePacket::Decoder(packet);
188 
189   base::Status status = find.Begin(&context);
190   ASSERT_OK(status) << status.message();
191 
192   status = find.Collect(decoder, &context);
193   ASSERT_OK(status) << status.message();
194 
195   status = find.End(&context);
196   ASSERT_OK(status) << status.message();
197 
198   ASSERT_TRUE(context.package_uid.has_value());
199 
200   // context.package_uid should have been normalized already.
201   ASSERT_EQ(context.package_uid.value(), NormalizeUid(10205));
202 }
203 
TEST(FindPackageUidTest,ContinuesOverNonPackageList)204 TEST(FindPackageUidTest, ContinuesOverNonPackageList) {
205   const auto packet = CreateProcessTreePacket();
206 
207   Context context;
208   context.package_name = "com.google.android.uvexposurereporter";
209 
210   const FindPackageUid find;
211 
212   const auto decoder = protos::pbzero::TracePacket::Decoder(packet);
213 
214   base::Status status = find.Begin(&context);
215   ASSERT_OK(status) << status.message();
216 
217   status = find.Collect(decoder, &context);
218   ASSERT_OK(status) << status.message();
219 
220   // The should not have been found; End() should return an error.
221   status = find.End(&context);
222   ASSERT_FALSE(status.ok()) << status.message();
223 
224   ASSERT_FALSE(context.package_uid.has_value());
225 }
226 
TEST(FindPackageUidTest,ContinuesOverPackageListWithOutPackageName)227 TEST(FindPackageUidTest, ContinuesOverPackageListWithOutPackageName) {
228   const auto packet = CreatePackageListPacket();
229 
230   Context context;
231   context.package_name = "com.not.a.packagename";
232 
233   const FindPackageUid find;
234 
235   const auto decoder = protos::pbzero::TracePacket::Decoder(packet);
236 
237   base::Status status = find.Begin(&context);
238   ASSERT_OK(status) << status.message();
239 
240   status = find.Collect(decoder, &context);
241   ASSERT_OK(status) << status.message();
242 
243   // The should not have been found; End() should return an error.
244   status = find.End(&context);
245   ASSERT_FALSE(status.ok()) << status.message();
246 
247   ASSERT_FALSE(context.package_uid.has_value());
248 }
249 
TEST(FindPackageUidTest,MissingPackageNameReturnsError)250 TEST(FindPackageUidTest, MissingPackageNameReturnsError) {
251   const auto packet = CreatePackageListPacket();
252 
253   Context context;
254 
255   const FindPackageUid find;
256 
257   const auto decoder = protos::pbzero::TracePacket::Decoder(packet);
258 
259   base::Status status = find.Begin(&context);
260   ASSERT_FALSE(status.ok()) << status.message();
261 }
262 
TEST(FindPackageUidTest,FailsIfUidStartsInitialized)263 TEST(FindPackageUidTest, FailsIfUidStartsInitialized) {
264   const auto packet = CreatePackageListPacket();
265 
266   Context context;
267   context.package_name = "com.google.android.uvexposurereporter";
268   context.package_uid = 1000;
269 
270   const FindPackageUid find;
271 
272   const auto decoder = protos::pbzero::TracePacket::Decoder(packet);
273 
274   base::Status status = find.Begin(&context);
275   ASSERT_FALSE(status.ok()) << status.message();
276 }
277 
278 }  // namespace perfetto::trace_redaction
279