1 #include <gtest/gtest.h>
2
3 #include <android-base/file.h>
4 #include <android-base/stringprintf.h>
5
6 #include "android_internal.h"
7 #include "label_internal.h"
8
9 using android::base::StringPrintf;
10 using android::base::WriteStringToFile;
11 using std::string;
12
13 class AndroidSELinuxTest : public ::testing::Test {
14 protected:
15 TemporaryDir tdir_;
16 };
17
TEST_F(AndroidSELinuxTest,LoadAndLookupServiceContext)18 TEST_F(AndroidSELinuxTest, LoadAndLookupServiceContext)
19 {
20 string service_contexts =
21 StringPrintf("%s/service_contexts", tdir_.path);
22 string unused_service_contexts =
23 StringPrintf("%s/unused_contexts", tdir_.path);
24 string vendor_contexts =
25 StringPrintf("%s/vendor_service_contexts", tdir_.path);
26
27 WriteStringToFile("account u:object_r:account_service:s0\n",
28 service_contexts);
29 WriteStringToFile("ignored u:object_r:ignored_service:s0\n",
30 unused_service_contexts);
31 WriteStringToFile(
32 "android.hardware.power.IPower/default u:object_r:hal_power_service:s0\n",
33 vendor_contexts);
34
35 const path_alts_t service_paths = { .paths = {
36 { service_contexts.c_str(), unused_service_contexts.c_str() },
37 { vendor_contexts.c_str() }
38 }};
39
40 struct selabel_handle *handle = context_handle(
41 SELABEL_CTX_ANDROID_SERVICE, &service_paths, "test_service");
42 EXPECT_NE(handle, nullptr);
43
44 char *tcontext;
45 EXPECT_EQ(selabel_lookup_raw(handle, &tcontext, "foobar",
46 SELABEL_CTX_ANDROID_SERVICE),
47 -1);
48
49 EXPECT_EQ(selabel_lookup_raw(handle, &tcontext, "account",
50 SELABEL_CTX_ANDROID_SERVICE),
51 0);
52 EXPECT_STREQ(tcontext, "u:object_r:account_service:s0");
53 free(tcontext);
54
55 EXPECT_EQ(selabel_lookup_raw(handle, &tcontext, "ignored",
56 SELABEL_CTX_ANDROID_SERVICE),
57 -1);
58
59 EXPECT_EQ(selabel_lookup_raw(handle, &tcontext,
60 "android.hardware.power.IPower/default",
61 SELABEL_CTX_ANDROID_SERVICE),
62 0);
63 EXPECT_STREQ(tcontext, "u:object_r:hal_power_service:s0");
64 free(tcontext);
65
66 selabel_close(handle);
67 }
68
TEST_F(AndroidSELinuxTest,FailLoadingServiceContext)69 TEST_F(AndroidSELinuxTest, FailLoadingServiceContext)
70 {
71 string service_contexts =
72 StringPrintf("%s/service_contexts", tdir_.path);
73
74 WriteStringToFile("garbage\n", service_contexts);
75
76 const path_alts_t service_paths = { .paths = {
77 { service_contexts.c_str() }
78 }};
79
80 struct selabel_handle *handle = context_handle(
81 SELABEL_CTX_ANDROID_SERVICE, &service_paths, "test_service");
82 EXPECT_EQ(handle, nullptr);
83 }
84
TEST_F(AndroidSELinuxTest,LoadAndLookupSeAppContext)85 TEST_F(AndroidSELinuxTest, LoadAndLookupSeAppContext)
86 {
87 string seapp_contexts =
88 StringPrintf("%s/seapp_contexts", tdir_.path);
89
90 WriteStringToFile(
91 "# some comment\n"
92 "user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user\n",
93 seapp_contexts);
94
95 const path_alts_t seapp_paths = { .paths = {
96 { seapp_contexts.c_str() }
97 }};
98
99 EXPECT_EQ(seapp_context_reload_internal(&seapp_paths), 0);
100
101 context_t ctx = context_new("u:r:unknown");
102 int ret = seapp_context_lookup_internal(SEAPP_DOMAIN, 10001, false, "platform", "com.android.test1", ctx);
103 EXPECT_EQ(ret, 0);
104 EXPECT_STREQ(context_str(ctx), "u:r:platform_app:s0:c512,c768");
105 context_free(ctx);
106
107 ctx = context_new("u:r:unknown_data_file");
108 ret = seapp_context_lookup_internal(SEAPP_TYPE, 10001, false, "platform", "com.android.test1", ctx);
109 EXPECT_EQ(ret, 0);
110 EXPECT_STREQ(context_str(ctx), "u:r:app_data_file:s0:c512,c768");
111 context_free(ctx);
112 }
113
TEST(AndroidSeAppTest,ParseValidSeInfo)114 TEST(AndroidSeAppTest, ParseValidSeInfo)
115 {
116 struct parsed_seinfo info;
117 memset(&info, 0, sizeof(info));
118
119 string seinfo = "default:privapp:targetSdkVersion=10000:partition=system:complete";
120 int ret = parse_seinfo(seinfo.c_str(), &info);
121
122 EXPECT_EQ(ret, 0);
123 EXPECT_STREQ(info.base, "default");
124 EXPECT_EQ(info.targetSdkVersion, 10000);
125 EXPECT_EQ(info.is, IS_PRIV_APP);
126 EXPECT_EQ(info.isPreinstalledApp, true);
127 EXPECT_STREQ(info.partition, "system");
128
129 seinfo = "platform:ephemeralapp:partition=system:complete";
130 ret = parse_seinfo(seinfo.c_str(), &info);
131
132 EXPECT_EQ(ret, 0);
133 EXPECT_STREQ(info.base, "platform");
134 EXPECT_EQ(info.targetSdkVersion, 0);
135 EXPECT_EQ(info.is, IS_EPHEMERAL_APP);
136 EXPECT_EQ(info.isPreinstalledApp, true);
137 EXPECT_STREQ(info.partition, "system");
138
139 seinfo = "bluetooth";
140 ret = parse_seinfo(seinfo.c_str(), &info);
141
142 EXPECT_EQ(ret, 0);
143 EXPECT_STREQ(info.base, "bluetooth");
144 EXPECT_EQ(info.targetSdkVersion, 0);
145 EXPECT_EQ(info.isPreinstalledApp, false);
146 EXPECT_EQ(info.is, 0);
147 }
148
TEST(AndroidSeAppTest,ParseInvalidSeInfo)149 TEST(AndroidSeAppTest, ParseInvalidSeInfo)
150 {
151 struct parsed_seinfo info;
152
153 string seinfo = "default:targetSdkVersion:complete";
154 int ret = parse_seinfo(seinfo.c_str(), &info);
155 EXPECT_EQ(ret, -1);
156
157 seinfo = "default:targetSdkVersion=:complete";
158 ret = parse_seinfo(seinfo.c_str(), &info);
159 EXPECT_EQ(ret, -1);
160 }
161
TEST(AndroidSeAppTest,ParseOverflow)162 TEST(AndroidSeAppTest, ParseOverflow)
163 {
164 struct parsed_seinfo info;
165
166 string seinfo = std::string(255, 'x');
167 int ret = parse_seinfo(seinfo.c_str(), &info);
168 EXPECT_EQ(ret, 0);
169 EXPECT_STREQ(info.base, seinfo.c_str());
170
171 seinfo = std::string(256, 'x');
172 ret = parse_seinfo(seinfo.c_str(), &info);
173 EXPECT_EQ(ret, -1);
174 }
175
TEST(AndroidSELinuxPathTest,IsAppDataPath)176 TEST(AndroidSELinuxPathTest, IsAppDataPath)
177 {
178 EXPECT_TRUE(is_app_data_path("/data/data"));
179 EXPECT_TRUE(is_app_data_path("/data/user/0"));
180
181 EXPECT_FALSE(is_app_data_path("/data"));
182 }
183
TEST(AndroidSELinuxPathTest,IsCredentialEncryptedPath)184 TEST(AndroidSELinuxPathTest, IsCredentialEncryptedPath)
185 {
186 EXPECT_TRUE(is_credential_encrypted_path("/data/system_ce/0"));
187 EXPECT_TRUE(is_credential_encrypted_path("/data/system_ce/0/backup"));
188 EXPECT_TRUE(is_credential_encrypted_path("/data/misc_ce/0"));
189 EXPECT_TRUE(is_credential_encrypted_path("/data/misc_ce/0/apexdata"));
190 EXPECT_TRUE(is_credential_encrypted_path("/data/vendor_ce/0"));
191 EXPECT_TRUE(is_credential_encrypted_path("/data/vendor_ce/0/data"));
192
193 EXPECT_FALSE(is_credential_encrypted_path("/data"));
194 EXPECT_FALSE(is_credential_encrypted_path("/data/data"));
195 EXPECT_FALSE(is_credential_encrypted_path("/data/user/0"));
196 }
197
TEST(AndroidSELinuxPathTest,ExtractPkgnameAndUserid)198 TEST(AndroidSELinuxPathTest, ExtractPkgnameAndUserid)
199 {
200 char *pkgname = NULL;
201 unsigned int userid;
202
203 EXPECT_EQ(extract_pkgname_and_userid("/data/", &pkgname, &userid), -1);
204
205 char const* path = "/data/user/0/com.android.myapp";
206 EXPECT_EQ(extract_pkgname_and_userid(path, &pkgname, &userid), 0);
207 EXPECT_STREQ("com.android.myapp", pkgname);
208 EXPECT_EQ(userid, 0);
209 free(pkgname);
210 pkgname = NULL;
211
212 path = "/data/user/0/com.android.myapp/som/subdir";
213 EXPECT_EQ(extract_pkgname_and_userid(path, &pkgname, &userid), 0);
214 EXPECT_STREQ("com.android.myapp", pkgname);
215 EXPECT_EQ(userid, 0);
216 free(pkgname);
217 pkgname = NULL;
218
219 path = "/data/data/com.android.myapp2";
220 EXPECT_EQ(extract_pkgname_and_userid(path, &pkgname, &userid), 0);
221 EXPECT_STREQ("com.android.myapp2", pkgname);
222 EXPECT_EQ(userid, 0);
223 free(pkgname);
224 pkgname = NULL;
225
226 path = "/data/misc_de/10/sdksandbox/com.android.myapp3";
227 EXPECT_EQ(extract_pkgname_and_userid(path, &pkgname, &userid), 0);
228 EXPECT_STREQ("com.android.myapp3", pkgname);
229 EXPECT_EQ(userid, 10);
230 free(pkgname);
231 pkgname = NULL;
232 }
233