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#include <gtest/gtest.h>
21
22#include "installd.h"
23
24#undef LOG_TAG
25#define LOG_TAG "utils_test"
26
27#define TEST_DATA_DIR "/data/"
28#define TEST_APP_DIR "/data/app/"
29#define TEST_APP_PRIVATE_DIR "/data/app-private/"
30#define TEST_ASEC_DIR "/mnt/asec/"
31#define TEST_EXPAND_DIR "/mnt/expand/"
32
33#define TEST_SYSTEM_DIR1 "/system/app/"
34#define TEST_SYSTEM_DIR2 "/vendor/app/"
35
36#define REALLY_LONG_APP_NAME "com.example." \
37        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \
38        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \
39        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
40
41#define REALLY_LONG_LEAF_NAME "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
42        "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
43        "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
44        "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_"
45
46namespace android {
47
48class UtilsTest : public testing::Test {
49protected:
50    virtual void SetUp() {
51        android_app_dir.path = (char*) TEST_APP_DIR;
52        android_app_dir.len = strlen(TEST_APP_DIR);
53
54        android_app_private_dir.path = (char*) TEST_APP_PRIVATE_DIR;
55        android_app_private_dir.len = strlen(TEST_APP_PRIVATE_DIR);
56
57        android_data_dir.path = (char*) TEST_DATA_DIR;
58        android_data_dir.len = strlen(TEST_DATA_DIR);
59
60        android_asec_dir.path = (char*) TEST_ASEC_DIR;
61        android_asec_dir.len = strlen(TEST_ASEC_DIR);
62
63        android_mnt_expand_dir.path = (char*) TEST_EXPAND_DIR;
64        android_mnt_expand_dir.len = strlen(TEST_EXPAND_DIR);
65
66        android_system_dirs.count = 2;
67
68        android_system_dirs.dirs = (dir_rec_t*) calloc(android_system_dirs.count, sizeof(dir_rec_t));
69        android_system_dirs.dirs[0].path = (char*) TEST_SYSTEM_DIR1;
70        android_system_dirs.dirs[0].len = strlen(TEST_SYSTEM_DIR1);
71
72        android_system_dirs.dirs[1].path = (char*) TEST_SYSTEM_DIR2;
73        android_system_dirs.dirs[1].len = strlen(TEST_SYSTEM_DIR2);
74    }
75
76    virtual void TearDown() {
77        free(android_system_dirs.dirs);
78    }
79};
80
81TEST_F(UtilsTest, IsValidApkPath_BadPrefix) {
82    // Bad prefixes directories
83    const char *badprefix1 = "/etc/passwd";
84    EXPECT_EQ(-1, validate_apk_path(badprefix1))
85            << badprefix1 << " should be allowed as a valid path";
86
87    const char *badprefix2 = "../.." TEST_APP_DIR "../../../blah";
88    EXPECT_EQ(-1, validate_apk_path(badprefix2))
89            << badprefix2 << " should be allowed as a valid path";
90
91    const char *badprefix3 = "init.rc";
92    EXPECT_EQ(-1, validate_apk_path(badprefix3))
93            << badprefix3 << " should be allowed as a valid path";
94
95    const char *badprefix4 = "/init.rc";
96    EXPECT_EQ(-1, validate_apk_path(badprefix4))
97            << badprefix4 << " should be allowed as a valid path";
98}
99
100TEST_F(UtilsTest, IsValidApkPath_Internal) {
101    // Internal directories
102    const char *internal1 = TEST_APP_DIR "example.apk";
103    EXPECT_EQ(0, validate_apk_path(internal1))
104            << internal1 << " should be allowed as a valid path";
105
106    // b/16888084
107    const char *path2 = TEST_APP_DIR "example.com/example.apk";
108    EXPECT_EQ(0, validate_apk_path(path2))
109            << path2 << " should be allowed as a valid path";
110
111    const char *badint1 = TEST_APP_DIR "../example.apk";
112    EXPECT_EQ(-1, validate_apk_path(badint1))
113            << badint1 << " should be rejected as a invalid path";
114
115    const char *badint2 = TEST_APP_DIR "/../example.apk";
116    EXPECT_EQ(-1, validate_apk_path(badint2))
117            << badint2 << " should be rejected as a invalid path";
118
119    // Only one subdir should be allowed.
120    const char *bad_path3 = TEST_APP_DIR "example.com/subdir/pkg.apk";
121    EXPECT_EQ(-1, validate_apk_path(bad_path3))
122            << bad_path3 << " should be rejected as a invalid path";
123
124    const char *bad_path4 = TEST_APP_DIR "example.com/subdir/../pkg.apk";
125    EXPECT_EQ(-1, validate_apk_path(bad_path4))
126            << bad_path4 << " should be rejected as a invalid path";
127
128    const char *bad_path5 = TEST_APP_DIR "example.com1/../example.com2/pkg.apk";
129    EXPECT_EQ(-1, validate_apk_path(bad_path5))
130            << bad_path5 << " should be rejected as a invalid path";
131}
132
133TEST_F(UtilsTest, IsValidApkPath_Private) {
134    // Internal directories
135    const char *private1 = TEST_APP_PRIVATE_DIR "example.apk";
136    EXPECT_EQ(0, validate_apk_path(private1))
137            << private1 << " should be allowed as a valid path";
138
139    // b/16888084
140    const char *path2 = TEST_APP_DIR "example.com/example.apk";
141    EXPECT_EQ(0, validate_apk_path(path2))
142            << path2 << " should be allowed as a valid path";
143
144    const char *badpriv1 = TEST_APP_PRIVATE_DIR "../example.apk";
145    EXPECT_EQ(-1, validate_apk_path(badpriv1))
146            << badpriv1 << " should be rejected as a invalid path";
147
148    const char *badpriv2 = TEST_APP_PRIVATE_DIR "/../example.apk";
149    EXPECT_EQ(-1, validate_apk_path(badpriv2))
150            << badpriv2 << " should be rejected as a invalid path";
151
152    // Only one subdir should be allowed.
153    const char *bad_path3 = TEST_APP_PRIVATE_DIR "example.com/subdir/pkg.apk";
154    EXPECT_EQ(-1, validate_apk_path(bad_path3))
155            << bad_path3 << " should be rejected as a invalid path";
156
157    const char *bad_path4 = TEST_APP_PRIVATE_DIR "example.com/subdir/../pkg.apk";
158    EXPECT_EQ(-1, validate_apk_path(bad_path4))
159            << bad_path4 << " should be rejected as a invalid path";
160
161    const char *bad_path5 = TEST_APP_PRIVATE_DIR "example.com1/../example.com2/pkg.apk";
162    EXPECT_EQ(-1, validate_apk_path(bad_path5))
163            << bad_path5 << " should be rejected as a invalid path";
164}
165
166
167TEST_F(UtilsTest, IsValidApkPath_AsecGood1) {
168    const char *asec1 = TEST_ASEC_DIR "example.apk";
169    EXPECT_EQ(0, validate_apk_path(asec1))
170            << asec1 << " should be allowed as a valid path";
171}
172
173TEST_F(UtilsTest, IsValidApkPath_AsecGood2) {
174    const char *asec2 = TEST_ASEC_DIR "com.example.asec/pkg.apk";
175    EXPECT_EQ(0, validate_apk_path(asec2))
176            << asec2 << " should be allowed as a valid path";
177}
178
179TEST_F(UtilsTest, IsValidApkPath_EscapeFail) {
180    const char *badasec1 = TEST_ASEC_DIR "../example.apk";
181    EXPECT_EQ(-1, validate_apk_path(badasec1))
182            << badasec1 << " should be rejected as a invalid path";
183}
184
185TEST_F(UtilsTest, IsValidApkPath_DoubleSlashFail) {
186    const char *badasec2 = TEST_ASEC_DIR "com.example.asec//pkg.apk";
187    EXPECT_EQ(-1, validate_apk_path(badasec2))
188            << badasec2 << " should be rejected as a invalid path";
189}
190
191TEST_F(UtilsTest, IsValidApkPath_SubdirEscapeFail) {
192    const char *badasec3 = TEST_ASEC_DIR "com.example.asec/../../../pkg.apk";
193    EXPECT_EQ(-1, validate_apk_path(badasec3))
194            << badasec3  << " should be rejected as a invalid path";
195}
196
197TEST_F(UtilsTest, IsValidApkPath_SlashEscapeFail) {
198    const char *badasec4 = TEST_ASEC_DIR "/../example.apk";
199    EXPECT_EQ(-1, validate_apk_path(badasec4))
200            << badasec4 << " should be rejected as a invalid path";
201}
202
203TEST_F(UtilsTest, IsValidApkPath_CrazyDirFail) {
204    const char *badasec5 = TEST_ASEC_DIR ".//../..";
205    EXPECT_EQ(-1, validate_apk_path(badasec5))
206            << badasec5 << " should be rejected as a invalid path";
207}
208
209TEST_F(UtilsTest, IsValidApkPath_SubdirEscapeSingleFail) {
210    const char *badasec6 = TEST_ASEC_DIR "com.example.asec/../pkg.apk";
211    EXPECT_EQ(-1, validate_apk_path(badasec6))
212            << badasec6 << " should be rejected as a invalid path";
213}
214
215TEST_F(UtilsTest, IsValidApkPath_TwoSubdirFail) {
216    const char *badasec7 = TEST_ASEC_DIR "com.example.asec/subdir1/pkg.apk";
217    EXPECT_EQ(-1, validate_apk_path(badasec7))
218            << badasec7 << " should be rejected as a invalid path";
219}
220
221TEST_F(UtilsTest, CheckSystemApp_Dir1) {
222    const char *sysapp1 = TEST_SYSTEM_DIR1 "Voice.apk";
223    EXPECT_EQ(0, validate_system_app_path(sysapp1))
224            << sysapp1 << " should be allowed as a system path";
225}
226
227TEST_F(UtilsTest, CheckSystemApp_Dir2) {
228    const char *sysapp2 = TEST_SYSTEM_DIR2 "com.example.myapp.apk";
229    EXPECT_EQ(0, validate_system_app_path(sysapp2))
230            << sysapp2 << " should be allowed as a system path";
231}
232
233TEST_F(UtilsTest, CheckSystemApp_EscapeFail) {
234    const char *badapp1 = TEST_SYSTEM_DIR1 "../com.example.apk";
235    EXPECT_EQ(-1, validate_system_app_path(badapp1))
236            << badapp1 << " should be rejected not a system path";
237}
238
239TEST_F(UtilsTest, CheckSystemApp_DoubleEscapeFail) {
240    const char *badapp2 = TEST_SYSTEM_DIR2 "/../../com.example.apk";
241    EXPECT_EQ(-1, validate_system_app_path(badapp2))
242            << badapp2 << " should be rejected not a system path";
243}
244
245TEST_F(UtilsTest, CheckSystemApp_BadPathEscapeFail) {
246    const char *badapp3 = TEST_APP_DIR "/../../com.example.apk";
247    EXPECT_EQ(-1, validate_system_app_path(badapp3))
248            << badapp3 << " should be rejected not a system path";
249}
250
251TEST_F(UtilsTest, CheckSystemApp_Subdir) {
252    const char *sysapp = TEST_SYSTEM_DIR1 "com.example/com.example.apk";
253    EXPECT_EQ(0, validate_system_app_path(sysapp))
254            << sysapp << " should be allowed as a system path";
255
256    const char *badapp = TEST_SYSTEM_DIR1 "com.example/subdir/com.example.apk";
257    EXPECT_EQ(-1, validate_system_app_path(badapp))
258            << badapp << " should be rejected not a system path";
259
260    const char *badapp1 = TEST_SYSTEM_DIR1 "com.example/subdir/../com.example.apk";
261    EXPECT_EQ(-1, validate_system_app_path(badapp1))
262            << badapp1 << " should be rejected not a system path";
263
264    const char *badapp2 = TEST_SYSTEM_DIR1 "com.example1/../com.example2/com.example.apk";
265    EXPECT_EQ(-1, validate_system_app_path(badapp2))
266            << badapp2 << " should be rejected not a system path";
267}
268
269TEST_F(UtilsTest, GetPathFromString_NullPathFail) {
270    dir_rec_t test1;
271    EXPECT_EQ(-1, get_path_from_string(&test1, (const char *) NULL))
272            << "Should not allow NULL as a path.";
273}
274
275TEST_F(UtilsTest, GetPathFromString_EmptyPathFail) {
276    dir_rec_t test1;
277    EXPECT_EQ(-1, get_path_from_string(&test1, ""))
278            << "Should not allow empty paths.";
279}
280
281TEST_F(UtilsTest, GetPathFromString_RelativePathFail) {
282    dir_rec_t test1;
283    EXPECT_EQ(-1, get_path_from_string(&test1, "mnt/asec"))
284            << "Should not allow relative paths.";
285}
286
287TEST_F(UtilsTest, GetPathFromString_NonCanonical) {
288    dir_rec_t test1;
289
290    EXPECT_EQ(0, get_path_from_string(&test1, "/mnt/asec"))
291            << "Should be able to canonicalize directory /mnt/asec";
292    EXPECT_STREQ("/mnt/asec/", test1.path)
293            << "/mnt/asec should be canonicalized to /mnt/asec/";
294    EXPECT_EQ(10, (ssize_t) test1.len)
295            << "path len should be equal to the length of /mnt/asec/ (10)";
296    free(test1.path);
297}
298
299TEST_F(UtilsTest, GetPathFromString_CanonicalPath) {
300    dir_rec_t test3;
301    EXPECT_EQ(0, get_path_from_string(&test3, "/data/app/"))
302            << "Should be able to canonicalize directory /data/app/";
303    EXPECT_STREQ("/data/app/", test3.path)
304            << "/data/app/ should be canonicalized to /data/app/";
305    EXPECT_EQ(10, (ssize_t) test3.len)
306            << "path len should be equal to the length of /data/app/ (10)";
307    free(test3.path);
308}
309
310TEST_F(UtilsTest, CreatePkgPath_LongPkgNameSuccess) {
311    char path[PKG_PATH_MAX];
312
313    // Create long packagename of "aaaaa..."
314    size_t pkgnameSize = PKG_NAME_MAX;
315    char pkgname[pkgnameSize + 1];
316    memset(pkgname, 'a', pkgnameSize);
317    pkgname[pkgnameSize] = '\0';
318
319    EXPECT_EQ(0, create_pkg_path(path, pkgname, "", 0))
320            << "Should successfully be able to create package name.";
321
322    const char *prefix = TEST_DATA_DIR PRIMARY_USER_PREFIX;
323    size_t offset = strlen(prefix);
324
325    EXPECT_STREQ(pkgname, path + offset)
326             << "Package path should be a really long string of a's";
327}
328
329TEST_F(UtilsTest, CreatePkgPath_LongPkgNameFail) {
330    char path[PKG_PATH_MAX];
331
332    // Create long packagename of "aaaaa..."
333    size_t pkgnameSize = PKG_NAME_MAX + 1;
334    char pkgname[pkgnameSize + 1];
335    memset(pkgname, 'a', pkgnameSize);
336    pkgname[pkgnameSize] = '\0';
337
338    EXPECT_EQ(-1, create_pkg_path(path, pkgname, "", 0))
339            << "Should return error because package name is too long.";
340}
341
342TEST_F(UtilsTest, CreatePkgPath_LongPostfixFail) {
343    char path[PKG_PATH_MAX];
344
345    // Create long packagename of "aaaaa..."
346    size_t postfixSize = PKG_PATH_MAX;
347    char postfix[postfixSize + 1];
348    memset(postfix, 'a', postfixSize);
349    postfix[postfixSize] = '\0';
350
351    EXPECT_EQ(-1, create_pkg_path(path, "com.example.package", postfix, 0))
352            << "Should return error because postfix is too long.";
353}
354
355TEST_F(UtilsTest, CreatePkgPath_PrimaryUser) {
356    char path[PKG_PATH_MAX];
357
358    EXPECT_EQ(0, create_pkg_path(path, "com.example.package", "", 0))
359            << "Should return error because postfix is too long.";
360
361    EXPECT_STREQ(TEST_DATA_DIR PRIMARY_USER_PREFIX "com.example.package", path)
362            << "Package path should be in /data/data/";
363}
364
365TEST_F(UtilsTest, CreatePkgPath_SecondaryUser) {
366    char path[PKG_PATH_MAX];
367
368    EXPECT_EQ(0, create_pkg_path(path, "com.example.package", "", 1))
369            << "Should successfully create package path.";
370
371    EXPECT_STREQ(TEST_DATA_DIR SECONDARY_USER_PREFIX "1/com.example.package", path)
372            << "Package path should be in /data/user/";
373}
374
375TEST_F(UtilsTest, CreateMovePath_Primary) {
376    char path[PKG_PATH_MAX];
377
378    EXPECT_EQ(0, create_move_path(path, "com.android.test", "shared_prefs", 0))
379            << "Should be able to create move path for primary user";
380
381    EXPECT_STREQ("/data/data/com.android.test/shared_prefs", path)
382            << "Primary user package directory should be created correctly";
383}
384
385TEST_F(UtilsTest, CreateMovePath_Fail_AppTooLong) {
386    char path[PKG_PATH_MAX];
387
388    EXPECT_EQ(-1, create_move_path(path, REALLY_LONG_APP_NAME, "shared_prefs", 0))
389            << "Should fail to create move path for primary user";
390}
391
392TEST_F(UtilsTest, CreateMovePath_Fail_LeafTooLong) {
393    char path[PKG_PATH_MAX];
394
395    EXPECT_EQ(-1, create_move_path(path, "com.android.test", REALLY_LONG_LEAF_NAME, 0))
396            << "Should fail to create move path for primary user";
397}
398
399TEST_F(UtilsTest, CopyAndAppend_Normal) {
400    //int copy_and_append(dir_rec_t* dst, dir_rec_t* src, char* suffix)
401    dir_rec_t dst;
402    dir_rec_t src;
403
404    src.path = (char*) "/data/";
405    src.len = strlen(src.path);
406
407    EXPECT_EQ(0, copy_and_append(&dst, &src, "app/"))
408            << "Should return error because postfix is too long.";
409
410    EXPECT_STREQ("/data/app/", dst.path)
411            << "Appended path should be correct";
412
413    EXPECT_EQ(10, (ssize_t) dst.len)
414            << "Appended path should be length of '/data/app/' (10)";
415}
416
417TEST_F(UtilsTest, AppendAndIncrement_Normal) {
418    size_t dst_size = 10;
419    char dst[dst_size];
420    char *dstp = dst;
421    const char* src = "FOO";
422
423    EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size))
424            << "String should append successfully";
425
426    EXPECT_STREQ("FOO", dst)
427            << "String should append correctly";
428
429    EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size))
430            << "String should append successfully again";
431
432    EXPECT_STREQ("FOOFOO", dst)
433            << "String should append correctly again";
434}
435
436TEST_F(UtilsTest, AppendAndIncrement_TooBig) {
437    size_t dst_size = 5;
438    char dst[dst_size];
439    char *dstp = dst;
440    const char* src = "FOO";
441
442    EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size))
443            << "String should append successfully";
444
445    EXPECT_STREQ("FOO", dst)
446            << "String should append correctly";
447
448    EXPECT_EQ(-1, append_and_increment(&dstp, src, &dst_size))
449            << "String should fail because it's too large to fit";
450}
451
452TEST_F(UtilsTest, CreateDataPath) {
453    EXPECT_EQ("/data", create_data_path(nullptr));
454    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b",
455            create_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b"));
456}
457
458TEST_F(UtilsTest, CreateDataAppPath) {
459    EXPECT_EQ("/data/app", create_data_app_path(nullptr));
460
461    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/app",
462            create_data_app_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b"));
463}
464
465TEST_F(UtilsTest, CreateDataUserPath) {
466    EXPECT_EQ("/data/data", create_data_user_path(nullptr, 0));
467    EXPECT_EQ("/data/user/10", create_data_user_path(nullptr, 10));
468
469    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/0",
470            create_data_user_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 0));
471    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/10",
472            create_data_user_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10));
473}
474
475TEST_F(UtilsTest, CreateDataMediaPath) {
476    EXPECT_EQ("/data/media/0", create_data_media_path(nullptr, 0));
477    EXPECT_EQ("/data/media/10", create_data_media_path(nullptr, 10));
478
479    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/media/0",
480            create_data_media_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 0));
481    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/media/10",
482            create_data_media_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10));
483}
484
485TEST_F(UtilsTest, CreateDataAppPackagePath) {
486    EXPECT_EQ("/data/app/com.example", create_data_app_package_path(nullptr, "com.example"));
487
488    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/app/com.example",
489            create_data_app_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example"));
490}
491
492TEST_F(UtilsTest, CreateDataUserPackagePath) {
493    EXPECT_EQ("/data/data/com.example", create_data_user_package_path(nullptr, 0, "com.example"));
494    EXPECT_EQ("/data/user/10/com.example", create_data_user_package_path(nullptr, 10, "com.example"));
495
496    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/0/com.example",
497            create_data_user_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 0, "com.example"));
498    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/10/com.example",
499            create_data_user_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10, "com.example"));
500}
501
502}
503