1 /*
2  * Copyright (C) 2018 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/tracing/core/packet_stream_validator.h"
18 
19 #include <string>
20 
21 #include "gtest/gtest.h"
22 
23 #include "perfetto/trace/trace_packet.pb.h"
24 
25 namespace perfetto {
26 namespace {
27 
TEST(PacketStreamValidatorTest,NullPacket)28 TEST(PacketStreamValidatorTest, NullPacket) {
29   std::string ser_buf;
30   Slices seq;
31   EXPECT_TRUE(PacketStreamValidator::Validate(seq));
32 }
33 
TEST(PacketStreamValidatorTest,SimplePacket)34 TEST(PacketStreamValidatorTest, SimplePacket) {
35   protos::TracePacket proto;
36   proto.mutable_for_testing()->set_str("string field");
37   std::string ser_buf = proto.SerializeAsString();
38 
39   Slices seq;
40   seq.emplace_back(&ser_buf[0], ser_buf.size());
41   EXPECT_TRUE(PacketStreamValidator::Validate(seq));
42 }
43 
TEST(PacketStreamValidatorTest,ComplexPacket)44 TEST(PacketStreamValidatorTest, ComplexPacket) {
45   protos::TracePacket proto;
46   proto.mutable_for_testing()->set_str("string field");
47   proto.mutable_ftrace_events()->set_cpu(0);
48   auto* ft = proto.mutable_ftrace_events()->add_event();
49   ft->set_pid(42);
50   ft->mutable_sched_switch()->set_prev_comm("tom");
51   ft->mutable_sched_switch()->set_prev_pid(123);
52   ft->mutable_sched_switch()->set_next_comm("jerry");
53   ft->mutable_sched_switch()->set_next_pid(456);
54   std::string ser_buf = proto.SerializeAsString();
55 
56   Slices seq;
57   seq.emplace_back(&ser_buf[0], ser_buf.size());
58   EXPECT_TRUE(PacketStreamValidator::Validate(seq));
59 }
60 
TEST(PacketStreamValidatorTest,SimplePacketWithUid)61 TEST(PacketStreamValidatorTest, SimplePacketWithUid) {
62   protos::TracePacket proto;
63   proto.set_trusted_uid(123);
64   std::string ser_buf = proto.SerializeAsString();
65 
66   Slices seq;
67   seq.emplace_back(&ser_buf[0], ser_buf.size());
68   EXPECT_FALSE(PacketStreamValidator::Validate(seq));
69 }
70 
TEST(PacketStreamValidatorTest,SimplePacketWithZeroUid)71 TEST(PacketStreamValidatorTest, SimplePacketWithZeroUid) {
72   protos::TracePacket proto;
73   proto.set_trusted_uid(0);
74   std::string ser_buf = proto.SerializeAsString();
75 
76   Slices seq;
77   seq.emplace_back(&ser_buf[0], ser_buf.size());
78   EXPECT_FALSE(PacketStreamValidator::Validate(seq));
79 }
80 
TEST(PacketStreamValidatorTest,SimplePacketWithNegativeOneUid)81 TEST(PacketStreamValidatorTest, SimplePacketWithNegativeOneUid) {
82   protos::TracePacket proto;
83   proto.set_trusted_uid(-1);
84   std::string ser_buf = proto.SerializeAsString();
85 
86   Slices seq;
87   seq.emplace_back(&ser_buf[0], ser_buf.size());
88   EXPECT_FALSE(PacketStreamValidator::Validate(seq));
89 }
90 
TEST(PacketStreamValidatorTest,ComplexPacketWithUid)91 TEST(PacketStreamValidatorTest, ComplexPacketWithUid) {
92   protos::TracePacket proto;
93   proto.mutable_for_testing()->set_str("string field");
94   proto.mutable_ftrace_events()->set_cpu(0);
95   auto* ft = proto.mutable_ftrace_events()->add_event();
96   ft->set_pid(42);
97   ft->mutable_sched_switch()->set_prev_comm("tom");
98   ft->mutable_sched_switch()->set_prev_pid(123);
99   ft->mutable_sched_switch()->set_next_comm("jerry");
100   ft->mutable_sched_switch()->set_next_pid(456);
101   proto.set_trusted_uid(123);
102   std::string ser_buf = proto.SerializeAsString();
103 
104   Slices seq;
105   seq.emplace_back(&ser_buf[0], ser_buf.size());
106   EXPECT_FALSE(PacketStreamValidator::Validate(seq));
107 }
108 
TEST(PacketStreamValidatorTest,FragmentedPacket)109 TEST(PacketStreamValidatorTest, FragmentedPacket) {
110   protos::TracePacket proto;
111   proto.mutable_for_testing()->set_str("string field");
112   proto.mutable_ftrace_events()->set_cpu(0);
113   auto* ft = proto.mutable_ftrace_events()->add_event();
114   ft->set_pid(42);
115   ft->mutable_sched_switch()->set_prev_comm("tom");
116   ft->mutable_sched_switch()->set_prev_pid(123);
117   ft->mutable_sched_switch()->set_next_comm("jerry");
118   ft->mutable_sched_switch()->set_next_pid(456);
119   std::string ser_buf = proto.SerializeAsString();
120 
121   for (size_t i = 0; i < ser_buf.size(); i++) {
122     Slices seq;
123     seq.emplace_back(&ser_buf[0], i);
124     seq.emplace_back(&ser_buf[i], ser_buf.size() - i);
125     EXPECT_TRUE(PacketStreamValidator::Validate(seq));
126   }
127 }
128 
TEST(PacketStreamValidatorTest,FragmentedPacketWithUid)129 TEST(PacketStreamValidatorTest, FragmentedPacketWithUid) {
130   protos::TracePacket proto;
131   proto.mutable_for_testing()->set_str("string field");
132   proto.set_trusted_uid(123);
133   proto.mutable_ftrace_events()->set_cpu(0);
134   auto* ft = proto.mutable_ftrace_events()->add_event();
135   ft->set_pid(42);
136   ft->mutable_sched_switch()->set_prev_comm("tom");
137   ft->mutable_sched_switch()->set_prev_pid(123);
138   ft->mutable_sched_switch()->set_next_comm("jerry");
139   ft->mutable_sched_switch()->set_next_pid(456);
140   proto.mutable_for_testing()->set_str("foo");
141   std::string ser_buf = proto.SerializeAsString();
142 
143   for (size_t i = 0; i < ser_buf.size(); i++) {
144     Slices seq;
145     seq.emplace_back(&ser_buf[0], i);
146     seq.emplace_back(&ser_buf[i], ser_buf.size() - i);
147     EXPECT_FALSE(PacketStreamValidator::Validate(seq));
148   }
149 }
150 
TEST(PacketStreamValidatorTest,TruncatedPacket)151 TEST(PacketStreamValidatorTest, TruncatedPacket) {
152   protos::TracePacket proto;
153   proto.mutable_for_testing()->set_str("string field");
154   std::string ser_buf = proto.SerializeAsString();
155 
156   for (size_t i = 1; i < ser_buf.size(); i++) {
157     Slices seq;
158     seq.emplace_back(&ser_buf[0], i);
159     EXPECT_FALSE(PacketStreamValidator::Validate(seq));
160   }
161 }
162 
TEST(PacketStreamValidatorTest,TrailingGarbage)163 TEST(PacketStreamValidatorTest, TrailingGarbage) {
164   protos::TracePacket proto;
165   proto.mutable_for_testing()->set_str("string field");
166   std::string ser_buf = proto.SerializeAsString();
167   ser_buf += "bike is short for bichael";
168 
169   Slices seq;
170   seq.emplace_back(&ser_buf[0], ser_buf.size());
171   EXPECT_FALSE(PacketStreamValidator::Validate(seq));
172 }
173 
174 }  // namespace
175 }  // namespace perfetto
176