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