xref: /aosp_15_r20/external/selinux/libselinux/src/android/android_unittest.cpp (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
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