• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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