add major version to so
[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 #include <fcntl.h>
34
35 #include <dlog.h>
36 #include <vconf.h>
37
38 #undef LOG_TAG
39 #define LOG_TAG "ENV_CONFIG"
40
41 #define _MAX_PACKAGEID_LENGTH 10
42 #define _MAX_APIVERSION_LENGTH 3
43
44 #ifdef _SECURE_LOG
45 #define _SECURE_LOGI LOGI
46 #define _SECURE_LOGE LOGE
47 #else
48 #define _SECURE_LOGI(...)
49 #define _SECURE_LOGE(...)
50 #endif
51
52 static const char* _OSP_COMPAT_SHARED_PATH = "/opt/usr/share/.osp-compat/\0";
53 static const char* _EXT_OSP_HOME_PATH = "/opt/storage/sdcard/osp/\0";
54
55 struct _path_info
56 {
57         char src_path[PATH_MAX];
58         char dest_path[PATH_MAX];
59 };
60
61 struct _dir_info
62 {
63         char path[PATH_MAX];
64         mode_t mode;
65         char app_privilege; // 0: root privilege
66 };
67
68 /*
69  * XXX: The returned app_roodir must be freed in caller.
70  */
71 static char*
72 get_app_rootpath_from_path(const char* bin_path)
73 {
74         char* app_rootpath = NULL;
75         char* delimiter = NULL;
76         size_t length = 0;
77         /* e.g., The specified bin_path is "/opt/apps/com.samsung.basicapp/bin/basicapp" */
78
79         length = strlen(bin_path);
80         app_rootpath = (char *)malloc(length + 1);
81         if(app_rootpath == NULL)
82                 return NULL;
83
84         memset(app_rootpath, '\0', length + 1);
85         strncpy(app_rootpath, bin_path, length);
86
87         _SECURE_LOGI("input bin_path: %s", app_rootpath);
88
89         delimiter = strrchr(app_rootpath, '/');
90         *delimiter = '\0';
91
92         delimiter  = strrchr(app_rootpath, '/');
93         *delimiter = '\0';
94
95         return app_rootpath;
96 }
97
98 static void
99 get_package_id_from_app_rootpath(const char* app_rootpath, char* package_id)
100 {
101         const char* p = NULL;
102         if (strncmp(app_rootpath, "/opt/apps/org.tizen.", 19) == 0)
103         {
104                 p = strrchr(app_rootpath, '.') + 1;
105         }
106         else
107         {
108                 p = strrchr(app_rootpath, '/') + 1;
109         }
110         strncpy(package_id, p, _MAX_PACKAGEID_LENGTH);
111         package_id[_MAX_PACKAGEID_LENGTH] = '\0';
112         _SECURE_LOGI("package id: %s", package_id);
113 }
114
115 #if 0
116 static void
117 get_package_id_from_package_name(const char* package_name, char* package_id)
118 {
119         char* tmpbuf = NULL;
120
121         if (strncmp(package_name, "com", 3) == 0)
122         {   // in case of com.samsung.#osp#[package_id]#[serviceid]
123                 tmpbuf = strstr(package_name, "#osp#");
124                 if (tmpbuf != NULL)
125                 {
126                         strncpy(package_id, tmpbuf + 5, _MAX_PACKAGEID_LENGTH);
127                 }
128         }
129         else if (strncmp(package_name, "osp", 3) == 0)
130         {   // in case of osp.[package_id].#osp#[serviceid]
131                 tmpbuf = strstr(package_name, "osp.");
132                 if (tmpbuf != NULL)
133                 {
134                         strncpy(package_id, tmpbuf + 4, _MAX_PACKAGEID_LENGTH);
135                 }
136         }
137         else if (strncmp(package_name, "org.tizen", 9) == 0)
138         {
139                 // in case of org.tizen.[package_id]#[serviceid]
140                 tmpbuf = strstr(package_name, "org.tizen.");
141                 if (tmpbuf != NULL)
142                 {
143                         strncpy(package_id, tmpbuf + 10, _MAX_PACKAGEID_LENGTH);
144                 }
145         }
146         else if (strlen(package_name) == 10)
147         {
148                 strncpy(package_id, package_name, _MAX_PACKAGEID_LENGTH);
149         }
150         else
151         {
152                 LOGE("package name is invalid (%s)", package_name);
153         }
154
155         package_id[_MAX_PACKAGEID_LENGTH] = '\0';
156         _SECURE_LOGI("package_id: %s", package_id);
157 }
158 #endif
159
160 static int
161 internal_is_mounted(const char* pkgid)
162 {
163         char mount_flag[64] = { 0, };
164         static const char dir[][64] =
165         {
166                 { "/tmp/osp-compat" },
167                 { "/tmp/osp-compat/mount" },
168                 { "/tmp/osp-compat/mount/internal" }
169         };
170
171         sprintf(mount_flag, "/tmp/osp-compat/mount/internal/%s", pkgid);
172         int res = access(mount_flag, F_OK);
173         if (res == 0)
174         {
175                 LOGI("Intenal path is already mounted.");
176                 return 1;
177         }
178         else if (res == -1 && errno == ENOENT)
179         {
180                 int i = 0;
181                 for (i = 0; i < sizeof(dir)/64; ++i)
182                 {
183                         int res = mkdir(dir[i], 0755);
184                         if (res == -1 && errno != EEXIST)
185                         {
186                                 LOGE("Failed to create directory (%s), errno: %d (%s)", dir[i], errno, strerror(errno));
187                                 return 1;
188                         }
189                 }
190
191                 int fd = creat(mount_flag, 0644);
192                 if (fd == -1)
193                 {
194                         LOGE("Failed to create mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
195                         return 1;
196                 }
197                 close(fd);
198         }
199         else
200         {
201                 LOGE("Failed to access mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
202                 return 1;
203         }
204
205         LOGI("Intenal path mount succeeded.");
206         return 0;
207 }
208
209 static int
210 external_is_mounted(const char* pkgid)
211 {
212         char mount_flag[64] = { 0, };
213         static const char dir[][64] =
214         {
215                 { "/tmp/osp-compat" },
216                 { "/tmp/osp-compat/mount" },
217                 { "/tmp/osp-compat/mount/external" }
218         };
219
220         sprintf(mount_flag, "/tmp/osp-compat/mount/external/%s", pkgid);
221         int res = access(mount_flag, F_OK);
222         if (res == 0)
223         {
224                 LOGI("Extenal path is already mounted.");
225                 return 1;
226         }
227         else if (res == -1 && errno == ENOENT)
228         {
229                 int i = 0;
230                 for (i = 0; i < sizeof(dir)/64; ++i)
231                 {
232                         int res = mkdir(dir[i], 0755);
233                         if (res == -1 && errno != EEXIST)
234                         {
235                                 LOGE("Failed to create directory (%s), errno: %d (%s)", dir[i], errno, strerror(errno));
236                                 return 1;
237                         }
238                 }
239
240                 int fd = creat(mount_flag, 0644);
241                 if (fd == -1)
242                 {
243                         LOGE("Failed to create mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
244                         return 1;
245                 }
246                 close(fd);
247         }
248         else
249         {
250                 LOGE("Failed to access mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno));
251                 return 1;
252         }
253
254         LOGI("Extenal path mount succeeded.");
255         return 0;
256 }
257
258 static int
259 mount_native_paths(const char* app_rootpath)
260 {
261         int i = 0;
262         static const struct _path_info mount_info[] =
263         {
264                 //{ "/bin",                             "./bin" },
265                 { "/csa",                               "./csa" },
266                 { "/dev",                               "./dev" },
267                 { "/dev/pts",                   "./dev/pts" },
268                 { "/dev/shm",                   "./dev/shm" },
269                 { "/etc",                               "./etc" },
270                 { "/lib",                               "./lib" },
271                 { "/mnt",                               "./mnt" },
272                 { "/proc",                              "./proc" },
273                 { "/sbin",                              "./sbin" },
274                 { "/smack",                             "./smack" },
275                 { "/srv",                               "./srv" },
276                 { "/sys",                               "./sys" },
277                 { "/sys/kernel/debug",  "./sys/kernel/debug" },
278                 { "/tmp",                               "./tmp" },
279                 { "/usr",                               "./usr" },
280                 { "/var",                               "./var" },
281                 { "/var/run",                   "./var/run" },
282                 { "/opt",                               "./opt" },
283                 { "/opt/usr",                   "./opt/usr" },
284                 { "/opt/var/kdb/db",    "./opt/var/kdb/db" },
285                 //{ "/opt/storage/sdcard","./opt/storage/sdcard" }
286         };
287
288         if (chdir(app_rootpath) != 0)
289         {
290                 LOGE("chdir() failed path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
291                 return -1;
292         }
293
294         for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i)
295         {
296                 if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
297                 {
298                         LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
299                                         mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
300
301                         int j = 0;
302                         for (j = i; j > 0; --j)
303                         {
304                                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
305                         }
306                         return -1;
307                 }
308         }
309
310         return 0;
311 }
312
313 static int
314 mount_osp_internal_paths(const char* app_rootpath, const char* pkgid)
315 {
316         int i = 0;
317         char osp_share_pkgid_path[PATH_MAX] = {0, };
318         char osp_share2_pkgid_path[PATH_MAX] = {0, };
319         struct _path_info mount_info[] =
320         {
321                 { "\0", "./data/Share" },
322                 { "\0", "./data/Share2" },
323                 { "/opt/usr/share/.osp-compat/share",   "./Share" },
324                 { "/opt/usr/share/.osp-compat/share2",  "./Share2" },
325                 { "/opt/usr/media",                     "./Media" }
326         };
327
328         strncpy(osp_share_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
329         strncat(osp_share_pkgid_path, "share/", 6);
330         strncat(osp_share_pkgid_path, pkgid, strlen(pkgid));
331
332         strncpy(osp_share2_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH));
333         strncat(osp_share2_pkgid_path, "share2/", 7);
334         strncat(osp_share2_pkgid_path, pkgid, strlen(pkgid));
335
336         strncpy(mount_info[0].src_path, osp_share_pkgid_path, strlen(osp_share_pkgid_path));
337         strncpy(mount_info[1].src_path, osp_share2_pkgid_path, strlen(osp_share2_pkgid_path));
338
339         if (chdir(app_rootpath) != 0)
340         {
341                 LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
342                 return -1;
343         }
344
345         for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i)
346         {
347                 if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
348                 {
349                         LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
350                                         mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
351
352                         int j = 0;
353                         for (j = i; j > 0; --j)
354                         {
355                                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
356                         }
357                         return -1;
358                 }
359         }
360
361         return 0;
362 }
363
364 static int
365 mount_linux_paths(const char* app_rootpath)
366 {
367         int i = 0;
368         static const struct _path_info mount_info[] =
369         {
370                 { "/bin",                               "./bin" },
371                 { "/cache",                             "./cache" },
372                 { "/csa",                               "./csa" },
373                 { "/data",                              "./data" },
374                 { "/dev",                               "./dev" },
375                 { "/dev/pts",                   "./dev/pts" },
376                 { "/dev/shm",                   "./dev/shm" },
377                 { "/etc",                               "./etc" },
378                 { "/lib",                               "./lib" },
379                 { "/lib/modules",               "./lib/modules" },
380                 { "/media",                             "./media" },
381                 { "/mnt",                               "./mnt" },
382                 { "/proc",                              "./proc" },
383                 { "/run",                               "./run" },
384                 { "/sbin",                              "./sbin" },
385                 { "/smack",                             "./smack" },
386                 { "/srv",                               "./srv" },
387                 { "/sys",                               "./sys" },
388                 { "/sys/fs/cgroup",             "./sys/fs/cgroup" },
389                 { "/sys/fs/cgroup/systemd",     "./sys/fs/cgroup/systemd" },
390                 { "/system",                    "./system" },
391                 { "/tmp",                               "./tmp" },
392                 { "/usr",                               "./usr" },
393                 { "/var",                               "./var" },
394                 { "/var/run",                   "./var/run" },
395                 { "/opt",                               "./opt" },
396                 { "/opt/usr",                   "./opt/usr" },
397                 //{ "/opt/var/run",             "./opt/var/run" },
398                 { "/opt/storage/sdcard","./opt/storage/sdcard" },
399         };
400
401         if (chdir(app_rootpath) != 0)
402         {
403                 LOGE("chdir() failed path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
404                 return -1;
405         }
406
407         for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i)
408         {
409                 if (i == 27) // /opt/storage/sdcard
410                 {
411                         int mmc_mounted = 0;
412                         int ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_mounted);
413                         if (ret < 0)
414                         {
415                                 LOGE("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
416                         }
417                         if (mmc_mounted == 0)
418                         {
419                                 continue;
420                         }
421                 }
422
423                 LOGI("src path: %s, dest path: %s", mount_info[i].src_path, mount_info[i].dest_path);
424                 if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
425                 {
426                         LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
427                                         mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
428
429                         int j = 0;
430                         for (j = i; j > 0; --j)
431                         {
432                                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
433                         }
434                         return -1;
435                 }
436         }
437
438         return 0;
439 }
440
441 static int
442 create_osp_external_paths(const char* app_rootpath, const char* pkgid)
443 {
444         char osp_ext_apps_pkgid_path[PATH_MAX] = {0, };
445         char osp_ext_apps_pkgid_share_path[PATH_MAX] = {0, };
446         char osp_ext_apps_pkgid_share2_path[PATH_MAX] = {0, };
447         char osp_ext_share_pkgid_path[PATH_MAX] = {0, };
448         char osp_ext_share2_pkgid_path[PATH_MAX] = {0, };
449         struct _dir_info external_dirs[] =
450         {
451                 { "./HomeExt",          0000,   0 },
452                 { "./ShareExt",         0000,   0 },
453                 { "./Share2Ext",        0000,   0 },
454                 { "/opt/storage/sdcard/osp",            0777,   0 },
455                 { "/opt/storage/sdcard/osp/apps",       0777,   0 },
456                 { "/opt/storage/sdcard/osp/share",      0777,   0 },
457                 { "/opt/storage/sdcard/osp/share2",     0777,   0 },
458                 { "\0", 0777,   0},
459                 { "\0", 0777,   0},
460                 { "\0", 0777,   0},
461                 { "\0", 0777,   0},
462                 { "\0", 0777,   0},
463                 { "/opt/storage/sdcard/Images", 0777,   0 },
464                 { "/opt/storage/sdcard/Sounds", 0777,   0 },
465                 { "/opt/storage/sdcard/Videos", 0777,   0 },
466                 { "/opt/storage/sdcard/Others", 0777,   0 }
467         };
468         int i = 0;
469
470         strncpy(osp_ext_apps_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
471         strncat(osp_ext_apps_pkgid_path, "apps/", 5);
472         strncat(osp_ext_apps_pkgid_path, pkgid, strlen(pkgid));
473
474         strncpy(osp_ext_apps_pkgid_share_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
475         strncat(osp_ext_apps_pkgid_share_path, "/Share", 6);
476
477         strncpy(osp_ext_apps_pkgid_share2_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
478         strncat(osp_ext_apps_pkgid_share2_path, "/Share2", 7);
479
480         strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
481         strncat(osp_ext_share_pkgid_path, "share/", 6);
482         strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid));
483
484         strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
485         strncat(osp_ext_share2_pkgid_path, "share2/", 7);
486         strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid));
487
488         strncpy(external_dirs[7].path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
489         strncpy(external_dirs[8].path, osp_ext_apps_pkgid_share_path, strlen(osp_ext_apps_pkgid_share_path));
490         strncpy(external_dirs[9].path, osp_ext_apps_pkgid_share2_path, strlen(osp_ext_apps_pkgid_share2_path));
491         strncpy(external_dirs[10].path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path));
492         strncpy(external_dirs[11].path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path));
493
494         if (chdir(app_rootpath) != 0)
495         {
496                 LOGE("chdir() failed (%s), path: %s", strerror(errno), app_rootpath);
497                 return -1;
498         }
499
500         for (i = 0; i < sizeof(external_dirs)/sizeof(struct _dir_info); i++)
501         {
502                 int ret = mkdir(external_dirs[i].path, external_dirs[i].mode);
503                 if (ret == -1 && errno != 17) // EEXIST
504                 {
505                         LOGE("mkdir() failed, path: %s, errno: %d (%s)", external_dirs[i].path, errno, strerror(errno));
506                         return -1;
507                 }
508         }
509
510         return 0;
511 }
512
513 static int
514 mount_osp_external_paths(const char* app_rootpath, const char* pkgid)
515 {
516         char osp_ext_apps_pkgid_path[PATH_MAX] = {0, };
517         char osp_ext_share_pkgid_path[PATH_MAX] = {0, };
518         char osp_ext_share2_pkgid_path[PATH_MAX] = {0, };
519         struct _path_info mount_info[] =
520         {
521                 { "/opt/storage/sdcard",                        "./Storagecard/Media"   },
522                 { "/opt/storage/sdcard/osp/share",      "./ShareExt"                    },
523                 { "/opt/storage/sdcard/osp/share2",     "./Share2Ext"                   },
524                 { "\0", "./HomeExt"                     },
525                 { "\0", "./HomeExt/Share"       },
526                 { "\0", "./HomeExt/Share2"      }
527         };
528         int i = 0;
529
530         strncpy(osp_ext_apps_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
531         strncat(osp_ext_apps_pkgid_path, "apps/", 5);
532         strncat(osp_ext_apps_pkgid_path, pkgid, strlen(pkgid));
533
534         strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
535         strncat(osp_ext_share_pkgid_path, "share/", 6);
536         strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid));
537
538         strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH));
539         strncat(osp_ext_share2_pkgid_path, "share2/", 7);
540         strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid));
541
542         strncpy(mount_info[3].src_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path));
543         strncpy(mount_info[4].src_path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path));
544         strncpy(mount_info[5].src_path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path));
545
546         if (chdir(app_rootpath) != 0)
547         {
548                 LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
549                 return -1;
550         }
551         LOGI("app_rootpath: %s", app_rootpath);
552
553         for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); i++)
554         {
555                 if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0)
556                 {
557                         LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)",
558                                         mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno));
559
560                         int j = 0;
561                         for (j = i; j > 0; --j)
562                         {
563                                 umount2(mount_info[j-1].dest_path, MNT_DETACH);
564                         }
565                         return -1;
566                 }
567         }
568
569         return 0;
570 }
571
572 int
573 do_pre_exe(const char* package_name, const char* bin_path, const char* package_id)
574 {
575         char* app_rootpath = NULL;
576         int mmc_mounted = 0;
577
578         /* e.g., app_rootdir is "/opt/usr/apps/[pkgId] */
579         app_rootpath = get_app_rootpath_from_path(bin_path);
580
581         _SECURE_LOGI("[data_caging] do_pre_exe() was called, package name: %s, package id: %s, binary: %s, app root: %s",
582                         package_name, package_id, bin_path, app_rootpath);
583
584         umask(0000);
585
586         if (!internal_is_mounted(package_id))
587         {
588                 if (mount_native_paths(app_rootpath) != 0)
589                 {
590                         goto ERROR;
591                 }
592                 if (mount_osp_internal_paths(app_rootpath, package_id) != 0)
593                 {
594                         goto ERROR;
595                 }
596         }
597
598         int ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_mounted);
599         if (ret < 0)
600         {
601                 LOGE("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
602         }
603         if (mmc_mounted == 1)
604         {
605                 LOGI("MMC is mounted.");
606                 if (create_osp_external_paths(app_rootpath, package_id) != 0)
607                 {
608                         goto ERROR;
609                 }
610
611                 if (!external_is_mounted(package_id))
612                 {
613                         if (mount_osp_external_paths(app_rootpath, package_id) != 0)
614                         {
615                                 goto ERROR;
616                         }
617                 }
618         }
619         LOGI("mount() succeeded.");
620
621         if (chroot(app_rootpath) != 0)
622         {
623                 LOGE("chroot() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno));
624                 goto ERROR;
625         }
626         if (chdir("/") != 0)
627         {
628                 LOGE("chdir() failed, path: /, errno: %d (%s)", errno, strerror(errno));
629                 goto ERROR;
630         }
631         LOGI("chroot() succeeded.");
632
633         if (chdir("/data") != 0)
634         {
635                 LOGE("chdir() failed, path: /data, errno: %d (%s)", errno, strerror(errno));
636                 goto ERROR;
637         }
638
639         free(app_rootpath);
640         umask(0022);
641
642         LOGI("[data_caging] do_pre_exec() succeeded.");
643         return 0;
644
645 ERROR:
646         free(app_rootpath);
647         umask(0022);
648
649         LOGI("[data_caging] do_pre_exec() failed.");
650         return -1;
651 }
652
653 static int
654 do_virtual_root(const char* virtual_root_path, const char* package_id)
655 {
656         _SECURE_LOGI("[virtual_root] do_virtual_root() was called, virtual root path: %s, package id: %s",
657                         virtual_root_path, package_id);
658
659         umask(0000);
660
661         if (!internal_is_mounted(package_id))
662         {
663                 if (mount_linux_paths(virtual_root_path) != 0)
664                 {
665                         goto ERROR;
666                 }
667         }
668         LOGI("mount() succeeded.");
669
670         if (chroot(virtual_root_path) != 0)
671         {
672                 LOGE("chroot() failed. path: %s, errno: %d (%s)", virtual_root_path, errno, strerror(errno));
673                 goto ERROR;
674         }
675         if (chdir("/") != 0)
676         {
677                 LOGE("chdir() failed. path: /data, errno: %d (%s)", errno, strerror(errno));
678                 goto ERROR;
679         }
680         LOGI("chroot() succeeded.");
681
682         umask(0022);
683
684         LOGI("[virtual_root] do_virtual_root() succeeded.");
685         return 0;
686
687 ERROR:
688         umask(0022);
689
690         LOGI("[virtual_root] do_virtual_root() failed.");
691         return -1;
692 }
693
694 int
695 do_pre_exec(const char* package_name, const char* bin_path)
696 {
697         char* app_rootpath = NULL;
698         char app_compat_path[PATH_MAX] = { 0, };
699         const char app_compat_file[] = "/info/compat.info\0";
700         char package_id[_MAX_PACKAGEID_LENGTH + 1] = { 0, };
701         char osp_app_data_path[PATH_MAX] = { 0, };
702         int osp_compat = 0;
703
704         _SECURE_LOGI("do_pre_exec() is called, package name: %s, binary path: %s", package_name, bin_path);
705
706         app_rootpath = get_app_rootpath_from_path(bin_path);
707
708         strncpy(app_compat_path, app_rootpath, strlen(app_rootpath));
709         strncat(app_compat_path, app_compat_file, strlen(app_compat_file));
710         if (access(app_compat_path, F_OK) == 0)
711         {
712                 osp_compat = 1;
713         }
714
715         // XXX: temp code
716         //if (package_name == NULL)
717         {
718                 //LOGI("The package name is empty.");
719                 get_package_id_from_app_rootpath(app_rootpath, package_id);
720         }
721 #if 0
722         else
723         {
724                 get_package_id_from_package_name(package_name, package_id);
725         }
726 #endif
727         // XXX-end
728
729         _SECURE_LOGI("package: %s (%s), binary: %s, OSP compat: %d", package_name, package_id, bin_path, osp_compat);
730
731         // FIXME: Temporary code with security risk
732         prctl(PR_SET_KEEPCAPS, 1);
733
734         if (osp_compat == 1)
735         {
736                 free(app_rootpath);
737                 //unshare(CLONE_NEWNS);
738                 return do_pre_exe(package_name, bin_path, package_id);
739         }
740
741         char virtual_root_file[PATH_MAX] = { 0, };
742         const char virtual_root_info[] = "/info/virtualroot.info";
743         strncpy(virtual_root_file, app_rootpath, strlen(app_rootpath));
744         strncat(virtual_root_file, virtual_root_info, strlen(virtual_root_info));
745         if (access(virtual_root_file, F_OK) == 0)
746         {
747                 LOGI("This is virtual root application.");
748                 int fd = open(virtual_root_file, O_RDONLY);
749                 if (fd < 0)
750                 {
751                         LOGE("failed to open %s, errno: %d (%s)", virtual_root_file, errno, strerror(errno));
752                         goto ERROR;
753                 }
754
755                 char user_path[PATH_MAX] = { 0, };
756                 int read_bytes = read(fd, user_path, PATH_MAX);
757                 if (read_bytes < 0)
758                 {
759                         LOGE("failed to read %s, errno: %d (%s)", virtual_root_file, errno, strerror(errno));
760                         close(fd);
761                         goto ERROR;
762                 }
763                 close(fd);
764
765                 char virtual_root_path[PATH_MAX] = { 0, };
766                 sprintf(virtual_root_path, "%s/data/%s", app_rootpath, user_path);
767
768                 int res = do_virtual_root(virtual_root_path, package_id);
769                 free(app_rootpath);
770                 return res;
771         }
772
773         // API version is equal to or greater than Tizen 2.0
774         // Set current working dir to "/opt/apps/{pkgId}/data"
775         strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath));
776         strncat(osp_app_data_path, "/data", strlen("/data"));
777
778         if (chdir(osp_app_data_path) != 0)
779         {
780                 LOGE("chdir() failed, path: %s, errno: %d (%s)", osp_app_data_path, errno, strerror(errno));
781                 goto ERROR;
782         }
783
784         LOGI("[data_caging] do_pre_exec() succeeded.");
785         free(app_rootpath);
786         return 0;
787
788 ERROR:
789         free(app_rootpath);
790         return -1;
791 }