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