Fix non-sharing problem of trusted directory for OSP compatible application
[platform/framework/native/env-config.git] / osp-env-config.c
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #ifndef _GNU_SOURCE
19 #define _GNU_SOURCE
20 #endif
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sched.h>
26 #include <sys/mount.h>
27 #include <errno.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <limits.h>
31 #include <sys/prctl.h>
32 #include <sys/vfs.h>
33
34 #include <dlog.h>
35 #include <vconf.h>
36
37 #undef LOG_TAG
38 #define LOG_TAG "ENV_CONFIG"
39
40 #define _MAX_PACKAGEID_LENGTH 10
41 #define _MAX_APIVERSION_LENGTH 3
42
43 static const char* _OSP_HOME_PATH = "/opt/osp/\0"; // /opt/apps/com.samsung.osp
44 static const char* _OSP_COMPAT_SHARED_PATH = "/opt/usr/share/.osp-compat/\0";
45 static const char* _EXT_OSP_HOME_PATH = "/opt/storage/sdcard/osp/\0";
46
47 struct _path_info
48 {
49     char src_path[PATH_MAX];
50     char dest_path[PATH_MAX];
51 };
52
53 struct _dir_info
54 {
55         char path[PATH_MAX];
56         mode_t mode;
57         char app_privilege; // 0: root privilege
58 };
59
60 /*
61  * XXX: The returned app_roodir must be freed in caller.
62  */
63 static char*
64 get_app_rootpath_from_path(const char* bin_path)
65 {
66         char* app_rootpath = NULL;
67         char* delimiter = NULL;
68         size_t length = 0;
69         /* e.g., The specified bin_path is "/opt/apps/com.samsung.basicapp/bin/basicapp" */
70
71         length = strlen(bin_path);
72         app_rootpath = (char *)malloc(length + 1);
73         if(app_rootpath == NULL)
74                 return NULL;
75
76         memset(app_rootpath, '\0', length + 1);
77         strncpy(app_rootpath, bin_path, length);
78
79         LOGI("input bin_path: %s", app_rootpath);
80
81         delimiter = strrchr(app_rootpath, '/');
82         *delimiter = '\0';
83
84         delimiter  = strrchr(app_rootpath, '/');
85         *delimiter = '\0';
86
87         return app_rootpath;
88 }
89
90 static void
91 get_package_id_from_app_rootpath(const char* app_rootpath, char* package_id)
92 {
93         const char* p = NULL;
94         if (strncmp(app_rootpath, "/opt/apps/org.tizen.", 19) == 0)
95         {
96         p = strrchr(app_rootpath, '.') + 1;
97         }
98         else
99         {
100         p = strrchr(app_rootpath, '/') + 1;
101         }
102         strncpy(package_id, p, _MAX_PACKAGEID_LENGTH);
103     package_id[_MAX_PACKAGEID_LENGTH] = '\0';
104     LOGI("package id: %s", package_id);
105 }
106
107 static void
108 get_package_id_from_package_name(const char* package_name, char* package_id)
109 {
110     char* tmpbuf = NULL;
111
112     if (strncmp(package_name, "com", 3) == 0)
113     {   // in case of com.samsung.#osp#[package_id]#[serviceid]
114         tmpbuf = strstr(package_name, "#osp#");
115         if (tmpbuf != NULL)
116         {
117             strncpy(package_id, tmpbuf + 5, _MAX_PACKAGEID_LENGTH);
118         }
119     }
120     else if (strncmp(package_name, "osp", 3) == 0)
121     {   // in case of osp.[package_id].#osp#[serviceid]
122         tmpbuf = strstr(package_name, "osp.");
123         if (tmpbuf != NULL)
124         {
125             strncpy(package_id, tmpbuf + 4, _MAX_PACKAGEID_LENGTH);
126         }
127     }
128         else if (strncmp(package_name, "org.tizen", 9) == 0)
129         {
130                 // in case of org.tizen.[package_id]#[serviceid]
131                 tmpbuf = strstr(package_name, "org.tizen.");
132                 if (tmpbuf != NULL)
133                 {
134                         strncpy(package_id, tmpbuf + 10, _MAX_PACKAGEID_LENGTH);
135                 }
136         }
137     else if (strlen(package_name) == 10)
138     {
139                 strncpy(package_id, package_name, _MAX_PACKAGEID_LENGTH);
140     }
141     else
142     {
143         LOGE("package name is invalid (%s)", package_name);
144     }
145
146     package_id[_MAX_PACKAGEID_LENGTH] = '\0';
147     LOGI("package_id: %s", package_id);
148 }
149
150 static int
151 internal_is_mounted(const char* pkgid)
152 {
153         char mount_flag[64] = { 0, };
154         static const char dir[][64] =
155         {
156                 { "/tmp/osp-compat" },
157                 { "/tmp/osp-compat/mount" },
158                 { "/tmp/osp-compat/mount/internal" }
159         };
160
161         sprintf(mount_flag, "/tmp/osp-compat/mount/internal/%s", pkgid);
162         int res = access(mount_flag, F_OK);
163         if (res == 0)
164         {
165                 LOGI("Intenal path is already mounted.");
166                 return 1;
167         }
168         else if (res == -1 && errno == ENOENT)
169         {
170                 int i = 0;
171                 for (i = 0; i < sizeof(dir)/64; ++i)
172                 {
173                         int res = mkdir(dir[i], 0755);
174                         if (res == -1 && errno != EEXIST)
175                         {
176                                 LOGE("Failed to create directory (%s), errno: %d (%s)", dir[i], errno, strerror(errno));
177                                 return 1;
178                         }
179                 }
180
181                 int fd = creat(mount_flag, 0644);
182                 if (fd == -1)
183                 {
184                         LOGE("Failed to create mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
185                         return 1;
186                 }
187                 close(fd);
188         }
189         else
190         {
191                 LOGE("Failed to access mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
192                 return 1;
193         }
194
195         LOGI("Intenal path mount succeeded.");
196         return 0;
197 }
198
199 static int
200 external_is_mounted(const char* pkgid)
201 {
202         char mount_flag[64] = { 0, };
203         static const char dir[][64] =
204         {
205                 { "/tmp/osp-compat" },
206                 { "/tmp/osp-compat/mount" },
207                 { "/tmp/osp-compat/mount/external" }
208         };
209
210         sprintf(mount_flag, "/tmp/osp-compat/mount/external/%s", pkgid);
211         int res = access(mount_flag, F_OK);
212         if (res == 0)
213         {
214                 LOGI("Extenal path is already mounted.");
215                 return 1;
216         }
217         else if (res == -1 && errno == ENOENT)
218         {
219                 int i = 0;
220                 for (i = 0; i < sizeof(dir)/64; ++i)
221                 {
222                         int res = mkdir(dir[i], 0755);
223                         if (res == -1 && errno != EEXIST)
224                         {
225                                 LOGE("Failed to create directory (%s), errno: %d (%s)", dir[i], errno, strerror(errno));
226                                 return 1;
227                         }
228                 }
229
230                 int fd = creat(mount_flag, 0644);
231                 if (fd == -1)
232                 {
233                         LOGE("Failed to create mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
234                         return 1;
235                 }
236                 close(fd);
237         }
238         else
239         {
240                 LOGE("Failed to access mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
241                 return 1;
242         }
243
244         LOGI("Extenal path mount succeeded.");
245         return 0;
246 }
247
248 static int
249 mount_slp_paths(const char* app_rootpath)
250 {
251     int i = 0;
252     static const struct _path_info mount_info[] = {
253         //{ "/bin",             "./bin" },
254         //{ "/boot",            "./boot" },
255         //{ "/cache",           "./cache" },
256         { "/csa",               "./csa" },
257         { "/dev",               "./dev" },
258         { "/dev/pts",           "./dev/pts" },
259         { "/dev/shm",           "./dev/shm" },
260         { "/etc",               "./etc" },
261         { "/lib",               "./lib" },
262         //{ "/lost+found",      "./lost+found" },
263         { "/media",             "./media" },
264         { "/mnt",               "./mnt" },
265         { "/opt",               "./opt" },
266         { "/opt/usr",           "./opt/usr" },
267         { "/opt/var/kdb/db",    "./opt/var/kdb/db" },
268         { "/opt/storage/sdcard","./opt/storage/sdcard" },
269         //{ "/packaging",       "./packaging" },
270         { "/proc",              "./proc" },
271         { "/sbin",              "./sbin" },
272         { "/srv",               "./srv" },
273         { "/sys",               "./sys" },
274         { "/sys/kernel/debug",  "./sys/kernel/debug" },
275         { "/tmp",               "./tmp" },
276         { "/usr",               "./usr" },
277         { "/var",               "./var" },
278         { "/var/run",           "./var/run" }
279     };
280
281     if (chdir(app_rootpath) != 0)
282     {
283         LOGE("chdir() failed path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
284         return -1;
285     }
286
287     for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i)
288     {
289         if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
290         {
291             LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
292                     mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
293
294             int j = 0;
295             for (j = i; j > 0; --j)
296             {
297                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
298             }
299             return -1;
300         }
301     }
302
303     return 0;
304 }
305
306 static int
307 mount_osp_internal_paths(const char* app_rootpath, const char* pkgid)
308 {
309     int i = 0;
310     char osp_share_pkgid_path[PATH_MAX] = {0, };
311     char osp_share2_pkgid_path[PATH_MAX] = {0, };
312     struct _path_info mount_info[] = {
313         { "\0",                    "./data/Share" },
314         { "\0",                    "./data/Share2" },
315         { "/opt/usr/share/.osp-compat/share",  "./Share" },
316         { "/opt/usr/share/.osp-compat/share2", "./Share2" },
317       //{ "/opt/osp/clipboard",    "./Clipboard" },
318       //{ "/opt/osp/partner/npki", "./NPKI" },
319       //{ "/opt/osp/system",       "./System" },
320       //{ "/opt/osp/Tmp",          "./Tmp" },
321         { "/opt/usr/media",        "./Media" }
322     };
323
324     strncpy(osp_share_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
325     strncat(osp_share_pkgid_path, "share/", 6);
326     strncat(osp_share_pkgid_path, pkgid, strlen(pkgid));
327
328     strncpy(osp_share2_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
329     strncat(osp_share2_pkgid_path, "share2/", 7);
330     strncat(osp_share2_pkgid_path, pkgid, strlen(pkgid));
331
332     strncpy(mount_info[0].src_path, osp_share_pkgid_path, strlen(osp_share_pkgid_path));
333     strncpy(mount_info[1].src_path, osp_share2_pkgid_path, strlen(osp_share2_pkgid_path));
334
335     if (chdir(app_rootpath) != 0)
336     {
337         LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
338         return -1;
339     }
340
341     for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i)
342     {
343         if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
344         {
345             LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
346                     mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
347
348             int j = 0;
349             for (j = i; j > 0; --j)
350             {
351                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
352             }
353             return -1;
354         }
355     }
356
357     return 0;
358 }
359
360 static int
361 link_osp_share_path(const char* app_rootpath, const char* pkgid)
362 {
363     char osp_app_share_path[PATH_MAX] = { 0, };
364     char osp_app_share2_path[PATH_MAX] = { 0, };
365     char osp_share_pkgid_path[PATH_MAX] = { 0, };
366     char osp_share2_pkgid_path[PATH_MAX] = { 0, };
367
368     strncpy(osp_app_share_path, app_rootpath, strlen(app_rootpath));
369     strncat(osp_app_share_path, "/shared/data", 12);
370
371     strncpy(osp_share_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
372     strncat(osp_share_pkgid_path, "share/", 6);
373     strncat(osp_share_pkgid_path, pkgid, strlen(pkgid));
374
375     strncpy(osp_app_share2_path, app_rootpath, strlen(app_rootpath));
376     strncat(osp_app_share2_path, "/shared/trusted", 15);
377
378     strncpy(osp_share2_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
379     strncat(osp_share2_pkgid_path, "share2/", 7);
380     strncat(osp_share2_pkgid_path, pkgid, strlen(pkgid));
381
382     unlink(osp_share_pkgid_path);
383     unlink(osp_share2_pkgid_path);
384
385     int ret = symlink(osp_app_share_path, osp_share_pkgid_path);
386     if (ret == -1 && errno != EEXIST)
387     {
388         LOGE("symlink() failed, src path: %s, dest path: %s, errno: %d (%s)",
389                 osp_app_share_path, osp_share_pkgid_path, errno, strerror(errno));
390         return -1;
391     }
392
393     ret = symlink(osp_app_share2_path, osp_share2_pkgid_path);
394     if (ret == -1 && errno != EEXIST)
395     {
396         LOGE("symlink() failed, src path: %s, dest path: %s, errno: %d (%s)",
397                 osp_app_share2_path, osp_share2_pkgid_path, errno, strerror(errno));
398         return -1;
399     }
400
401     return 0;
402 }
403
404 static int
405 create_osp_external_paths(const char* app_rootpath, const char* pkgid)
406 {
407     char osp_ext_apps_pkgid_path[PATH_MAX] = {0, };
408     char osp_ext_apps_pkgid_share_path[PATH_MAX] = {0, };
409     char osp_ext_apps_pkgid_share2_path[PATH_MAX] = {0, };
410     char osp_ext_share_pkgid_path[PATH_MAX] = {0, };
411     char osp_ext_share2_pkgid_path[PATH_MAX] = {0, };
412         struct _dir_info external_dirs[] = {
413         { "./HomeExt",           0000, 0},
414         { "./ShareExt",          0000, 0},
415         { "./Share2Ext",         0000, 0},
416         { "/opt/storage/sdcard/osp",            0777,   0 },
417         { "/opt/storage/sdcard/osp/apps",       0777,   0 },
418         { "/opt/storage/sdcard/osp/share",      0777,   0 },
419         { "/opt/storage/sdcard/osp/share2",     0777,   0 },
420         { "\0", 0777, 0},
421         { "\0", 0777, 0},
422         { "\0", 0777, 0},
423         { "\0", 0777, 0},
424         { "\0", 0777, 0},
425         { "/opt/storage/sdcard/Images", 0777,   0 },
426         { "/opt/storage/sdcard/Sounds", 0777,   0 },
427         { "/opt/storage/sdcard/Videos", 0777,   0 },
428       //{ "/opt/storage/sdcard/Themes", 0777,   0 },
429         { "/opt/storage/sdcard/Others", 0777,   0 }
430         };
431     int i = 0;
432
433     strncpy(osp_ext_apps_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
434     strncat(osp_ext_apps_pkgid_path, "apps/", 5);
435     strncat(osp_ext_apps_pkgid_path, pkgid, strlen(pkgid));
436
437     strncpy(osp_ext_apps_pkgid_share_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
438     strncat(osp_ext_apps_pkgid_share_path, "/Share", 6);
439
440     strncpy(osp_ext_apps_pkgid_share2_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
441     strncat(osp_ext_apps_pkgid_share2_path, "/Share2", 7);
442
443     strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
444     strncat(osp_ext_share_pkgid_path, "share/", 6);
445     strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid));
446
447     strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
448     strncat(osp_ext_share2_pkgid_path, "share2/", 7);
449     strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid));
450
451     strncpy(external_dirs[7].path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
452     strncpy(external_dirs[8].path, osp_ext_apps_pkgid_share_path, strlen(osp_ext_apps_pkgid_share_path));
453     strncpy(external_dirs[9].path, osp_ext_apps_pkgid_share2_path, strlen(osp_ext_apps_pkgid_share2_path));
454     strncpy(external_dirs[10].path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path));
455     strncpy(external_dirs[11].path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path));
456
457     if (chdir(app_rootpath) != 0)
458     {
459         LOGE("chdir() failed (%s), path: %s", strerror(errno), app_rootpath);
460         return -1;
461     }
462
463     for (i = 0; i < sizeof(external_dirs)/sizeof(struct _dir_info); i++)
464     {
465         int ret = mkdir(external_dirs[i].path, external_dirs[i].mode);
466         if (ret == -1 && errno != 17) // EEXIST
467         {
468             LOGE("mkdir() failed, path: %s, errno: %d (%s)", external_dirs[i].path, errno, strerror(errno));
469             return -1;
470         }
471     }
472
473     return 0;
474 }
475
476 static int
477 mount_osp_external_paths(const char* app_rootpath, const char* pkgid)
478 {
479     char osp_ext_apps_pkgid_path[PATH_MAX] = {0, };
480     char osp_ext_share_pkgid_path[PATH_MAX] = {0, };
481     char osp_ext_share2_pkgid_path[PATH_MAX] = {0, };
482     struct _path_info mount_info[] = {
483         { "/opt/storage/sdcard",  "./Storagecard/Media" },
484         { "/opt/storage/sdcard/osp/share",  "./ShareExt" },
485         { "/opt/storage/sdcard/osp/share2", "./Share2Ext" },
486         { "\0",  "./HomeExt" },
487         { "\0",  "./HomeExt/Share" },
488         { "\0",  "./HomeExt/Share2" },
489     };
490     int i = 0;
491
492     strncpy(osp_ext_apps_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
493     strncat(osp_ext_apps_pkgid_path, "apps/", 5);
494     strncat(osp_ext_apps_pkgid_path, pkgid, strlen(pkgid));
495
496     strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
497     strncat(osp_ext_share_pkgid_path, "share/", 6);
498     strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid));
499
500     strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
501     strncat(osp_ext_share2_pkgid_path, "share2/", 7);
502     strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid));
503
504     strncpy(mount_info[3].src_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
505     strncpy(mount_info[4].src_path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path));
506     strncpy(mount_info[5].src_path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path));
507
508     if (chdir(app_rootpath) != 0)
509     {
510         LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
511         return -1;
512     }
513     LOGI("app_rootpath: %s", app_rootpath);
514
515     for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); i++)
516     {
517         if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
518         {
519             LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
520                     mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
521
522             int j = 0;
523             for (j = i; j > 0; --j)
524             {
525                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
526             }
527             return -1;
528         }
529     }
530
531     return 0;
532 }
533
534 int
535 do_pre_exe(const char* package_name, const char* bin_path, const char* package_id)
536 {
537         char* app_rootpath = NULL;
538         char osp_app_data_path[PATH_MAX] = {0, };
539         //char internal_installed = 1; // true
540         int mmc_mounted = 0;
541     struct statfs fs;
542
543         /* e.g., app_rootdir is "/opt/apps/com.samsung.basicapp or /opt/osp/applications/[appId] */
544         app_rootpath = get_app_rootpath_from_path(bin_path);
545
546         LOGI("[data_caging] do_pre_exe() was called, package name: %s, \
547             binary path: %s, application root(home) path: %s, package id: %s",
548             package_name, bin_path, app_rootpath, package_id);
549
550         umask(0000);
551
552         // TODO: Check whether the application is installed in internal or external storage.
553         // Check installation position using the input path.
554     //if (internal_installed)
555     //{
556
557     if (!internal_is_mounted(package_id))
558     {
559         if (mount_slp_paths(app_rootpath) != 0)
560             goto ERROR;
561
562         if (mount_osp_internal_paths(app_rootpath, package_id) != 0)
563             goto ERROR;
564     }
565
566     int ret = 0;
567     ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_mounted);
568     if (ret < 0)
569     {
570         LOGE("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
571     }
572     if (mmc_mounted == 1)
573     {
574         LOGI("MMC is mounted.");
575         if (create_osp_external_paths(app_rootpath, package_id) != 0)
576         {
577             goto ERROR;
578         }
579
580         if (!external_is_mounted(package_id))
581         {
582             if (mount_osp_external_paths(app_rootpath, package_id) != 0)
583             {
584                 goto ERROR;
585             }
586         }
587     }
588     /*}
589         else
590         {
591             // TODO mount_external_paths(app_rootpath);
592         }*/
593         LOGI("mount() succeeded.");
594
595         if (chroot(app_rootpath) != 0)
596         {
597                 LOGE("chroot() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
598                 goto ERROR;
599         }
600     if (chdir("/") != 0)
601         {
602                 LOGE("chdir() failed, path: /, errno: %d (%s)", errno, strerror(errno));
603                 goto ERROR;
604         }
605         LOGI("chroot() succeeded.");
606
607         // set current working dir to "/opt/apps/{packageId}/data"
608 #if 0
609         strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath));
610         strncat(osp_app_data_path, "/data", strlen("/data"));
611 #endif
612
613         if (chdir("/data") != 0)
614         {
615                 LOGE("chdir() failed, path: /data, errno: %d (%s)", errno, strerror(errno));
616                 goto ERROR;
617         }
618
619         free(app_rootpath);
620     umask(0022);
621
622         LOGI("[data_caging] do_pre_exec() succeeded.");
623         return 0;
624
625 ERROR:
626     free(app_rootpath);
627     umask(0022);
628
629         LOGI("[data_caging] do_pre_exec() failed.");
630     return -1;
631 }
632
633 int
634 do_pre_exec(const char* package_name, const char* bin_path)
635 {
636         char* app_rootpath = NULL;
637     char app_compat_path[PATH_MAX] = { 0, };
638     const char app_compat_file[] = "/info/compat.info\0";
639     int pathlen = 0;
640     char package_id[_MAX_PACKAGEID_LENGTH + 1] = { 0, };
641     char osp_app_data_path[PATH_MAX] = { 0, };
642     int osp_compat = 0;
643
644     LOGI("do_pre_exec() is called, package_name: %s, bin_path: %s", package_name, bin_path);
645
646         app_rootpath = get_app_rootpath_from_path(bin_path);
647
648         strncpy(app_compat_path, app_rootpath, strlen(app_rootpath));
649         strncat(app_compat_path, app_compat_file, strlen(app_compat_file));
650     if (access(app_compat_path, F_OK) == 0)
651     {
652         osp_compat = 1;
653     }
654
655     // XXX: temp code
656     //if (package_name == NULL)
657     {
658         //LOGI("The package name is empty.");
659         get_package_id_from_app_rootpath(app_rootpath, package_id);
660     }
661 #if 0
662     else
663     {
664         get_package_id_from_package_name(package_name, package_id);
665     }
666 #endif
667     // XXX-end
668
669     LOGI("package name: %s, binary path: %s, package id: %s, OSP compatibility: %d",
670             package_name, bin_path, package_id, osp_compat);
671
672         // FIXME: Temporary code with security risk
673         prctl(PR_SET_KEEPCAPS, 1);
674
675     if (osp_compat == 1)
676     {
677                 free(app_rootpath);
678                 //unshare(CLONE_NEWNS);
679                 return do_pre_exe(package_name, bin_path, package_id);
680     }
681
682     // API version is equal to or greater than Tizen 2.0
683         // Set current working dir to "/opt/apps/{pkgId}/data"
684         strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath));
685         strncat(osp_app_data_path, "/data", strlen("/data"));
686
687         if (chdir(osp_app_data_path) != 0)
688         {
689                 LOGE("chdir() failed, path: %s, errno: %d (%s)", osp_app_data_path, errno, strerror(errno));
690                 goto ERROR;
691         }
692
693         if (link_osp_share_path(app_rootpath, package_id) != 0)
694         {
695                 goto ERROR;
696         }
697
698         LOGI("[data_caging] do_pre_exec() succeeded.");
699         free(app_rootpath);
700         return 0;
701
702 ERROR:
703         free(app_rootpath);
704         return -1;
705 }