• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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