1 /*
2 * Copyright (C) 2011 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 #include <stdlib.h>
18 #include <string.h>
19
20 #define LOG_TAG "utils_test"
21 #include <utils/Log.h>
22
23 #include <gtest/gtest.h>
24
25 extern "C" {
26 #include "installd.h"
27 }
28
29 #define TEST_DATA_DIR "/data/"
30 #define TEST_APP_DIR "/data/app/"
31 #define TEST_APP_PRIVATE_DIR "/data/app-private/"
32 #define TEST_ASEC_DIR "/mnt/asec/"
33
34 #define TEST_SYSTEM_DIR1 "/system/app/"
35 #define TEST_SYSTEM_DIR2 "/vendor/app/"
36
37 namespace android {
38
39 class UtilsTest : public testing::Test {
40 protected:
SetUp()41 virtual void SetUp() {
42 android_app_dir.path = TEST_APP_DIR;
43 android_app_dir.len = strlen(TEST_APP_DIR);
44
45 android_app_private_dir.path = TEST_APP_PRIVATE_DIR;
46 android_app_private_dir.len = strlen(TEST_APP_PRIVATE_DIR);
47
48 android_data_dir.path = TEST_DATA_DIR;
49 android_data_dir.len = strlen(TEST_DATA_DIR);
50
51 android_asec_dir.path = TEST_ASEC_DIR;
52 android_asec_dir.len = strlen(TEST_ASEC_DIR);
53
54 android_system_dirs.count = 2;
55
56 android_system_dirs.dirs = (dir_rec_t*) calloc(android_system_dirs.count, sizeof(dir_rec_t));
57 android_system_dirs.dirs[0].path = TEST_SYSTEM_DIR1;
58 android_system_dirs.dirs[0].len = strlen(TEST_SYSTEM_DIR1);
59
60 android_system_dirs.dirs[1].path = TEST_SYSTEM_DIR2;
61 android_system_dirs.dirs[1].len = strlen(TEST_SYSTEM_DIR2);
62 }
63
TearDown()64 virtual void TearDown() {
65 free(android_system_dirs.dirs);
66 }
67 };
68
TEST_F(UtilsTest,IsValidApkPath_BadPrefix)69 TEST_F(UtilsTest, IsValidApkPath_BadPrefix) {
70 // Bad prefixes directories
71 const char *badprefix1 = "/etc/passwd";
72 EXPECT_EQ(-1, validate_apk_path(badprefix1))
73 << badprefix1 << " should be allowed as a valid path";
74
75 const char *badprefix2 = "../.." TEST_APP_DIR "../../../blah";
76 EXPECT_EQ(-1, validate_apk_path(badprefix2))
77 << badprefix2 << " should be allowed as a valid path";
78
79 const char *badprefix3 = "init.rc";
80 EXPECT_EQ(-1, validate_apk_path(badprefix3))
81 << badprefix3 << " should be allowed as a valid path";
82
83 const char *badprefix4 = "/init.rc";
84 EXPECT_EQ(-1, validate_apk_path(badprefix4))
85 << badprefix4 << " should be allowed as a valid path";
86 }
87
TEST_F(UtilsTest,IsValidApkPath_Internal)88 TEST_F(UtilsTest, IsValidApkPath_Internal) {
89 // Internal directories
90 const char *internal1 = TEST_APP_DIR "example.apk";
91 EXPECT_EQ(0, validate_apk_path(internal1))
92 << internal1 << " should be allowed as a valid path";
93
94 const char *badint1 = TEST_APP_DIR "../example.apk";
95 EXPECT_EQ(-1, validate_apk_path(badint1))
96 << badint1 << " should be rejected as a invalid path";
97
98 const char *badint2 = TEST_APP_DIR "/../example.apk";
99 EXPECT_EQ(-1, validate_apk_path(badint2))
100 << badint2 << " should be rejected as a invalid path";
101
102 const char *badint3 = TEST_APP_DIR "example.com/pkg.apk";
103 EXPECT_EQ(-1, validate_apk_path(badint3))
104 << badint3 << " should be rejected as a invalid path";
105 }
106
TEST_F(UtilsTest,IsValidApkPath_Private)107 TEST_F(UtilsTest, IsValidApkPath_Private) {
108 // Internal directories
109 const char *private1 = TEST_APP_PRIVATE_DIR "example.apk";
110 EXPECT_EQ(0, validate_apk_path(private1))
111 << private1 << " should be allowed as a valid path";
112
113 const char *badpriv1 = TEST_APP_PRIVATE_DIR "../example.apk";
114 EXPECT_EQ(-1, validate_apk_path(badpriv1))
115 << badpriv1 << " should be rejected as a invalid path";
116
117 const char *badpriv2 = TEST_APP_PRIVATE_DIR "/../example.apk";
118 EXPECT_EQ(-1, validate_apk_path(badpriv2))
119 << badpriv2 << " should be rejected as a invalid path";
120
121 const char *badpriv3 = TEST_APP_PRIVATE_DIR "example.com/pkg.apk";
122 EXPECT_EQ(-1, validate_apk_path(badpriv3))
123 << badpriv3 << " should be rejected as a invalid path";
124 }
125
126
TEST_F(UtilsTest,IsValidApkPath_AsecGood1)127 TEST_F(UtilsTest, IsValidApkPath_AsecGood1) {
128 const char *asec1 = TEST_ASEC_DIR "example.apk";
129 EXPECT_EQ(0, validate_apk_path(asec1))
130 << asec1 << " should be allowed as a valid path";
131 }
132
TEST_F(UtilsTest,IsValidApkPath_AsecGood2)133 TEST_F(UtilsTest, IsValidApkPath_AsecGood2) {
134 const char *asec2 = TEST_ASEC_DIR "com.example.asec/pkg.apk";
135 EXPECT_EQ(0, validate_apk_path(asec2))
136 << asec2 << " should be allowed as a valid path";
137 }
138
TEST_F(UtilsTest,IsValidApkPath_EscapeFail)139 TEST_F(UtilsTest, IsValidApkPath_EscapeFail) {
140 const char *badasec1 = TEST_ASEC_DIR "../example.apk";
141 EXPECT_EQ(-1, validate_apk_path(badasec1))
142 << badasec1 << " should be rejected as a invalid path";
143 }
144
TEST_F(UtilsTest,IsValidApkPath_DoubleSlashFail)145 TEST_F(UtilsTest, IsValidApkPath_DoubleSlashFail) {
146 const char *badasec2 = TEST_ASEC_DIR "com.example.asec//pkg.apk";
147 EXPECT_EQ(-1, validate_apk_path(badasec2))
148 << badasec2 << " should be rejected as a invalid path";
149 }
150
TEST_F(UtilsTest,IsValidApkPath_SubdirEscapeFail)151 TEST_F(UtilsTest, IsValidApkPath_SubdirEscapeFail) {
152 const char *badasec3 = TEST_ASEC_DIR "com.example.asec/../../../pkg.apk";
153 EXPECT_EQ(-1, validate_apk_path(badasec3))
154 << badasec3 << " should be rejected as a invalid path";
155 }
156
TEST_F(UtilsTest,IsValidApkPath_SlashEscapeFail)157 TEST_F(UtilsTest, IsValidApkPath_SlashEscapeFail) {
158 const char *badasec4 = TEST_ASEC_DIR "/../example.apk";
159 EXPECT_EQ(-1, validate_apk_path(badasec4))
160 << badasec4 << " should be rejected as a invalid path";
161 }
162
TEST_F(UtilsTest,IsValidApkPath_CrazyDirFail)163 TEST_F(UtilsTest, IsValidApkPath_CrazyDirFail) {
164 const char *badasec5 = TEST_ASEC_DIR ".//../..";
165 EXPECT_EQ(-1, validate_apk_path(badasec5))
166 << badasec5 << " should be rejected as a invalid path";
167 }
168
TEST_F(UtilsTest,IsValidApkPath_SubdirEscapeSingleFail)169 TEST_F(UtilsTest, IsValidApkPath_SubdirEscapeSingleFail) {
170 const char *badasec6 = TEST_ASEC_DIR "com.example.asec/../pkg.apk";
171 EXPECT_EQ(-1, validate_apk_path(badasec6))
172 << badasec6 << " should be rejected as a invalid path";
173 }
174
TEST_F(UtilsTest,IsValidApkPath_TwoSubdirFail)175 TEST_F(UtilsTest, IsValidApkPath_TwoSubdirFail) {
176 const char *badasec7 = TEST_ASEC_DIR "com.example.asec/subdir1/pkg.apk";
177 EXPECT_EQ(-1, validate_apk_path(badasec7))
178 << badasec7 << " should be rejected as a invalid path";
179 }
180
TEST_F(UtilsTest,CheckSystemApp_Dir1)181 TEST_F(UtilsTest, CheckSystemApp_Dir1) {
182 const char *sysapp1 = TEST_SYSTEM_DIR1 "Voice.apk";
183 EXPECT_EQ(0, validate_system_app_path(sysapp1))
184 << sysapp1 << " should be allowed as a system path";
185 }
186
TEST_F(UtilsTest,CheckSystemApp_Dir2)187 TEST_F(UtilsTest, CheckSystemApp_Dir2) {
188 const char *sysapp2 = TEST_SYSTEM_DIR2 "com.example.myapp.apk";
189 EXPECT_EQ(0, validate_system_app_path(sysapp2))
190 << sysapp2 << " should be allowed as a system path";
191 }
192
TEST_F(UtilsTest,CheckSystemApp_EscapeFail)193 TEST_F(UtilsTest, CheckSystemApp_EscapeFail) {
194 const char *badapp1 = TEST_SYSTEM_DIR1 "../com.example.apk";
195 EXPECT_EQ(-1, validate_system_app_path(badapp1))
196 << badapp1 << " should be rejected not a system path";
197 }
198
TEST_F(UtilsTest,CheckSystemApp_DoubleEscapeFail)199 TEST_F(UtilsTest, CheckSystemApp_DoubleEscapeFail) {
200 const char *badapp2 = TEST_SYSTEM_DIR2 "/../../com.example.apk";
201 EXPECT_EQ(-1, validate_system_app_path(badapp2))
202 << badapp2 << " should be rejected not a system path";
203 }
204
TEST_F(UtilsTest,CheckSystemApp_BadPathEscapeFail)205 TEST_F(UtilsTest, CheckSystemApp_BadPathEscapeFail) {
206 const char *badapp3 = TEST_APP_DIR "/../../com.example.apk";
207 EXPECT_EQ(-1, validate_system_app_path(badapp3))
208 << badapp3 << " should be rejected not a system path";
209 }
210
TEST_F(UtilsTest,GetPathFromString_NullPathFail)211 TEST_F(UtilsTest, GetPathFromString_NullPathFail) {
212 dir_rec_t test1;
213 EXPECT_EQ(-1, get_path_from_string(&test1, NULL))
214 << "Should not allow NULL as a path.";
215 }
216
TEST_F(UtilsTest,GetPathFromString_EmptyPathFail)217 TEST_F(UtilsTest, GetPathFromString_EmptyPathFail) {
218 dir_rec_t test1;
219 EXPECT_EQ(-1, get_path_from_string(&test1, ""))
220 << "Should not allow empty paths.";
221 }
222
TEST_F(UtilsTest,GetPathFromString_RelativePathFail)223 TEST_F(UtilsTest, GetPathFromString_RelativePathFail) {
224 dir_rec_t test1;
225 EXPECT_EQ(-1, get_path_from_string(&test1, "mnt/asec"))
226 << "Should not allow relative paths.";
227 }
228
TEST_F(UtilsTest,GetPathFromString_NonCanonical)229 TEST_F(UtilsTest, GetPathFromString_NonCanonical) {
230 dir_rec_t test1;
231
232 EXPECT_EQ(0, get_path_from_string(&test1, "/mnt/asec"))
233 << "Should be able to canonicalize directory /mnt/asec";
234 EXPECT_STREQ("/mnt/asec/", test1.path)
235 << "/mnt/asec should be canonicalized to /mnt/asec/";
236 EXPECT_EQ(10, (ssize_t) test1.len)
237 << "path len should be equal to the length of /mnt/asec/ (10)";
238 free(test1.path);
239 }
240
TEST_F(UtilsTest,GetPathFromString_CanonicalPath)241 TEST_F(UtilsTest, GetPathFromString_CanonicalPath) {
242 dir_rec_t test3;
243 EXPECT_EQ(0, get_path_from_string(&test3, "/data/app/"))
244 << "Should be able to canonicalize directory /data/app/";
245 EXPECT_STREQ("/data/app/", test3.path)
246 << "/data/app/ should be canonicalized to /data/app/";
247 EXPECT_EQ(10, (ssize_t) test3.len)
248 << "path len should be equal to the length of /data/app/ (10)";
249 free(test3.path);
250 }
251
TEST_F(UtilsTest,CreatePkgPath_LongPkgNameSuccess)252 TEST_F(UtilsTest, CreatePkgPath_LongPkgNameSuccess) {
253 char path[PKG_PATH_MAX];
254
255 // Create long packagename of "aaaaa..."
256 size_t pkgnameSize = PKG_NAME_MAX;
257 char pkgname[pkgnameSize + 1];
258 memset(pkgname, 'a', pkgnameSize);
259 pkgname[pkgnameSize] = '\0';
260
261 EXPECT_EQ(0, create_pkg_path(path, pkgname, "", 0))
262 << "Should successfully be able to create package name.";
263
264 const char *prefix = TEST_DATA_DIR PRIMARY_USER_PREFIX;
265 size_t offset = strlen(prefix);
266 EXPECT_STREQ(pkgname, path + offset)
267 << "Package path should be a really long string of a's";
268 }
269
TEST_F(UtilsTest,CreatePkgPath_LongPkgNameFail)270 TEST_F(UtilsTest, CreatePkgPath_LongPkgNameFail) {
271 char path[PKG_PATH_MAX];
272
273 // Create long packagename of "aaaaa..."
274 size_t pkgnameSize = PKG_NAME_MAX + 1;
275 char pkgname[pkgnameSize + 1];
276 memset(pkgname, 'a', pkgnameSize);
277 pkgname[pkgnameSize] = '\0';
278
279 EXPECT_EQ(-1, create_pkg_path(path, pkgname, "", 0))
280 << "Should return error because package name is too long.";
281 }
282
TEST_F(UtilsTest,CreatePkgPath_LongPostfixFail)283 TEST_F(UtilsTest, CreatePkgPath_LongPostfixFail) {
284 char path[PKG_PATH_MAX];
285
286 // Create long packagename of "aaaaa..."
287 size_t postfixSize = PKG_PATH_MAX;
288 char postfix[postfixSize + 1];
289 memset(postfix, 'a', postfixSize);
290 postfix[postfixSize] = '\0';
291
292 EXPECT_EQ(-1, create_pkg_path(path, "com.example.package", postfix, 0))
293 << "Should return error because postfix is too long.";
294 }
295
TEST_F(UtilsTest,CreatePkgPath_PrimaryUser)296 TEST_F(UtilsTest, CreatePkgPath_PrimaryUser) {
297 char path[PKG_PATH_MAX];
298
299 EXPECT_EQ(0, create_pkg_path(path, "com.example.package", "", 0))
300 << "Should return error because postfix is too long.";
301
302 EXPECT_STREQ(TEST_DATA_DIR PRIMARY_USER_PREFIX "com.example.package", path)
303 << "Package path should be in /data/data/";
304 }
305
TEST_F(UtilsTest,CreatePkgPath_SecondaryUser)306 TEST_F(UtilsTest, CreatePkgPath_SecondaryUser) {
307 char path[PKG_PATH_MAX];
308
309 EXPECT_EQ(0, create_pkg_path(path, "com.example.package", "", 1))
310 << "Should successfully create package path.";
311
312 EXPECT_STREQ(TEST_DATA_DIR SECONDARY_USER_PREFIX "1/com.example.package", path)
313 << "Package path should be in /data/user/";
314 }
315
TEST_F(UtilsTest,CreatePkgPathInDir_ProtectedDir)316 TEST_F(UtilsTest, CreatePkgPathInDir_ProtectedDir) {
317 char path[PKG_PATH_MAX];
318
319 dir_rec_t dir;
320 dir.path = "/data/app-private/";
321 dir.len = strlen(dir.path);
322
323 EXPECT_EQ(0, create_pkg_path_in_dir(path, &dir, "com.example.package", ".apk"))
324 << "Should successfully create package path.";
325
326 EXPECT_STREQ("/data/app-private/com.example.package.apk", path)
327 << "Package path should be in /data/app-private/";
328 }
329
TEST_F(UtilsTest,CopyAndAppend_Normal)330 TEST_F(UtilsTest, CopyAndAppend_Normal) {
331 //int copy_and_append(dir_rec_t* dst, dir_rec_t* src, char* suffix)
332 dir_rec_t dst;
333 dir_rec_t src;
334
335 src.path = "/data/";
336 src.len = strlen(src.path);
337
338 EXPECT_EQ(0, copy_and_append(&dst, &src, "app/"))
339 << "Should return error because postfix is too long.";
340
341 EXPECT_STREQ("/data/app/", dst.path)
342 << "Appended path should be correct";
343
344 EXPECT_EQ(10, (ssize_t) dst.len)
345 << "Appended path should be length of '/data/app/' (10)";
346 }
347
TEST_F(UtilsTest,AppendAndIncrement_Normal)348 TEST_F(UtilsTest, AppendAndIncrement_Normal) {
349 size_t dst_size = 10;
350 char dst[dst_size];
351 char *dstp = dst;
352 const char* src = "FOO";
353
354 EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size))
355 << "String should append successfully";
356
357 EXPECT_STREQ("FOO", dst)
358 << "String should append correctly";
359
360 EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size))
361 << "String should append successfully again";
362
363 EXPECT_STREQ("FOOFOO", dst)
364 << "String should append correctly again";
365 }
366
TEST_F(UtilsTest,AppendAndIncrement_TooBig)367 TEST_F(UtilsTest, AppendAndIncrement_TooBig) {
368 size_t dst_size = 5;
369 char dst[dst_size];
370 char *dstp = dst;
371 const char* src = "FOO";
372
373 EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size))
374 << "String should append successfully";
375
376 EXPECT_STREQ("FOO", dst)
377 << "String should append correctly";
378
379 EXPECT_EQ(-1, append_and_increment(&dstp, src, &dst_size))
380 << "String should fail because it's too large to fit";
381 }
382
383 }
384