1 /*
2 * Copyright (C) 2017 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 #define STATSD_DEBUG false // STOPSHIP if true
17 #include "Log.h"
18
19 #include "matchers/matcher_util.h"
20
21 #include <fnmatch.h>
22
23 #include "matchers/AtomMatchingTracker.h"
24 #include "src/statsd_config.pb.h"
25 #include "stats_util.h"
26
27 using std::set;
28 using std::string;
29 using std::vector;
30
31 namespace android {
32 namespace os {
33 namespace statsd {
34
combinationMatch(const vector<int> & children,const LogicalOperation & operation,const vector<MatchingState> & matcherResults)35 bool combinationMatch(const vector<int>& children, const LogicalOperation& operation,
36 const vector<MatchingState>& matcherResults) {
37 bool matched;
38 switch (operation) {
39 case LogicalOperation::AND: {
40 matched = true;
41 for (const int childIndex : children) {
42 if (matcherResults[childIndex] != MatchingState::kMatched) {
43 matched = false;
44 break;
45 }
46 }
47 break;
48 }
49 case LogicalOperation::OR: {
50 matched = false;
51 for (const int childIndex : children) {
52 if (matcherResults[childIndex] == MatchingState::kMatched) {
53 matched = true;
54 break;
55 }
56 }
57 break;
58 }
59 case LogicalOperation::NOT:
60 matched = matcherResults[children[0]] == MatchingState::kNotMatched;
61 break;
62 case LogicalOperation::NAND:
63 matched = false;
64 for (const int childIndex : children) {
65 if (matcherResults[childIndex] != MatchingState::kMatched) {
66 matched = true;
67 break;
68 }
69 }
70 break;
71 case LogicalOperation::NOR:
72 matched = true;
73 for (const int childIndex : children) {
74 if (matcherResults[childIndex] == MatchingState::kMatched) {
75 matched = false;
76 break;
77 }
78 }
79 break;
80 case LogicalOperation::LOGICAL_OPERATION_UNSPECIFIED:
81 matched = false;
82 break;
83 }
84 return matched;
85 }
86
tryMatchString(const sp<UidMap> & uidMap,const FieldValue & fieldValue,const string & str_match)87 bool tryMatchString(const sp<UidMap>& uidMap, const FieldValue& fieldValue,
88 const string& str_match) {
89 if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) {
90 int uid = fieldValue.mValue.int_value;
91 auto aidIt = UidMap::sAidToUidMapping.find(str_match);
92 if (aidIt != UidMap::sAidToUidMapping.end()) {
93 return ((int)aidIt->second) == uid;
94 }
95 std::set<string> packageNames = uidMap->getAppNamesFromUid(uid, true /* normalize*/);
96 return packageNames.find(str_match) != packageNames.end();
97 } else if (fieldValue.mValue.getType() == STRING) {
98 return fieldValue.mValue.str_value == str_match;
99 }
100 return false;
101 }
102
tryMatchWildcardString(const sp<UidMap> & uidMap,const FieldValue & fieldValue,const string & wildcardPattern)103 bool tryMatchWildcardString(const sp<UidMap>& uidMap, const FieldValue& fieldValue,
104 const string& wildcardPattern) {
105 if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) {
106 int uid = fieldValue.mValue.int_value;
107 // TODO(b/236886985): replace aid/uid mapping with efficient bidirectional container
108 // AidToUidMapping will never have uids above 10000
109 if (uid < 10000) {
110 for (auto aidIt = UidMap::sAidToUidMapping.begin();
111 aidIt != UidMap::sAidToUidMapping.end(); ++aidIt) {
112 if ((int)aidIt->second == uid) {
113 // Assumes there is only one aid mapping for each uid
114 return fnmatch(wildcardPattern.c_str(), aidIt->first.c_str(), 0) == 0;
115 }
116 }
117 }
118 std::set<string> packageNames = uidMap->getAppNamesFromUid(uid, true /* normalize*/);
119 for (const auto& packageName : packageNames) {
120 if (fnmatch(wildcardPattern.c_str(), packageName.c_str(), 0) == 0) {
121 return true;
122 }
123 }
124 } else if (fieldValue.mValue.getType() == STRING) {
125 return fnmatch(wildcardPattern.c_str(), fieldValue.mValue.str_value.c_str(), 0) == 0;
126 }
127 return false;
128 }
129
matchesSimple(const sp<UidMap> & uidMap,const FieldValueMatcher & matcher,const vector<FieldValue> & values,int start,int end,int depth)130 bool matchesSimple(const sp<UidMap>& uidMap, const FieldValueMatcher& matcher,
131 const vector<FieldValue>& values, int start, int end, int depth) {
132 if (depth > 2) {
133 ALOGE("Depth > 3 not supported");
134 return false;
135 }
136
137 if (start >= end) {
138 return false;
139 }
140
141 // Filter by entry field first
142 int newStart = -1;
143 int newEnd = end;
144 // because the fields are naturally sorted in the DFS order. we can safely
145 // break when pos is larger than the one we are searching for.
146 for (int i = start; i < end; i++) {
147 int pos = values[i].mField.getPosAtDepth(depth);
148 if (pos == matcher.field()) {
149 if (newStart == -1) {
150 newStart = i;
151 }
152 newEnd = i + 1;
153 } else if (pos > matcher.field()) {
154 break;
155 }
156 }
157
158 // Now we have zoomed in to a new range
159 start = newStart;
160 end = newEnd;
161
162 if (start == -1) {
163 // No such field found.
164 return false;
165 }
166
167 vector<pair<int, int>> ranges; // the ranges are for matching ANY position
168 if (matcher.has_position()) {
169 // Repeated fields position is stored as a node in the path.
170 depth++;
171 if (depth > 2) {
172 return false;
173 }
174 switch (matcher.position()) {
175 case Position::FIRST: {
176 for (int i = start; i < end; i++) {
177 int pos = values[i].mField.getPosAtDepth(depth);
178 if (pos != 1) {
179 // Again, the log elements are stored in sorted order. so
180 // once the position is > 1, we break;
181 end = i;
182 break;
183 }
184 }
185 ranges.push_back(std::make_pair(start, end));
186 break;
187 }
188 case Position::LAST: {
189 // move the starting index to the first LAST field at the depth.
190 for (int i = start; i < end; i++) {
191 if (values[i].mField.isLastPos(depth)) {
192 start = i;
193 break;
194 }
195 }
196 ranges.push_back(std::make_pair(start, end));
197 break;
198 }
199 case Position::ANY: {
200 // ANY means all the children matchers match in any of the sub trees, it's a match
201 newStart = start;
202 newEnd = end;
203 // Here start is guaranteed to be a valid index.
204 int currentPos = values[start].mField.getPosAtDepth(depth);
205 // Now find all sub trees ranges.
206 for (int i = start; i < end; i++) {
207 int newPos = values[i].mField.getPosAtDepth(depth);
208 if (newPos != currentPos) {
209 ranges.push_back(std::make_pair(newStart, i));
210 newStart = i;
211 currentPos = newPos;
212 }
213 }
214 ranges.push_back(std::make_pair(newStart, end));
215 break;
216 }
217 case Position::ALL:
218 ALOGE("Not supported: field matcher with ALL position.");
219 break;
220 case Position::POSITION_UNKNOWN:
221 break;
222 }
223 } else {
224 // No position
225 ranges.push_back(std::make_pair(start, end));
226 }
227 // start and end are still pointing to the matched range.
228 switch (matcher.value_matcher_case()) {
229 case FieldValueMatcher::kMatchesTuple: {
230 ++depth;
231 // If any range matches all matchers, good.
232 for (const auto& range : ranges) {
233 bool matched = true;
234 for (const auto& subMatcher : matcher.matches_tuple().field_value_matcher()) {
235 if (!matchesSimple(uidMap, subMatcher, values, range.first, range.second,
236 depth)) {
237 matched = false;
238 break;
239 }
240 }
241 if (matched) return true;
242 }
243 return false;
244 }
245 // Finally, we get to the point of real value matching.
246 // If the field matcher ends with ANY, then we have [start, end) range > 1.
247 // In the following, we should return true, when ANY of the values matches.
248 case FieldValueMatcher::ValueMatcherCase::kEqBool: {
249 for (int i = start; i < end; i++) {
250 if ((values[i].mValue.getType() == INT &&
251 (values[i].mValue.int_value != 0) == matcher.eq_bool()) ||
252 (values[i].mValue.getType() == LONG &&
253 (values[i].mValue.long_value != 0) == matcher.eq_bool())) {
254 return true;
255 }
256 }
257 return false;
258 }
259 case FieldValueMatcher::ValueMatcherCase::kEqString: {
260 for (int i = start; i < end; i++) {
261 if (tryMatchString(uidMap, values[i], matcher.eq_string())) {
262 return true;
263 }
264 }
265 return false;
266 }
267 case FieldValueMatcher::ValueMatcherCase::kNeqAnyString: {
268 const auto& str_list = matcher.neq_any_string();
269 for (int i = start; i < end; i++) {
270 bool notEqAll = true;
271 for (const auto& str : str_list.str_value()) {
272 if (tryMatchString(uidMap, values[i], str)) {
273 notEqAll = false;
274 break;
275 }
276 }
277 if (notEqAll) {
278 return true;
279 }
280 }
281 return false;
282 }
283 case FieldValueMatcher::ValueMatcherCase::kEqAnyString: {
284 const auto& str_list = matcher.eq_any_string();
285 for (int i = start; i < end; i++) {
286 for (const auto& str : str_list.str_value()) {
287 if (tryMatchString(uidMap, values[i], str)) {
288 return true;
289 }
290 }
291 }
292 return false;
293 }
294 case FieldValueMatcher::ValueMatcherCase::kEqWildcardString: {
295 for (int i = start; i < end; i++) {
296 if (tryMatchWildcardString(uidMap, values[i], matcher.eq_wildcard_string())) {
297 return true;
298 }
299 }
300 return false;
301 }
302 case FieldValueMatcher::ValueMatcherCase::kEqAnyWildcardString: {
303 const auto& str_list = matcher.eq_any_wildcard_string();
304 for (int i = start; i < end; i++) {
305 for (const auto& str : str_list.str_value()) {
306 if (tryMatchWildcardString(uidMap, values[i], str)) {
307 return true;
308 }
309 }
310 }
311 return false;
312 }
313 case FieldValueMatcher::ValueMatcherCase::kNeqAnyWildcardString: {
314 const auto& str_list = matcher.neq_any_wildcard_string();
315 for (int i = start; i < end; i++) {
316 bool notEqAll = true;
317 for (const auto& str : str_list.str_value()) {
318 if (tryMatchWildcardString(uidMap, values[i], str)) {
319 notEqAll = false;
320 break;
321 }
322 }
323 if (notEqAll) {
324 return true;
325 }
326 }
327 return false;
328 }
329 case FieldValueMatcher::ValueMatcherCase::kEqInt: {
330 for (int i = start; i < end; i++) {
331 if (values[i].mValue.getType() == INT &&
332 (matcher.eq_int() == values[i].mValue.int_value)) {
333 return true;
334 }
335 // eq_int covers both int and long.
336 if (values[i].mValue.getType() == LONG &&
337 (matcher.eq_int() == values[i].mValue.long_value)) {
338 return true;
339 }
340 }
341 return false;
342 }
343 case FieldValueMatcher::ValueMatcherCase::kEqAnyInt: {
344 const auto& int_list = matcher.eq_any_int();
345 for (int i = start; i < end; i++) {
346 for (const int int_value : int_list.int_value()) {
347 if (values[i].mValue.getType() == INT &&
348 (int_value == values[i].mValue.int_value)) {
349 return true;
350 }
351 // eq_any_int covers both int and long.
352 if (values[i].mValue.getType() == LONG &&
353 (int_value == values[i].mValue.long_value)) {
354 return true;
355 }
356 }
357 }
358 return false;
359 }
360 case FieldValueMatcher::ValueMatcherCase::kNeqAnyInt: {
361 const auto& int_list = matcher.neq_any_int();
362 for (int i = start; i < end; i++) {
363 bool notEqAll = true;
364 for (const int int_value : int_list.int_value()) {
365 if (values[i].mValue.getType() == INT &&
366 (int_value == values[i].mValue.int_value)) {
367 notEqAll = false;
368 break;
369 }
370 // neq_any_int covers both int and long.
371 if (values[i].mValue.getType() == LONG &&
372 (int_value == values[i].mValue.long_value)) {
373 notEqAll = false;
374 break;
375 }
376 }
377 if (notEqAll) {
378 return true;
379 }
380 }
381 return false;
382 }
383 case FieldValueMatcher::ValueMatcherCase::kLtInt: {
384 for (int i = start; i < end; i++) {
385 if (values[i].mValue.getType() == INT &&
386 (values[i].mValue.int_value < matcher.lt_int())) {
387 return true;
388 }
389 // lt_int covers both int and long.
390 if (values[i].mValue.getType() == LONG &&
391 (values[i].mValue.long_value < matcher.lt_int())) {
392 return true;
393 }
394 }
395 return false;
396 }
397 case FieldValueMatcher::ValueMatcherCase::kGtInt: {
398 for (int i = start; i < end; i++) {
399 if (values[i].mValue.getType() == INT &&
400 (values[i].mValue.int_value > matcher.gt_int())) {
401 return true;
402 }
403 // gt_int covers both int and long.
404 if (values[i].mValue.getType() == LONG &&
405 (values[i].mValue.long_value > matcher.gt_int())) {
406 return true;
407 }
408 }
409 return false;
410 }
411 case FieldValueMatcher::ValueMatcherCase::kLtFloat: {
412 for (int i = start; i < end; i++) {
413 if (values[i].mValue.getType() == FLOAT &&
414 (values[i].mValue.float_value < matcher.lt_float())) {
415 return true;
416 }
417 }
418 return false;
419 }
420 case FieldValueMatcher::ValueMatcherCase::kGtFloat: {
421 for (int i = start; i < end; i++) {
422 if (values[i].mValue.getType() == FLOAT &&
423 (values[i].mValue.float_value > matcher.gt_float())) {
424 return true;
425 }
426 }
427 return false;
428 }
429 case FieldValueMatcher::ValueMatcherCase::kLteInt: {
430 for (int i = start; i < end; i++) {
431 if (values[i].mValue.getType() == INT &&
432 (values[i].mValue.int_value <= matcher.lte_int())) {
433 return true;
434 }
435 // lte_int covers both int and long.
436 if (values[i].mValue.getType() == LONG &&
437 (values[i].mValue.long_value <= matcher.lte_int())) {
438 return true;
439 }
440 }
441 return false;
442 }
443 case FieldValueMatcher::ValueMatcherCase::kGteInt: {
444 for (int i = start; i < end; i++) {
445 if (values[i].mValue.getType() == INT &&
446 (values[i].mValue.int_value >= matcher.gte_int())) {
447 return true;
448 }
449 // gte_int covers both int and long.
450 if (values[i].mValue.getType() == LONG &&
451 (values[i].mValue.long_value >= matcher.gte_int())) {
452 return true;
453 }
454 }
455 return false;
456 }
457 default:
458 return false;
459 }
460 }
461
matchesSimple(const sp<UidMap> & uidMap,const SimpleAtomMatcher & simpleMatcher,const LogEvent & event)462 bool matchesSimple(const sp<UidMap>& uidMap, const SimpleAtomMatcher& simpleMatcher,
463 const LogEvent& event) {
464 if (event.GetTagId() != simpleMatcher.atom_id()) {
465 return false;
466 }
467
468 for (const auto& matcher : simpleMatcher.field_value_matcher()) {
469 if (!matchesSimple(uidMap, matcher, event.getValues(), 0, event.getValues().size(), 0)) {
470 return false;
471 }
472 }
473 return true;
474 }
475
476 } // namespace statsd
477 } // namespace os
478 } // namespace android
479