summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Cherry2018-03-23 16:09:23 -0500
committerTom Cherry2018-03-26 11:22:55 -0500
commit882faa644876cddac03b98526b6029fe7b25cf9f (patch)
tree2085cdf54011ed67c580ef7316d70f693aaca795 /property_service
parentd888e343b7551b1b93522ffb23b53238fa19c18e (diff)
downloadplatform-system-core-882faa644876cddac03b98526b6029fe7b25cf9f.tar.gz
platform-system-core-882faa644876cddac03b98526b6029fe7b25cf9f.tar.xz
platform-system-core-882faa644876cddac03b98526b6029fe7b25cf9f.zip
Verify the SELabels used in property_contexts
Verify that the SELabels used in property_contexts correspond to a real type in the SEPolicy and that this type has the property_type attribute. Bug: 74078792 Test: Build property_contexts on bullhead successfully Test: See failure when using a faulty SELabel in property_contexts Change-Id: If1618c2c3dae4c0cd3efa5f88056478a6db6bd0b
Diffstat (limited to 'property_service')
-rw-r--r--property_service/property_info_checker/Android.bp1
-rw-r--r--property_service/property_info_checker/property_info_checker.cpp146
2 files changed, 142 insertions, 5 deletions
diff --git a/property_service/property_info_checker/Android.bp b/property_service/property_info_checker/Android.bp
index 6ee649af0..7d6619967 100644
--- a/property_service/property_info_checker/Android.bp
+++ b/property_service/property_info_checker/Android.bp
@@ -7,6 +7,7 @@ cc_binary {
7 "libpropertyinfoserializer", 7 "libpropertyinfoserializer",
8 "libpropertyinfoparser", 8 "libpropertyinfoparser",
9 "libbase", 9 "libbase",
10 "libsepol",
10 ], 11 ],
11 srcs: ["property_info_checker.cpp"], 12 srcs: ["property_info_checker.cpp"],
12} 13}
diff --git a/property_service/property_info_checker/property_info_checker.cpp b/property_service/property_info_checker/property_info_checker.cpp
index e4f8264d4..52c4383ad 100644
--- a/property_service/property_info_checker/property_info_checker.cpp
+++ b/property_service/property_info_checker/property_info_checker.cpp
@@ -1,26 +1,150 @@
1#include <iostream> 1#include <iostream>
2#include <memory>
2#include <string> 3#include <string>
3#include <vector> 4#include <vector>
4 5
5#include <android-base/file.h> 6#include <android-base/file.h>
6 7#include <property_info_parser/property_info_parser.h>
7#include <property_info_serializer/property_info_serializer.h> 8#include <property_info_serializer/property_info_serializer.h>
9#include <sepol/context.h>
10#include <sepol/context_record.h>
11#include <sepol/handle.h>
12#include <sepol/policydb.h>
13#include <sepol/policydb/policydb.h>
8 14
9using android::base::ReadFileToString; 15using android::base::ReadFileToString;
10using android::properties::BuildTrie; 16using android::properties::BuildTrie;
11using android::properties::ParsePropertyInfoFile; 17using android::properties::ParsePropertyInfoFile;
18using android::properties::PropertyInfoArea;
12using android::properties::PropertyInfoEntry; 19using android::properties::PropertyInfoEntry;
13 20
21class ContextChecker {
22 public:
23 ContextChecker()
24 : policy_file_(nullptr),
25 sepol_handle_(nullptr),
26 sepol_policy_file_(nullptr),
27 sepol_policy_db_(nullptr) {}
28
29 ~ContextChecker() {
30 if (sepol_policy_db_ != nullptr) {
31 sepol_policydb_free(sepol_policy_db_);
32 }
33
34 if (sepol_policy_file_ != nullptr) {
35 sepol_policy_file_free(sepol_policy_file_);
36 }
37
38 if (sepol_handle_ != nullptr) {
39 sepol_handle_destroy(sepol_handle_);
40 }
41
42 if (policy_file_ != nullptr) {
43 fclose(policy_file_);
44 }
45 }
46
47 bool Initialize(const char* policy_file) {
48 policy_file_ = fopen(policy_file, "re");
49 if (policy_file_ == nullptr) {
50 std::cerr << "Could not open policy file, " << policy_file << std::endl;
51 return false;
52 }
53
54 sepol_handle_ = sepol_handle_create();
55 if (sepol_handle_ == nullptr) {
56 std::cerr << "Could not create policy handle." << std::endl;
57 return false;
58 }
59
60 if (sepol_policy_file_create(&sepol_policy_file_) < 0) {
61 std::cerr << "Could not create policy file." << std::endl;
62 return false;
63 }
64
65 if (sepol_policydb_create(&sepol_policy_db_) < 0) {
66 std::cerr << "Could not create policy db." << std::endl;
67 return false;
68 }
69
70 sepol_policy_file_set_fp(sepol_policy_file_, policy_file_);
71 sepol_policy_file_set_handle(sepol_policy_file_, sepol_handle_);
72
73 if (sepol_policydb_read(sepol_policy_db_, sepol_policy_file_) < 0) {
74 std::cerr << "Could not read policy file into policy db." << std::endl;
75 return false;
76 }
77
78 auto* attr =
79 reinterpret_cast<type_datum*>(hashtab_search(policy_db_->p_types.table, "property_type"));
80 if (attr == nullptr || attr->flavor != TYPE_ATTRIB) {
81 std::cerr << "'property_type' is not defined correctly." << std::endl;
82 return false;
83 }
84
85 property_type_bit_ = attr->s.value - 1;
86
87 return true;
88 }
89
90 bool CheckContext(const char* context) {
91 sepol_context_t* sepol_context_raw;
92 if (sepol_context_from_string(sepol_handle_, context, &sepol_context_raw) < 0) {
93 std::cerr << "Could not allocate context for " << context << std::endl;
94 return false;
95 }
96 auto sepol_context = std::unique_ptr<sepol_context_t, decltype(&sepol_context_free)>{
97 sepol_context_raw, sepol_context_free};
98
99 if (sepol_context_check(sepol_handle_, sepol_policy_db_, sepol_context.get()) < 0) {
100 std::cerr << "Sepol context check failed for " << context << std::endl;
101 return false;
102 }
103
104 const char* context_type = sepol_context_get_type(sepol_context.get());
105
106 auto* type =
107 reinterpret_cast<type_datum*>(hashtab_search(policy_db_->p_types.table, context_type));
108 if (type == nullptr) {
109 std::cerr << "Could not find context '" << context << "' in policy database" << std::endl;
110 return false;
111 }
112
113 if (type->flavor != TYPE_TYPE) {
114 std::cerr << "Context '" << context << "' is not defined as a type in policy database"
115 << std::endl;
116 return false;
117 }
118
119 if (!ebitmap_get_bit(&policy_db_->type_attr_map[type->s.value - 1], property_type_bit_)) {
120 std::cerr << "Context '" << context << "' does not have property_type attribute" << std::endl;
121 return false;
122 }
123
124 return true;
125 }
126
127 private:
128 FILE* policy_file_;
129 sepol_handle_t* sepol_handle_;
130 sepol_policy_file_t* sepol_policy_file_;
131 union {
132 sepol_policydb_t* sepol_policy_db_;
133 policydb_t* policy_db_;
134 };
135 unsigned int property_type_bit_;
136};
137
14int main(int argc, char** argv) { 138int main(int argc, char** argv) {
15 if (argc < 2) { 139 if (argc < 3) {
16 std::cerr << "A list of property info files to be checked is expected on the command line" 140 std::cerr << "usage: " << argv[0]
17 << std::endl; 141 << " COMPILED_SEPOLICY PROPERTY_INFO_FILE [PROPERTY_INFO_FILE]..." << std::endl;
18 return -1; 142 return -1;
19 } 143 }
20 144
21 auto property_info_entries = std::vector<PropertyInfoEntry>{}; 145 auto property_info_entries = std::vector<PropertyInfoEntry>{};
22 146
23 for (int i = 1; i < argc; ++i) { 147 for (int i = 2; i < argc; ++i) {
24 auto filename = argv[i]; 148 auto filename = argv[i];
25 auto file_contents = std::string{}; 149 auto file_contents = std::string{};
26 if (!ReadFileToString(filename, &file_contents)) { 150 if (!ReadFileToString(filename, &file_contents)) {
@@ -47,5 +171,17 @@ int main(int argc, char** argv) {
47 return -1; 171 return -1;
48 } 172 }
49 173
174 auto checker = ContextChecker{};
175 if (!checker.Initialize(argv[1])) {
176 return -1;
177 }
178
179 auto property_info_area = reinterpret_cast<PropertyInfoArea*>(serialized_contexts.data());
180 for (size_t i = 0; i < property_info_area->num_contexts(); ++i) {
181 if (!checker.CheckContext(property_info_area->context(i))) {
182 return -1;
183 }
184 }
185
50 return 0; 186 return 0;
51} 187}