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