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 DEBUG false  // STOPSHIP if true
17 #include "Log.h"
18 
19 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
20 #include "matchers/LogMatchingTracker.h"
21 #include "matchers/matcher_util.h"
22 #include "stats_util.h"
23 
24 using std::set;
25 using std::string;
26 using std::vector;
27 
28 namespace android {
29 namespace os {
30 namespace statsd {
31 
combinationMatch(const vector<int> & children,const LogicalOperation & operation,const vector<MatchingState> & matcherResults)32 bool combinationMatch(const vector<int>& children, const LogicalOperation& operation,
33                       const vector<MatchingState>& matcherResults) {
34     bool matched;
35     switch (operation) {
36         case LogicalOperation::AND: {
37             matched = true;
38             for (const int childIndex : children) {
39                 if (matcherResults[childIndex] != MatchingState::kMatched) {
40                     matched = false;
41                     break;
42                 }
43             }
44             break;
45         }
46         case LogicalOperation::OR: {
47             matched = false;
48             for (const int childIndex : children) {
49                 if (matcherResults[childIndex] == MatchingState::kMatched) {
50                     matched = true;
51                     break;
52                 }
53             }
54             break;
55         }
56         case LogicalOperation::NOT:
57             matched = matcherResults[children[0]] == MatchingState::kNotMatched;
58             break;
59         case LogicalOperation::NAND:
60             matched = false;
61             for (const int childIndex : children) {
62                 if (matcherResults[childIndex] != MatchingState::kMatched) {
63                     matched = true;
64                     break;
65                 }
66             }
67             break;
68         case LogicalOperation::NOR:
69             matched = true;
70             for (const int childIndex : children) {
71                 if (matcherResults[childIndex] == MatchingState::kMatched) {
72                     matched = false;
73                     break;
74                 }
75             }
76             break;
77         case LogicalOperation::LOGICAL_OPERATION_UNSPECIFIED:
78             matched = false;
79             break;
80     }
81     return matched;
82 }
83 
tryMatchString(const UidMap & uidMap,const Field & field,const Value & value,const string & str_match)84 bool tryMatchString(const UidMap& uidMap, const Field& field, const Value& value,
85                     const string& str_match) {
86     if (isAttributionUidField(field, value)) {
87         int uid = value.int_value;
88         auto aidIt = UidMap::sAidToUidMapping.find(str_match);
89         if (aidIt != UidMap::sAidToUidMapping.end()) {
90             return ((int)aidIt->second) == uid;
91         }
92         std::set<string> packageNames = uidMap.getAppNamesFromUid(uid, true /* normalize*/);
93         return packageNames.find(str_match) != packageNames.end();
94     } else if (value.getType() == STRING) {
95         return value.str_value == str_match;
96     }
97     return false;
98 }
99 
matchesSimple(const UidMap & uidMap,const FieldValueMatcher & matcher,const vector<FieldValue> & values,int start,int end,int depth)100 bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher,
101                    const vector<FieldValue>& values, int start, int end, int depth) {
102     if (depth > 2) {
103         ALOGE("Depth > 3 not supported");
104         return false;
105     }
106 
107     if (start >= end) {
108         return false;
109     }
110 
111     // Filter by entry field first
112     int newStart = -1;
113     int newEnd = end;
114     // because the fields are naturally sorted in the DFS order. we can safely
115     // break when pos is larger than the one we are searching for.
116     for (int i = start; i < end; i++) {
117         int pos = values[i].mField.getPosAtDepth(depth);
118         if (pos == matcher.field()) {
119             if (newStart == -1) {
120                 newStart = i;
121             }
122             newEnd = i + 1;
123         } else if (pos > matcher.field()) {
124             break;
125         }
126     }
127 
128     // Now we have zoomed in to a new range
129     start = newStart;
130     end = newEnd;
131 
132     if (start == -1) {
133         // No such field found.
134         return false;
135     }
136 
137     vector<pair<int, int>> ranges; // the ranges are for matching ANY position
138     if (matcher.has_position()) {
139         // Repeated fields position is stored as a node in the path.
140         depth++;
141         if (depth > 2) {
142             return false;
143         }
144         switch (matcher.position()) {
145             case Position::FIRST: {
146                 for (int i = start; i < end; i++) {
147                     int pos = values[i].mField.getPosAtDepth(depth);
148                     if (pos != 1) {
149                         // Again, the log elements are stored in sorted order. so
150                         // once the position is > 1, we break;
151                         end = i;
152                         break;
153                     }
154                 }
155                 ranges.push_back(std::make_pair(start, end));
156                 break;
157             }
158             case Position::LAST: {
159                 // move the starting index to the first LAST field at the depth.
160                 for (int i = start; i < end; i++) {
161                     if (values[i].mField.isLastPos(depth)) {
162                         start = i;
163                         break;
164                     }
165                 }
166                 ranges.push_back(std::make_pair(start, end));
167                 break;
168             }
169             case Position::ANY: {
170                 // ANY means all the children matchers match in any of the sub trees, it's a match
171                 newStart = start;
172                 newEnd = end;
173                 // Here start is guaranteed to be a valid index.
174                 int currentPos = values[start].mField.getPosAtDepth(depth);
175                 // Now find all sub trees ranges.
176                 for (int i = start; i < end; i++) {
177                     int newPos = values[i].mField.getPosAtDepth(depth);
178                     if (newPos != currentPos) {
179                         ranges.push_back(std::make_pair(newStart, i));
180                         newStart = i;
181                         currentPos = newPos;
182                     }
183                 }
184                 ranges.push_back(std::make_pair(newStart, end));
185                 break;
186             }
187             case Position::ALL:
188                 ALOGE("Not supported: field matcher with ALL position.");
189                 break;
190             case Position::POSITION_UNKNOWN:
191                 break;
192         }
193     } else {
194         // No position
195         ranges.push_back(std::make_pair(start, end));
196     }
197     // start and end are still pointing to the matched range.
198     switch (matcher.value_matcher_case()) {
199         case FieldValueMatcher::kMatchesTuple: {
200             ++depth;
201             // If any range matches all matchers, good.
202             for (const auto& range : ranges) {
203                 bool matched = true;
204                 for (const auto& subMatcher : matcher.matches_tuple().field_value_matcher()) {
205                     if (!matchesSimple(uidMap, subMatcher, values, range.first, range.second,
206                                        depth)) {
207                         matched = false;
208                         break;
209                     }
210                 }
211                 if (matched) return true;
212             }
213             return false;
214         }
215         // Finally, we get to the point of real value matching.
216         // If the field matcher ends with ANY, then we have [start, end) range > 1.
217         // In the following, we should return true, when ANY of the values matches.
218         case FieldValueMatcher::ValueMatcherCase::kEqBool: {
219             for (int i = start; i < end; i++) {
220                 if ((values[i].mValue.getType() == INT &&
221                      (values[i].mValue.int_value != 0) == matcher.eq_bool()) ||
222                     (values[i].mValue.getType() == LONG &&
223                      (values[i].mValue.long_value != 0) == matcher.eq_bool())) {
224                     return true;
225                 }
226             }
227             return false;
228         }
229         case FieldValueMatcher::ValueMatcherCase::kEqString: {
230             for (int i = start; i < end; i++) {
231                 if (tryMatchString(uidMap, values[i].mField, values[i].mValue,
232                                    matcher.eq_string())) {
233                     return true;
234                 }
235             }
236             return false;
237         }
238         case FieldValueMatcher::ValueMatcherCase::kNeqAnyString: {
239             const auto& str_list = matcher.neq_any_string();
240             for (int i = start; i < end; i++) {
241                 bool notEqAll = true;
242                 for (const auto& str : str_list.str_value()) {
243                     if (tryMatchString(uidMap, values[i].mField, values[i].mValue, str)) {
244                         notEqAll = false;
245                         break;
246                     }
247                 }
248                 if (notEqAll) {
249                     return true;
250                 }
251             }
252             return false;
253         }
254         case FieldValueMatcher::ValueMatcherCase::kEqAnyString: {
255             const auto& str_list = matcher.eq_any_string();
256             for (int i = start; i < end; i++) {
257                 for (const auto& str : str_list.str_value()) {
258                     if (tryMatchString(uidMap, values[i].mField, values[i].mValue, str)) {
259                         return true;
260                     }
261                 }
262             }
263             return false;
264         }
265         case FieldValueMatcher::ValueMatcherCase::kEqInt: {
266             for (int i = start; i < end; i++) {
267                 if (values[i].mValue.getType() == INT &&
268                     (matcher.eq_int() == values[i].mValue.int_value)) {
269                     return true;
270                 }
271                 // eq_int covers both int and long.
272                 if (values[i].mValue.getType() == LONG &&
273                     (matcher.eq_int() == values[i].mValue.long_value)) {
274                     return true;
275                 }
276             }
277             return false;
278         }
279         case FieldValueMatcher::ValueMatcherCase::kLtInt: {
280             for (int i = start; i < end; i++) {
281                 if (values[i].mValue.getType() == INT &&
282                     (values[i].mValue.int_value < matcher.lt_int())) {
283                     return true;
284                 }
285                 // lt_int covers both int and long.
286                 if (values[i].mValue.getType() == LONG &&
287                     (values[i].mValue.long_value < matcher.lt_int())) {
288                     return true;
289                 }
290             }
291             return false;
292         }
293         case FieldValueMatcher::ValueMatcherCase::kGtInt: {
294             for (int i = start; i < end; i++) {
295                 if (values[i].mValue.getType() == INT &&
296                     (values[i].mValue.int_value > matcher.gt_int())) {
297                     return true;
298                 }
299                 // gt_int covers both int and long.
300                 if (values[i].mValue.getType() == LONG &&
301                     (values[i].mValue.long_value > matcher.gt_int())) {
302                     return true;
303                 }
304             }
305             return false;
306         }
307         case FieldValueMatcher::ValueMatcherCase::kLtFloat: {
308             for (int i = start; i < end; i++) {
309                 if (values[i].mValue.getType() == FLOAT &&
310                     (values[i].mValue.float_value < matcher.lt_float())) {
311                     return true;
312                 }
313             }
314             return false;
315         }
316         case FieldValueMatcher::ValueMatcherCase::kGtFloat: {
317             for (int i = start; i < end; i++) {
318                 if (values[i].mValue.getType() == FLOAT &&
319                     (values[i].mValue.float_value > matcher.gt_float())) {
320                     return true;
321                 }
322             }
323             return false;
324         }
325         case FieldValueMatcher::ValueMatcherCase::kLteInt: {
326             for (int i = start; i < end; i++) {
327                 if (values[i].mValue.getType() == INT &&
328                     (values[i].mValue.int_value <= matcher.lte_int())) {
329                     return true;
330                 }
331                 // lte_int covers both int and long.
332                 if (values[i].mValue.getType() == LONG &&
333                     (values[i].mValue.long_value <= matcher.lte_int())) {
334                     return true;
335                 }
336             }
337             return false;
338         }
339         case FieldValueMatcher::ValueMatcherCase::kGteInt: {
340             for (int i = start; i < end; i++) {
341                 if (values[i].mValue.getType() == INT &&
342                     (values[i].mValue.int_value >= matcher.gte_int())) {
343                     return true;
344                 }
345                 // gte_int covers both int and long.
346                 if (values[i].mValue.getType() == LONG &&
347                     (values[i].mValue.long_value >= matcher.gte_int())) {
348                     return true;
349                 }
350             }
351             return false;
352         }
353         default:
354             return false;
355     }
356 }
357 
matchesSimple(const UidMap & uidMap,const SimpleAtomMatcher & simpleMatcher,const LogEvent & event)358 bool matchesSimple(const UidMap& uidMap, const SimpleAtomMatcher& simpleMatcher,
359                    const LogEvent& event) {
360     if (simpleMatcher.field_value_matcher_size() <= 0) {
361         return event.GetTagId() == simpleMatcher.atom_id();
362     }
363     for (const auto& matcher : simpleMatcher.field_value_matcher()) {
364         if (!matchesSimple(uidMap, matcher, event.getValues(), 0, event.getValues().size(), 0)) {
365             return false;
366         }
367     }
368     return true;
369 }
370 
371 }  // namespace statsd
372 }  // namespace os
373 }  // namespace android
374