installd_utils_test.cpp revision 86c9584559439504fc57ece2ccd9b6cbd568430c
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
25extern "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
37namespace android {
38
39class UtilsTest : public testing::Test {
40protected:
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
64    virtual void TearDown() {
65        free(android_system_dirs.dirs);
66    }
67};
68
69TEST_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
88TEST_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
107TEST_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
127TEST_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
133TEST_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
139TEST_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
145TEST_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
151TEST_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
157TEST_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
163TEST_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
169TEST_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
175TEST_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
181TEST_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
187TEST_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
193TEST_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
199TEST_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
205TEST_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
211TEST_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
217TEST_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
223TEST_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
229TEST_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
241TEST_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
252TEST_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
270TEST_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
283TEST_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
296TEST_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
306TEST_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
316TEST_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
330TEST_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
348TEST_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
367TEST_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