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 "src/statsd_config.pb.h" 20 #include "matchers/AtomMatchingTracker.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 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 84 bool tryMatchString(const sp<UidMap>& uidMap, const FieldValue& fieldValue, 85 const string& str_match) { 86 if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) { 87 int uid = fieldValue.mValue.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 (fieldValue.mValue.getType() == STRING) { 95 return fieldValue.mValue.str_value == str_match; 96 } 97 return false; 98 } 99 100 bool matchesSimple(const sp<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], matcher.eq_string())) { 232 return true; 233 } 234 } 235 return false; 236 } 237 case FieldValueMatcher::ValueMatcherCase::kNeqAnyString: { 238 const auto& str_list = matcher.neq_any_string(); 239 for (int i = start; i < end; i++) { 240 bool notEqAll = true; 241 for (const auto& str : str_list.str_value()) { 242 if (tryMatchString(uidMap, values[i], str)) { 243 notEqAll = false; 244 break; 245 } 246 } 247 if (notEqAll) { 248 return true; 249 } 250 } 251 return false; 252 } 253 case FieldValueMatcher::ValueMatcherCase::kEqAnyString: { 254 const auto& str_list = matcher.eq_any_string(); 255 for (int i = start; i < end; i++) { 256 for (const auto& str : str_list.str_value()) { 257 if (tryMatchString(uidMap, values[i], str)) { 258 return true; 259 } 260 } 261 } 262 return false; 263 } 264 case FieldValueMatcher::ValueMatcherCase::kEqInt: { 265 for (int i = start; i < end; i++) { 266 if (values[i].mValue.getType() == INT && 267 (matcher.eq_int() == values[i].mValue.int_value)) { 268 return true; 269 } 270 // eq_int covers both int and long. 271 if (values[i].mValue.getType() == LONG && 272 (matcher.eq_int() == values[i].mValue.long_value)) { 273 return true; 274 } 275 } 276 return false; 277 } 278 case FieldValueMatcher::ValueMatcherCase::kLtInt: { 279 for (int i = start; i < end; i++) { 280 if (values[i].mValue.getType() == INT && 281 (values[i].mValue.int_value < matcher.lt_int())) { 282 return true; 283 } 284 // lt_int covers both int and long. 285 if (values[i].mValue.getType() == LONG && 286 (values[i].mValue.long_value < matcher.lt_int())) { 287 return true; 288 } 289 } 290 return false; 291 } 292 case FieldValueMatcher::ValueMatcherCase::kGtInt: { 293 for (int i = start; i < end; i++) { 294 if (values[i].mValue.getType() == INT && 295 (values[i].mValue.int_value > matcher.gt_int())) { 296 return true; 297 } 298 // gt_int covers both int and long. 299 if (values[i].mValue.getType() == LONG && 300 (values[i].mValue.long_value > matcher.gt_int())) { 301 return true; 302 } 303 } 304 return false; 305 } 306 case FieldValueMatcher::ValueMatcherCase::kLtFloat: { 307 for (int i = start; i < end; i++) { 308 if (values[i].mValue.getType() == FLOAT && 309 (values[i].mValue.float_value < matcher.lt_float())) { 310 return true; 311 } 312 } 313 return false; 314 } 315 case FieldValueMatcher::ValueMatcherCase::kGtFloat: { 316 for (int i = start; i < end; i++) { 317 if (values[i].mValue.getType() == FLOAT && 318 (values[i].mValue.float_value > matcher.gt_float())) { 319 return true; 320 } 321 } 322 return false; 323 } 324 case FieldValueMatcher::ValueMatcherCase::kLteInt: { 325 for (int i = start; i < end; i++) { 326 if (values[i].mValue.getType() == INT && 327 (values[i].mValue.int_value <= matcher.lte_int())) { 328 return true; 329 } 330 // lte_int covers both int and long. 331 if (values[i].mValue.getType() == LONG && 332 (values[i].mValue.long_value <= matcher.lte_int())) { 333 return true; 334 } 335 } 336 return false; 337 } 338 case FieldValueMatcher::ValueMatcherCase::kGteInt: { 339 for (int i = start; i < end; i++) { 340 if (values[i].mValue.getType() == INT && 341 (values[i].mValue.int_value >= matcher.gte_int())) { 342 return true; 343 } 344 // gte_int covers both int and long. 345 if (values[i].mValue.getType() == LONG && 346 (values[i].mValue.long_value >= matcher.gte_int())) { 347 return true; 348 } 349 } 350 return false; 351 } 352 default: 353 return false; 354 } 355 } 356 357 bool matchesSimple(const sp<UidMap>& uidMap, const SimpleAtomMatcher& simpleMatcher, 358 const LogEvent& event) { 359 if (event.GetTagId() != simpleMatcher.atom_id()) { 360 return false; 361 } 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