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 
17 #pragma once
18 
19 #include <string>
20 #include <unordered_map>
21 #include <unordered_set>
22 
23 #include <private/android_filesystem_config.h>
24 #include <utils/RWLock.h>
25 
26 class LogTags {
27     // This lock protects all the unordered_map accesses below.  It
28     // is a reader/writer lock so that contentions are kept to a
29     // minimum since writes are rare, even administratably when
30     // reads are extended.  Resist the temptation to use the writer
31     // lock to protect anything outside the following unordered_maps
32     // as that would increase the reader contentions.  Use a separate
33     // mutex to protect the other entities.
34     android::RWLock rwlock;
35 
36     // key is Name + "+" + Format
37     std::unordered_map<std::string, uint32_t> key2tag;
38     typedef std::unordered_map<std::string, uint32_t>::const_iterator
39         key2tag_const_iterator;
40 
41     // Allows us to manage access permissions based on uid registrants
42     // Global entries are specifically erased.
43     typedef std::unordered_set<uid_t> uid_list;
44     std::unordered_map<uint32_t, uid_list> tag2uid;
45     typedef std::unordered_map<uint32_t, uid_list>::const_iterator
46         tag2uid_const_iterator;
47 
48     std::unordered_map<uint32_t, std::string> tag2name;
49     typedef std::unordered_map<uint32_t, std::string>::const_iterator
50         tag2name_const_iterator;
51 
52     std::unordered_map<uint32_t, std::string> tag2format;
53     typedef std::unordered_map<uint32_t, std::string>::const_iterator
54         tag2format_const_iterator;
55 
56     static const size_t max_per_uid = 256;  // Put a cap on the tags per uid
57     std::unordered_map<uid_t, size_t> uid2count;
58     typedef std::unordered_map<uid_t, size_t>::const_iterator
59         uid2count_const_iterator;
60 
61     // Dynamic entries are assigned
62     std::unordered_map<uint32_t, size_t> tag2total;
63     typedef std::unordered_map<uint32_t, size_t>::const_iterator
64         tag2total_const_iterator;
65 
66     // emplace unique tag
67     uint32_t nameToTag(uid_t uid, const char* name, const char* format);
68     // find unique or associated tag
69     uint32_t nameToTag_locked(const std::string& name, const char* format,
70                               bool& unique);
71 
72     // Record expected file watermarks to detect corruption.
73     std::unordered_map<std::string, size_t> file2watermark;
74     typedef std::unordered_map<std::string, size_t>::const_iterator
75         file2watermark_const_iterator;
76 
77     void ReadPersistEventLogTags();
78 
79     // format helpers
80     // format a single entry, does not need object data
81     static std::string formatEntry(uint32_t tag, uid_t uid, const char* name,
82                                    const char* format);
83     // caller locks, database lookup, authenticate against uid
84     std::string formatEntry_locked(uint32_t tag, uid_t uid,
85                                    bool authenticate = true);
86 
87     bool RebuildFileEventLogTags(const char* filename, bool warn = true);
88 
89     void AddEventLogTags(uint32_t tag, uid_t uid, const std::string& Name,
90                          const std::string& Format, const char* source = nullptr,
91                          bool warn = false);
92 
93     void WriteDynamicEventLogTags(uint32_t tag, uid_t uid);
94     void WriteDebugEventLogTags(uint32_t tag, uid_t uid);
95     // push tag details to persistent storage
96     void WritePersistEventLogTags(uint32_t tag, uid_t uid = AID_ROOT,
97                                   const char* source = nullptr);
98 
99     static const uint32_t emptyTag = uint32_t(-1);
100 
101    public:
102     static const char system_event_log_tags[];
103     static const char dynamic_event_log_tags[];
104     // Only for userdebug and eng
105     static const char debug_event_log_tags[];
106 
107     LogTags();
108 
109     void WritePmsgEventLogTags(uint32_t tag, uid_t uid = AID_ROOT);
110     void ReadFileEventLogTags(const char* filename, bool warn = true);
111 
112     // reverse lookup from tag
113     const char* tagToName(uint32_t tag) const;
114     const char* tagToFormat(uint32_t tag) const;
115     std::string formatEntry(uint32_t tag, uid_t uid);
116     // find associated tag
117     uint32_t nameToTag(const char* name) const;
118 
119     // emplace tag if necessary, provide event-log-tag formated output in string
120     std::string formatGetEventTag(uid_t uid, const char* name,
121                                   const char* format);
122 };
123