4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
6 * Contact: Kidong Kim <kd0228.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
26 #include <sys/types.h>
38 #include <sys/smack.h>
39 #include <linux/capability.h>
40 #include <sys/capability.h>
46 #include "privilege-control.h"
47 #include "access-db.h"
52 #define DEVELOPER_GID 5100
53 #define DEVELOPER_UID 5100
55 #define APP_USER_NAME "app"
56 #define DEV_USER_NAME "developer"
58 #define APP_HOME_DIR TOSTRING(HOMEDIR) "/app"
59 #define DEV_HOME_DIR TOSTRING(HOMEDIR) "/developer"
61 #define APP_GROUP_PATH TOSTRING(SHAREDIR) "/app_group_list"
62 #define DEV_GROUP_PATH TOSTRING(SHAREDIR) "/dev_group_list"
64 #define SMACK_APP_LABEL_TEMPLATE "~APP~"
65 #define SMACK_SHARED_DIR_LABEL_TEMPLATE "~APP_SHARED_DIR~"
67 #define SMACK_SRC_FILE_SUFFIX "_src_file"
68 #define SMACK_SRC_DIR_SUFFIX "_src_dir"
69 #define SMACK_DATA_SUFFIX "_data"
70 #define WRT_BASE_DEVCAP "WRT"
71 #define WRT_CLIENT_PATH "/usr/bin/wrt-client"
73 #define TIZEN_PRIVILEGE_ANTIVIRUS "http://tizen.org/privilege/antivirus"
74 #define TIZEN_PRIVILEGE_APPSETTING "http://tizen.org/privilege/appsetting"
75 #define PATH_RULES_PUBLIC_RO "PATH_RULES_PUBLIC_RO.smack"
76 #define PATH_RULES_GROUP_RW "PATH_RULES_GROUP_RW.smack"
92 typedef int (*label_decision_fn)(const FTSENT*);
98 API int control_privilege(void)//deprecated
100 SECURE_C_LOGD("Entering function: %s.", __func__);
102 if(getuid() == APP_UID) // current user is 'app'
103 return PC_OPERATION_SUCCESS;
105 if(perm_app_set_privilege("org.tizen.", NULL, NULL) == PC_OPERATION_SUCCESS)
106 return PC_OPERATION_SUCCESS;
108 C_LOGE("perm_app_set_privilege failed (not permitted).");
109 return PC_ERR_NOT_PERMITTED;
114 * TODO: this function should be moved to libsmack in open-source.
116 API int get_smack_label_from_process(pid_t pid, char smack_label[SMACK_LABEL_LEN + 1])
118 SECURE_C_LOGD("Entering function: %s. Params: pid=%i", __func__, pid);
122 int PATH_MAX_LEN = 64;
123 char path[PATH_MAX_LEN + 1];
126 C_LOGE("invalid param pid.");
127 ret = PC_ERR_INVALID_PARAM;
131 if(smack_label == NULL) {
132 C_LOGE("Invalid param smack_label (NULL).");
133 ret = PC_ERR_INVALID_PARAM;
137 bzero(smack_label, SMACK_LABEL_LEN + 1);
138 if (!have_smack()) { // If no smack just return success with empty label
139 C_LOGD("No SMACK. Returning empty label");
140 ret = PC_OPERATION_SUCCESS;
144 bzero(path, PATH_MAX_LEN + 1);
145 snprintf(path, PATH_MAX_LEN, "/proc/%d/attr/current", pid);
146 fd = open(path, O_RDONLY);
148 SECURE_C_LOGE("Cannot open file %s (errno: %s)", path, strerror(errno));
149 ret = PC_ERR_FILE_OPERATION;
153 ret = read(fd, smack_label, SMACK_LABEL_LEN);
155 SECURE_C_LOGE("Cannot read from file %s", path);
156 ret = PC_ERR_FILE_OPERATION;
160 SECURE_C_LOGD("smack_label=%s", smack_label);
162 ret = PC_OPERATION_SUCCESS;
168 API int smack_pid_have_access(pid_t pid,
170 const char *access_type)
172 SECURE_C_LOGD("Entering function: %s. Params: pid=%i, object=%s, access_type=%s",
173 __func__, pid, object, access_type);
176 char pid_subject_label[SMACK_LABEL_LEN + 1];
178 cap_flag_value_t cap_v;
181 C_LOGD("No SMACK. Return access granted");
186 C_LOGE("Invalid pid.");
191 C_LOGE("Invalid object param.");
195 if(access_type == NULL) {
196 C_LOGE("Invalid access_type param");
200 //get SMACK label of process
201 ret = get_smack_label_from_process(pid, pid_subject_label);
202 if (PC_OPERATION_SUCCESS != ret) {
203 SECURE_C_LOGE("get_smack_label_from_process %d failed: %d", pid, ret);
206 SECURE_C_LOGD("pid %d has label: %s", pid, pid_subject_label);
208 // do not call smack_have_access() if label is empty
209 if (pid_subject_label[0] != '\0') {
210 ret = smack_have_access(pid_subject_label, object, access_type);
212 C_LOGE("smack_have_access failed.");
215 if ( 1 == ret ) { // smack_have_access return 1 (access granted)
216 C_LOGD("smack_have_access returned 1 (access granted)");
221 // smack_have_access returned 0 (access denied). Now CAP_MAC_OVERRIDE should be checked
222 C_LOGD("smack_have_access returned 0 (access denied)");
223 cap = cap_get_pid(pid);
225 C_LOGE("cap_get_pid failed");
228 ret = cap_get_flag(cap, CAP_MAC_OVERRIDE, CAP_EFFECTIVE, &cap_v);
230 C_LOGE("cap_get_flag failed");
234 if (cap_v == CAP_SET) {
235 C_LOGD("pid %d has CAP_MAC_OVERRIDE", pid);
239 C_LOGD("pid %d doesn't have CAP_MAC_OVERRIDE", pid);
244 static int set_dac(const char *smack_label, const char *pkg_name)
246 SECURE_C_LOGD("Entering function: %s. Params: smack_label=%s, pkg_name=%s",
247 __func__, smack_label, pkg_name);
249 FILE* fp_group = NULL; // /etc/group
250 uid_t t_uid = -1; // uid of current process
251 gid_t *glist = NULL; // group list
252 gid_t temp_gid = -1; // for group list
253 char buf[10] = {0, }; // contents in group_list file
254 int glist_cnt = 0; // for group list
258 unsigned *additional_gids = NULL;
261 * initialize user structure
263 C_LOGD("Initialize user structure");
264 memset(usr.user_name, 0x00, 10);
265 memset(usr.home_dir, 0x00, 64);
266 memset(usr.group_list, 0x00, 64);
271 C_LOGD("Current uid is %d", t_uid);
273 if(t_uid == 0) // current user is 'root'
275 if(!strncmp(pkg_name, "developer", 9))
277 strncpy(usr.user_name, DEV_USER_NAME, sizeof(usr.user_name));
278 usr.uid = DEVELOPER_UID;
279 usr.gid = DEVELOPER_GID;
280 strncpy(usr.home_dir, DEV_HOME_DIR, sizeof(usr.home_dir));
281 strncpy(usr.group_list, DEV_GROUP_PATH, sizeof(usr.group_list));
285 strncpy(usr.user_name, APP_USER_NAME, sizeof(usr.user_name));
288 strncpy(usr.home_dir, APP_HOME_DIR, sizeof(usr.home_dir));
289 strncpy(usr.group_list, APP_GROUP_PATH, sizeof(usr.group_list));
293 * get group information
295 C_LOGD("Get group information");
296 SECURE_C_LOGD("Opening file %s.", usr.group_list);
297 if(!(fp_group = fopen(usr.group_list, "r")))
299 C_LOGE("fopen failed.");
300 result = PC_ERR_FILE_OPERATION; // return -1
304 while(fgets(buf, 10, fp_group) != NULL)
307 temp_gid = strtoul(buf, 0, 10);
308 if(errno != 0) // error occured during strtoul()
310 C_LOGE("Cannot change string to integer: %s", buf);
311 result = PC_ERR_INVALID_OPERATION;
315 glist = (gid_t*)realloc(glist, sizeof(gid_t) * (glist_cnt + 1));
318 result = PC_ERR_MEM_OPERATION; // return -2
319 C_LOGE("Cannot allocate memory");
322 glist[glist_cnt] = temp_gid;
328 if(NULL != smack_label)
333 result = get_app_gids(smack_label, &additional_gids, &cnt);
334 if (result != PC_OPERATION_SUCCESS)
338 glist_new = (gid_t*)realloc(glist, sizeof(gid_t) * (glist_cnt + cnt));
339 if (glist_new == NULL) {
340 result = PC_ERR_MEM_OPERATION; // return -2
341 C_LOGE("Memory allocation failed");
345 for (i = 0; i < cnt; ++i) {
346 C_LOGD("Additional GID based on enabled permissions: %u", additional_gids[i]);
347 glist[glist_cnt++] = additional_gids[i];
355 C_LOGD("Adding process to the following groups:");
356 for(i=0; i<glist_cnt; ++i) {
357 SECURE_C_LOGD("glist [ %d ] = %d", i, glist[i]);
359 C_LOGD("Calling setgroups()");
360 if(setgroups(glist_cnt, glist) != 0)
362 C_LOGE("setgroups failed");
363 result = PC_ERR_NOT_PERMITTED; // return -3
373 * setuid() & setgid()
375 C_LOGD("setgid( %d ) & setuid( %d )", usr.gid, usr.uid);
376 if(setgid(usr.gid) != 0) // fail
378 C_LOGE("Failed to execute setgid().");
379 result = PC_ERR_INVALID_OPERATION;
382 if(setuid(usr.uid) != 0) // fail
384 C_LOGE("Failed to execute setuid().");
385 result = PC_ERR_INVALID_OPERATION;
389 SECURE_C_LOGD("setenv(): USER = %s, HOME = %s", usr.user_name, usr.home_dir);
390 if(setenv("USER", usr.user_name, 1) != 0) //fail
392 C_LOGE("Failed to execute setenv() [USER].");
393 result = PC_ERR_INVALID_OPERATION;
396 if(setenv("HOME", usr.home_dir, 1) != 0) // fail
398 C_LOGE("Failed to execute setenv() [HOME].");
399 result = PC_ERR_INVALID_OPERATION;
403 else // current user is not only 'root' but 'app'
405 C_LOGE("Current user is NOT root");
406 result = PC_ERR_NOT_PERMITTED; // return -3
410 result = PC_OPERATION_SUCCESS;
417 free(additional_gids);
423 * Get SMACK label from EXEC label of a file.
424 * SMACK label should be freed by caller
426 * @param path file path to take label from
427 * @return PC_OPERATION_SUCCESS on success, PC_ERR_* on error
429 static int get_smack_from_binary(char **smack_label, const char* path, app_type_t type)
431 SECURE_C_LOGD("Entering function: %s. Params: path=%s, type=%d",
432 __func__, path, type);
436 if (type == APP_TYPE_WGT
437 || type == APP_TYPE_WGT_PARTNER
438 || type == APP_TYPE_WGT_PLATFORM) {
439 ret = smack_lgetlabel(path, smack_label, SMACK_LABEL_EXEC);
441 ret = smack_getlabel(path, smack_label, SMACK_LABEL_EXEC);
444 C_LOGE("Getting exec label from file %s failed", path);
445 return PC_ERR_INVALID_OPERATION;
448 return PC_OPERATION_SUCCESS;
452 * Set process SMACK label.
453 * This function is emulating EXEC label behavior of SMACK for programs
454 * run by dlopen/dlsym instead of execv.
457 * @return PC_OPERATION_SUCCESS on success, PC_ERR_* on error
459 static int set_smack_for_self (char *smack_label)
461 SECURE_C_LOGD("Entering function: %s. Params: smack_label=%s",
462 __func__, smack_label);
465 if (smack_label == NULL) {
466 /* No label to set, just return with success */
467 C_LOGD("No label to set, just return with success.");
468 ret = PC_OPERATION_SUCCESS;
471 SECURE_C_LOGD("smack_label=%s", smack_label);
473 ret = smack_set_label_for_self(smack_label);
474 C_LOGD("smack_set_label_for_self returned %d", ret);
476 ret = PC_OPERATION_SUCCESS;
482 static int is_widget(const char* path)
484 SECURE_C_LOGD("Entering function: %s. Params: path=%s",
486 char buf[sizeof(WRT_CLIENT_PATH)];
489 ret = readlink(path, buf, sizeof(WRT_CLIENT_PATH));
491 C_LOGD("readlink(%s) returned error: %s. Assuming that app is not a widget", path, strerror(errno));
492 else if (ret == sizeof(WRT_CLIENT_PATH))
493 C_LOGD("%s is not a widget", path);
494 if (ret == -1 || ret == sizeof(WRT_CLIENT_PATH))
497 C_LOGD("buf=%s", buf);
499 ret = !strcmp(WRT_CLIENT_PATH, buf);
500 C_LOGD("%s is %s widget", path, ret ? "a" : "not a");
505 * Partially verify, that the type given for app is correct.
506 * This function will use some heuristics to check whether the app type is right.
507 * It is intended for security hardening to catch privilege setting for the
508 * app type not corresponding to the actual binary.
509 * Beware - when it detects an anomaly, the whole process will be terminated.
511 * @param type claimed application type
512 * @param path file path to executable
513 * @return return void on success, terminate the process on error
515 static app_type_t verify_app_type(const char* type, const char* path)
517 SECURE_C_LOGD("Entering function: %s. Params: type=%s, path=%s",
518 __func__, type, path);
520 /* TODO: this should actually be treated as error, but until the old
521 * set_privilege API is removed, it must be ignored */
523 C_LOGD("PKG_TYPE_OTHER");
524 return APP_TYPE_OTHER; /* good */
527 if (is_widget(path)) {
528 if (!strcmp(type, "wgt")) {
529 C_LOGD("PKG_TYPE_WGT");
530 return APP_TYPE_WGT; /* good */
531 } else if (!strcmp(type, "wgt_partner")) {
532 C_LOGD("PKG_TYPE_WGT_PARTNER");
533 return APP_TYPE_WGT_PARTNER; /* good */
534 } else if (!strcmp(type, "wgt_platform")) {
535 C_LOGD("PKG_TYPE_WGT_PLATFORM");
536 return APP_TYPE_WGT_PLATFORM; /* good */
540 if (type == NULL || (strcmp(type, "wgt")
541 && strcmp(type, "wgt_partner")
542 && strcmp(type, "wgt_platform"))){
543 C_LOGD("PKG_TYPE_OTHER");
544 return APP_TYPE_OTHER; /* good */
549 C_LOGE("EXIT_FAILURE");
553 API int set_app_privilege(const char* name, const char* type, const char* path)//deprecated
555 SECURE_C_LOGD("Entering function: %s. Params: name=%s, type=%s, path=%s",
556 __func__, name, type, path);
558 return perm_app_set_privilege(name, type, path);
561 API int perm_app_set_privilege(const char* name, const char* type, const char* path)
563 SECURE_C_LOGD("Entering function: %s. Params: name=%s, type=%s, path=%s",
564 __func__, name, type, path);
566 //SECURE_C_LOGD("Function params: name = %s, type = %s, path = %s", name, type, path);
567 int ret = PC_OPERATION_SUCCESS;
568 int were_rules_loaded = 0;
569 char *smack_label AUTO_FREE;
572 C_LOGE("Error invalid parameter");
573 return PC_ERR_INVALID_PARAM;
576 if (path != NULL && have_smack()) {
577 ret = get_smack_from_binary(&smack_label, path, verify_app_type(type, path));
578 if (ret != PC_OPERATION_SUCCESS)
581 were_rules_loaded = check_if_rules_were_loaded(smack_label);
582 if (were_rules_loaded < 0) {
583 C_LOGE("check_if_rules_was_loaded failed.");
584 return PC_ERR_INVALID_OPERATION;
586 if (!were_rules_loaded) { // first run of application
587 C_LOGD("This is first run of this application. Adding SMACK rules.");
588 ret = add_app_first_run_rules(smack_label);
589 if (ret != PC_OPERATION_SUCCESS ) {
590 C_LOGW("add_app_first_run_rules failed");
591 // should we return here with error code?
593 mark_rules_as_loaded(smack_label);
596 ret = set_smack_for_self(smack_label);
597 if (ret != PC_OPERATION_SUCCESS)
601 if (path != NULL && !have_smack()) {
602 ret = get_smack_from_binary(&smack_label, path, verify_app_type(type, path));
603 if (ret != PC_OPERATION_SUCCESS)
607 return set_dac(smack_label, name);
610 API int set_privilege(const char* pkg_name)//deprecated
612 SECURE_C_LOGD("Entering function: %s. Params: pkg_name=%s",
615 return perm_app_set_privilege(pkg_name, NULL, NULL);
618 static inline const char* app_type_name(app_type_t app_type)
620 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d",
625 C_LOGD("App type = APP_TYPE_WGT");
628 C_LOGD("App type = APP_TYPE_OSP");
630 case APP_TYPE_WGT_PARTNER:
631 C_LOGD("App type = APP_TYPE_WGT_PARTNER");
632 return "WRT_partner";
633 case APP_TYPE_WGT_PLATFORM:
634 C_LOGD("App type = APP_TYPE_WGT_PLATFORM");
635 return "WRT_platform";
636 case APP_TYPE_OSP_PARTNER:
637 C_LOGD("App type = APP_TYPE_OSP_PARTNER");
638 return "OSP_partner";
639 case APP_TYPE_OSP_PLATFORM:
640 C_LOGD("App type = APP_TYPE_OSP_PLATFORM");
641 return "OSP_platform";
645 C_LOGD("App type = other");
650 static inline const char* app_type_group_name(app_type_t app_type)
652 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d",
657 case APP_TYPE_WGT_PARTNER:
658 case APP_TYPE_WGT_PLATFORM:
659 C_LOGD("App type group name = WRT");
662 case APP_TYPE_OSP_PARTNER:
663 case APP_TYPE_OSP_PLATFORM:
664 C_LOGD("App type group name = OST");
674 * This function changes permission URI to basename for file name.
675 * For e.g. from http://tizen.org/privilege/contact.read will be
676 * created basename : org.tizen.privilege.contact.read
679 static int base_name_from_perm(const char *perm, char **name)
681 SECURE_C_LOGD("Entering function: %s. Params: perm=%s",
685 char *host_dot = NULL;
686 char *rest_slash = NULL;
689 ip = iri_parse(perm);
690 if (ip == NULL || ip->host == NULL) {
691 SECURE_C_LOGE("Bad permission format : %s", perm);
693 return PC_ERR_INVALID_PARAM;
696 if (ip->path == NULL) {
702 host_dot = strrchr(ip->host, '.');
709 while ((rest_slash = strchr(ip->path, '/'))) {
713 ret = asprintf(name, "%s%s%s%s",
714 host_dot ? host_dot : "", host_dot ? "." : "",
715 ip->host ? ip->host : "", ip->path);
717 C_LOGE("asprintf failed");
719 return PC_ERR_MEM_OPERATION;
723 return PC_OPERATION_SUCCESS;
726 static int perm_file_path(char** path, app_type_t app_type, const char* perm, const char *suffix, bool is_early)
728 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, perm=%s, suffix=%s, is_early=%d",
729 __func__, app_type, perm, suffix, is_early);
731 const char* app_type_prefix = NULL;
732 char* perm_basename = NULL;
735 if (perm == NULL || strlen(perm) == 0) {
736 C_LOGE("Empty permission name.");
737 return PC_ERR_INVALID_PARAM;
740 app_type_prefix = app_type_group_name(app_type);
742 ret = base_name_from_perm(perm, &perm_basename);
743 if (ret != PC_OPERATION_SUCCESS) {
744 C_LOGE("Couldn't get permission basename.");
749 ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s%s",
750 app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
751 perm_basename, "_early", suffix);
754 ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s",
755 app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
756 perm_basename, suffix);
759 C_LOGE("asprintf failed.");
760 return PC_ERR_MEM_OPERATION;
763 C_LOGD("Path=%s", *path);
765 return PC_OPERATION_SUCCESS;
768 static int perm_to_smack_from_file(struct smack_accesses* smack,
769 const char* app_label,
770 const char* app_label_template,
771 const char* rules_file_path)
773 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_label_template=%s, rules_file_path=%s",
774 __func__, app_label, app_label_template, rules_file_path);
776 char smack_subject[SMACK_LABEL_LEN + 1];
777 char smack_object[SMACK_LABEL_LEN + 1];
778 char smack_accesses[ACC_LEN + 1];
779 FILE* file AUTO_FCLOSE;
781 SECURE_C_LOGD("Opening file %s.", rules_file_path);
782 file = fopen(rules_file_path, "r");
784 SECURE_C_LOGW("fopen failed [%s] %s", rules_file_path, strerror(errno));
785 return PC_OPERATION_SUCCESS;
789 "%" TOSTRING(SMACK_LABEL_LEN) "s "
790 "%" TOSTRING(SMACK_LABEL_LEN) "s "
791 "%" TOSTRING(ACC_LEN) "s\n",
792 smack_subject, smack_object, smack_accesses) == 3) {
793 if (!strcmp(smack_subject, app_label_template))
794 strcpy(smack_subject, app_label);
796 if (!strcmp(smack_object, app_label_template))
797 strcpy(smack_object, app_label);
799 C_LOGD("smack_accesses_add_modify (subject: %s, object: %s, access: %s)", smack_subject, smack_object, smack_accesses);
800 if (smack_accesses_add_modify(smack, smack_subject, smack_object, smack_accesses, "") != 0) {
801 C_LOGE("smack_accesses_add_modify failed.");
802 return PC_ERR_INVALID_OPERATION;
806 return PC_OPERATION_SUCCESS;
809 static int perm_to_smack_generic(struct smack_accesses* smack, const char* app_label, app_type_t app_type, const char* perm, bool is_early)
811 C_LOGD("Enter function: %s", __func__);
814 char* path AUTO_FREE;
816 // get file name for permission (devcap)
817 ret = perm_file_path(&path, app_type, perm, ".smack", is_early);
818 if (ret != PC_OPERATION_SUCCESS) {
819 C_LOGD("No smack config file for permission %s", perm);
823 ret = perm_to_smack_from_file(smack, app_label, SMACK_APP_LABEL_TEMPLATE, path);
824 if (ret != PC_OPERATION_SUCCESS) {
828 return PC_OPERATION_SUCCESS;
831 static int perm_to_smack_early(struct smack_accesses* smack, const char* app_label, app_type_t app_type, const char* perm)
833 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_type=%d, perm=%s",
834 __func__, app_label, app_type, perm);
836 return perm_to_smack_generic(smack, app_label, app_type, perm, 1);
839 static int perm_to_smack(struct smack_accesses* smack, const char* app_label, app_type_t app_type, const char* perm)
841 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_type=%d, perm=%s",
842 __func__, app_label, app_type, perm);
844 return perm_to_smack_generic(smack, app_label, app_type, perm, 0);
847 static int perm_to_dac(const char* app_label, app_type_t app_type, const char* perm)
849 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_type=%d, perm=%s",
850 __func__, app_label, app_type, perm);
853 char* path AUTO_FREE;
854 FILE* file AUTO_FCLOSE;
857 ret = perm_file_path(&path, app_type, perm, ".dac", 0);
858 if (ret != PC_OPERATION_SUCCESS) {
859 C_LOGD("No dac config file for permission %s", perm);
863 SECURE_C_LOGD("Opening file %s.", path);
864 file = fopen(path, "r");
866 C_LOGW("fopen failed.");
867 return PC_OPERATION_SUCCESS;
870 while (fscanf(file, "%d\n", &gid) == 1) {
871 SECURE_C_LOGD("Adding app_id %s to group %d", app_label, gid);
872 ret = add_app_gid(app_label, gid);
873 if (ret != PC_OPERATION_SUCCESS) {
874 C_LOGE("add_app_gid failed");
879 return PC_OPERATION_SUCCESS;
882 static int label_all(const FTSENT* ftsent)
884 SECURE_C_LOGD("Entering function: %s.", __func__);
886 return DECISION_LABEL;
889 static int label_execs(const FTSENT* ftsent)
891 SECURE_C_LOGD("Entering function: %s.", __func__);
893 C_LOGD("Mode = %d", ftsent->fts_statp->st_mode);
894 // label only regular executable files
895 if (S_ISREG(ftsent->fts_statp->st_mode) && (ftsent->fts_statp->st_mode & S_IXUSR))
896 return DECISION_LABEL;
897 return DECISION_SKIP;
900 static int label_dirs(const FTSENT* ftsent)
902 SECURE_C_LOGD("Entering function: %s.", __func__);
904 // label only directories
905 if (S_ISDIR(ftsent->fts_statp->st_mode))
906 return DECISION_LABEL;
907 return DECISION_SKIP;
910 static int label_links_to_execs(const FTSENT* ftsent)
912 SECURE_C_LOGD("Entering function: %s.", __func__);
915 char* target AUTO_FREE;
917 // check if it's a link
918 if ( !S_ISLNK(ftsent->fts_statp->st_mode))
919 return DECISION_SKIP;
921 target = realpath(ftsent->fts_path, NULL);
923 SECURE_C_LOGE("Getting link target for %s failed (Error = %s)", ftsent->fts_path, strerror(errno));
924 return PC_ERR_FILE_OPERATION;
926 if (-1 == stat(target, &buf)) {
927 SECURE_C_LOGE("stat failed for %s (Error = %s", target, strerror(errno));
928 return PC_ERR_FILE_OPERATION;
930 // skip if link target is not a regular executable file
931 if (buf.st_mode != (buf.st_mode | S_IXUSR | S_IFREG)) {
932 SECURE_C_LOGD("%s is not a regular executable file. Skipping.", target);
933 return DECISION_SKIP;
936 return DECISION_LABEL;
939 static int dir_set_smack_r(const char *path, const char* label,
940 enum smack_label_type type, label_decision_fn fn)
942 SECURE_C_LOGD("Entering function: %s. Params: path=%s, label=%s, type=%d",
943 __func__, path, label, type);
945 const char* path_argv[] = {path, NULL};
946 FTS *fts AUTO_FTS_CLOSE;
950 fts = fts_open((char * const *) path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
952 C_LOGE("fts_open failed.");
953 return PC_ERR_FILE_OPERATION;
956 while ((ftsent = fts_read(fts)) != NULL) {
957 /* Check for error (FTS_ERR) or failed stat(2) (FTS_NS) */
958 if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
959 C_LOGE("FTS_ERR error or failed stat(2) (FTS_NS)");
960 return PC_ERR_FILE_OPERATION;
965 C_LOGE("fn(ftsent) failed.");
969 if (ret == DECISION_LABEL) {
970 C_LOGD("smack_lsetlabel (label: %s (type: %d), path: %s)", label, type, ftsent->fts_path);
971 if (smack_lsetlabel(ftsent->fts_path, label, type) != 0) {
972 C_LOGE("smack_lsetlabel failed.");
973 return PC_ERR_FILE_OPERATION;
978 /* If last call to fts_read() set errno, we need to return error. */
980 C_LOGE("Last errno from fts_read: %s", strerror(errno));
981 return PC_ERR_FILE_OPERATION;
983 return PC_OPERATION_SUCCESS;
986 API char* app_id_from_socket(int sockfd)//deprecated
988 SECURE_C_LOGD("Entering function: %s. Params: sockfd=%d",
991 return perm_app_id_from_socket(sockfd);
994 API char* perm_app_id_from_socket(int sockfd)
996 SECURE_C_LOGD("Entering function: %s. Params: sockfd=%d",
1000 C_LOGD("No SMACK. Returning NULL.");
1007 ret = smack_new_label_from_socket(sockfd, &app_id);
1009 C_LOGE("smack_new_label_from_socket failed");
1013 SECURE_C_LOGD("app_id = %s", app_id);
1018 static int app_add_rule(const char *app_id, const char *object, const char *perm)
1020 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, object=%s, perm=%s",
1021 __func__, app_id, object, perm);
1025 char *smack_path AUTO_FREE;
1026 struct smack_accesses* smack AUTO_SMACK_FREE;
1028 ret = load_smack_from_file(app_id, &smack, &fd, &smack_path);
1029 if (ret != PC_OPERATION_SUCCESS) {
1030 C_LOGE("load_smack_from_file failed.");
1034 ret = smack_accesses_add_modify(smack, app_id, object, perm, "");
1036 C_LOGE("smack_accesses_add_modify failed.");
1037 return PC_ERR_INVALID_OPERATION;
1040 if (have_smack() && smack_accesses_apply(smack)) {
1041 C_LOGE("smack_accesses_apply failed.");
1042 return PC_ERR_INVALID_OPERATION;
1045 if (smack_accesses_save(smack, fd)) {
1046 C_LOGE("smack_accesses_save failed.");
1047 return PC_ERR_INVALID_OPERATION;
1050 return PC_OPERATION_SUCCESS;
1055 app_register_appsetting(const char *app_id, struct smack_accesses *smack)
1057 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1063 char **label_app_list AUTO_FREE;
1064 char **label_dir_list AUTO_FREE;
1065 int app_list_len = 0;
1066 int dir_list_len = 0;
1068 if (!smack_label_is_valid(app_id)) {
1069 C_LOGE("Invalid param app_id.");
1070 return PC_ERR_INVALID_PARAM;
1073 /* writing appsetting_id (app_id) to "database"*/
1074 ret = add_appsetting_id_to_databse(app_id);
1075 if (ret != PC_OPERATION_SUCCESS)
1079 /* Reading labels of all installed apps from "database"*/
1080 ret = get_all_apps_ids(&label_app_list, &app_list_len);
1081 if (ret != PC_OPERATION_SUCCESS) {
1082 C_LOGE("Error while getting data from database");
1086 /*Add smack rules with rx access to each app*/
1087 for (i = 0; i < app_list_len; ++i) {
1088 C_LOGD("Appsetting: applying rx rule for %s", label_app_list[i]);
1089 if (smack_accesses_add_modify(smack, app_id,
1090 label_app_list[i], "rx", "") == -1) {
1091 C_LOGE("smack_accesses_add_modify failed.");
1092 ret = PC_ERR_INVALID_OPERATION;
1097 /* Reading labels of all registered settings dirs from "database"*/
1098 ret = get_all_settings_dir_ids(
1099 &label_dir_list, &dir_list_len);
1100 if (ret != PC_OPERATION_SUCCESS) {
1101 C_LOGE("Error while getting data from database");
1104 /*Add smack rules with rwx access to each app*/
1105 for (i = 0; i < dir_list_len; ++i) {
1106 C_LOGD("Appsetting: applying rwx rule for %s", label_dir_list[i]);
1107 if (smack_accesses_add_modify(smack, app_id,
1108 label_dir_list[i], "rwx", "") == -1) {
1109 C_LOGE("smack_accesses_add_modify failed.");
1110 ret = PC_ERR_INVALID_OPERATION;
1112 /* Should we abort adding rules if
1113 * smack_accesses_add_modify fails once?*/
1118 for (i = 0; i < app_list_len; ++i) {
1119 free(label_app_list[i]);
1121 for (i = 0; i < dir_list_len; ++i) {
1122 free(label_dir_list[i]);
1128 static int app_register_av_internal(const char *app_av_id, struct smack_accesses* smack)
1130 SECURE_C_LOGD("Entering function: %s. Params: app_av_id=%s.",
1131 __func__, app_av_id);
1136 char** smack_label_app_list AUTO_FREE;
1137 int smack_label_app_list_len = 0;
1139 if (!smack_label_is_valid(app_av_id)) {
1140 C_LOGE("Invalid param app_av_id.");
1141 return PC_ERR_INVALID_PARAM;
1145 C_LOGE("Invalid param smack (NULL).");
1146 return PC_ERR_INVALID_PARAM;
1149 // writing anti_virus_id (app_av_id) to "database"
1150 ret = add_av_id_to_databse(app_av_id);
1151 if (ret != PC_OPERATION_SUCCESS )
1154 // Reading labels of all installed apps from "database"
1155 ret = get_all_apps_ids(&smack_label_app_list, &smack_label_app_list_len);
1156 if (ret != PC_OPERATION_SUCCESS ) {
1157 C_LOGE("Error while geting data from database.");
1160 for (i = 0; i < smack_label_app_list_len; ++i) {
1161 SECURE_C_LOGD("Applying rwx rule for %s", smack_label_app_list[i]);
1162 if (smack_accesses_add_modify(smack, app_av_id, smack_label_app_list[i], "wrx", "") == -1) {
1163 C_LOGE("smack_accesses_add_modify failed.");
1164 ret = PC_ERR_INVALID_OPERATION;
1166 // Should we abort adding rules once smack_accesses_add_modify will fail?
1171 for (i = 0; i < smack_label_app_list_len; ++i) {
1172 free(smack_label_app_list[i]);
1179 * This function will find labels of all anti viruses in database
1180 * and for all of them will add a rule "anti_virus_label app_id rwx".
1181 * This should be called in app_install function.
1183 static int register_app_for_av(const char * app_id)
1185 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s.",
1189 char** smack_label_av_list AUTO_FREE;
1190 int smack_label_av_list_len = 0;
1192 // Reading labels of all installed anti viruses from "database"
1193 ret = get_all_avs_ids(&smack_label_av_list, &smack_label_av_list_len);
1194 if (ret != PC_OPERATION_SUCCESS) {
1195 C_LOGE("Error while geting data from database.");
1199 // for each anti-virus label put rule: "anti_virus_label app_id rwx"
1200 for (i = 0; i < smack_label_av_list_len; ++i) {
1201 SECURE_C_LOGD("Antivirus: app_add_rule (%s, %s rx)", smack_label_av_list[i], app_id);
1202 if (strcmp(app_id, smack_label_av_list[i])==0) {
1203 SECURE_C_LOGW("Trying to add antivirus rule for self. Skipping");
1206 ret = app_add_rule(smack_label_av_list[i], app_id, "wrx");
1207 if (ret != PC_OPERATION_SUCCESS) {
1208 C_LOGE("app_add_rule failed.");
1212 free(smack_label_av_list[i]);
1215 ret = PC_OPERATION_SUCCESS;
1218 // If something failed, then no entry of smack_label_av_list[i]
1219 // was deallocated. They all must be freed.
1220 for(; i<smack_label_av_list_len; ++i) {
1221 free(smack_label_av_list[i]);
1228 * This function will find labels of all setting applications in database
1229 * and for all of them will add a rule "appsetting_id app_id rwx".
1230 * This should be called in app_install function.
1232 static int register_app_for_appsetting(const char *app_id)
1234 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1238 char **smack_label_list AUTO_FREE;
1239 int smack_label_list_len = 0;
1241 /* Reading labels of all installed setting managers from "database"*/
1242 ret = get_all_appsetting_ids(&smack_label_list, &smack_label_list_len);
1243 if (ret != PC_OPERATION_SUCCESS) {
1244 C_LOGE("Error while geting data from database.");
1248 /* for each appsetting put rule: "appsetting_id app_id rx"*/
1249 for (i = 0; i < smack_label_list_len; ++i) {
1251 SECURE_C_LOGD("Appsetting: app_add_rule (%s, %s rx)", smack_label_list[i], app_id);
1252 if (strcmp(app_id, smack_label_list[i])==0) {
1253 SECURE_C_LOGW("Trying to add setting rule for self. Skipping");
1256 ret = app_add_rule(smack_label_list[i], app_id, "rx");
1257 if (ret != PC_OPERATION_SUCCESS) {
1258 C_LOGE("app_add_rule failed");
1262 free(smack_label_list[i]);
1265 ret = PC_OPERATION_SUCCESS;
1268 /* If something failed, then no entry of smack_label_list[i]
1269 was deallocated. They all must be freed.*/
1270 for (; i < smack_label_list_len; ++i) {
1271 free(smack_label_list[i]);
1279 * This function will grant app_id rx access to all public directories and
1280 * files previously designated by app_setup_path(APP_PATH_PUBLIC_RO)
1281 * This should be called in app_install function.
1283 static int register_app_for_public_dirs(const char *app_id, struct smack_accesses *smack)
1285 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1288 char **public_dirs AUTO_FREE;
1289 int public_dirs_cnt = 0;
1291 ret = db_get_public_dirs(&public_dirs, &public_dirs_cnt);
1292 if (ret != PC_OPERATION_SUCCESS) {
1293 C_LOGE("Error while getting data from database");
1297 for (i = 0; i < public_dirs_cnt; ++i) {
1298 SECURE_C_LOGD("Allowing app %s to access public path %s", app_id, public_dirs[i]);
1299 if (smack_accesses_add_modify(smack, app_id, public_dirs[i], "rx", "")) {
1300 C_LOGE("app_add_rule_modify failed");
1301 while (i < public_dirs_cnt)
1302 free(public_dirs[i++]);
1303 return PC_ERR_INVALID_OPERATION;
1305 free(public_dirs[i]);
1308 return PC_OPERATION_SUCCESS;
1311 static int app_add_permissions_internal(const char* app_id, app_type_t app_type, const char** perm_list, int permanent)
1313 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, app_type=%d, permanent=%d",
1314 __func__, app_id, app_type, permanent);
1317 char* smack_path AUTO_FREE;
1318 char* smack_path_early AUTO_FREE;
1320 int fd_early AUTO_CLOSE;
1321 struct smack_accesses *smack AUTO_SMACK_FREE;
1322 struct smack_accesses *smack_early AUTO_SMACK_FREE;
1323 const char* base_perm = NULL;
1325 if (!smack_label_is_valid(app_id)) {
1326 C_LOGE("Invalid param app_id.");
1327 return PC_ERR_INVALID_PARAM;
1330 if(perm_list == NULL) {
1331 C_LOGE("Invalid perm_list (NULL).");
1332 return PC_ERR_INVALID_PARAM;
1335 ret = load_smack_from_file(app_id, &smack, &fd, &smack_path);
1336 if (ret != PC_OPERATION_SUCCESS) {
1337 C_LOGE("load_smack_from_file failed");
1341 ret = load_smack_from_file_early(app_id, &smack_early, &fd_early, &smack_path_early);
1342 if (ret != PC_OPERATION_SUCCESS) {
1343 C_LOGE("load_smack_from_file failed");
1347 /* Implicitly enable base permission for an app_type */
1348 base_perm = app_type_name(app_type);
1350 SECURE_C_LOGD("perm_to_smack params: app_id: %s, %s", app_id, base_perm);
1351 ret = perm_to_smack(smack, app_id, APP_TYPE_OTHER, base_perm);
1352 if (ret != PC_OPERATION_SUCCESS){
1353 C_LOGE("perm_to_smack failed");
1357 // Add early permission - such permissions should be enabled right after system boot
1358 SECURE_C_LOGD("perm_to_smack params: app_id: %s, %s", app_id, base_perm);
1359 ret = perm_to_smack_early(smack_early, app_id, APP_TYPE_OTHER, base_perm);
1360 if (ret != PC_OPERATION_SUCCESS){
1361 C_LOGE("perm_to_smack failed");
1366 for (i = 0; perm_list[i] != NULL; ++i) {
1367 SECURE_C_LOGD("perm_to_smack params: app_id: %s, perm_list[%d]: %s", app_id, i, perm_list[i]);
1368 if (strcmp(perm_list[i], TIZEN_PRIVILEGE_ANTIVIRUS) == 0) {
1369 ret = app_register_av_internal(app_id, smack);
1370 if (ret != PC_OPERATION_SUCCESS) {
1371 C_LOGE("app_register_av_internal failed");
1375 if (strcmp(perm_list[i], TIZEN_PRIVILEGE_APPSETTING) == 0) {
1376 ret = app_register_appsetting(app_id, smack);
1377 if (ret != PC_OPERATION_SUCCESS) {
1378 C_LOGE("app_register_appsetting failed");
1383 ret = perm_to_smack(smack, app_id, app_type, perm_list[i]);
1384 if (ret != PC_OPERATION_SUCCESS){
1385 C_LOGE("perm_to_smack failed");
1389 ret = perm_to_smack_early(smack_early, app_id, app_type, perm_list[i]);
1390 if (ret != PC_OPERATION_SUCCESS){
1391 C_LOGE("perm_to_smack_early failed");
1395 ret = perm_to_dac(app_id, app_type, perm_list[i]);
1396 if (ret != PC_OPERATION_SUCCESS){
1397 C_LOGE("perm_to_dac failed");
1402 if (have_smack() && smack_accesses_apply(smack)) {
1403 C_LOGE("smack_accesses_apply failed");
1404 return PC_ERR_INVALID_OPERATION;
1407 if (have_smack() && smack_accesses_apply(smack_early)) {
1408 C_LOGE("smack_accesses_apply (early) failed");
1409 return PC_ERR_INVALID_OPERATION;
1412 if (permanent && smack_accesses_save(smack, fd)) {
1413 C_LOGE("smack_accesses_save failed");
1414 return PC_ERR_INVALID_OPERATION;
1417 if (permanent && smack_accesses_save(smack_early, fd_early)) {
1418 C_LOGE("smack_accesses_save (early) failed");
1419 return PC_ERR_INVALID_OPERATION;
1422 return PC_OPERATION_SUCCESS;
1425 API int app_add_permissions(const char* app_id, const char** perm_list)//deprecated
1427 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1430 return app_add_permissions_internal(app_id, APP_TYPE_OTHER, perm_list, 1);
1433 API int app_add_volatile_permissions(const char* app_id, const char** perm_list)//deprecated
1435 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1438 return app_add_permissions_internal(app_id, APP_TYPE_OTHER, perm_list, 0);
1441 API int app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)//deprecated
1443 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
1444 __func__, pkg_id, app_type, persistent);
1446 return app_add_permissions_internal(pkg_id, app_type, perm_list, persistent);
1449 API int perm_app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)
1451 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
1452 __func__, pkg_id, app_type, persistent);
1454 return app_add_permissions_internal(pkg_id, app_type, perm_list, persistent);
1457 API int app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)//deprecated
1459 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
1460 __func__, pkg_id, app_type);
1462 return perm_app_disable_permissions(pkg_id, app_type, perm_list);
1465 /* FIXME: this function is only a stub */
1466 API int perm_app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)
1468 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
1469 __func__, pkg_id, app_type);
1471 return PC_OPERATION_SUCCESS;
1474 static int app_revoke_permissions_internal(const char* app_id, bool persistent)
1476 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, persistent=%d",
1477 __func__, app_id, persistent);
1479 char* smack_path AUTO_FREE;
1482 struct smack_accesses *smack AUTO_SMACK_FREE;
1484 if (!smack_label_is_valid(app_id)) {
1485 C_LOGE("Invalid param app_id.");
1486 return PC_ERR_INVALID_PARAM;
1489 ret = load_smack_from_file(app_id, &smack, &fd, &smack_path);
1490 if (ret != PC_OPERATION_SUCCESS) {
1491 C_LOGE("load_smack_from_file failed.");
1495 if (have_smack() && smack_accesses_clear(smack)) {
1496 ret = PC_ERR_INVALID_OPERATION;
1497 C_LOGE("smack_accesses_clear failed.");
1501 if (have_smack() && smack_revoke_subject(app_id)) {
1502 ret = PC_ERR_INVALID_OPERATION;
1503 C_LOGE("smack_revoke_subject failed.");
1507 if (persistent && ftruncate(fd, 0) == -1)
1508 C_LOGW("file truncation failed");
1510 return PC_OPERATION_SUCCESS;
1513 API int app_revoke_permissions(const char* pkg_id)//deprecated
1515 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
1516 return perm_app_revoke_permissions(pkg_id);
1519 API int perm_app_revoke_permissions(const char* pkg_id)
1521 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
1524 if (!smack_label_is_valid(pkg_id)) {
1525 C_LOGE("Invalid param app_id.");
1526 return PC_ERR_INVALID_PARAM;
1529 ret = app_revoke_permissions_internal(pkg_id, true);
1531 C_LOGE("Revoking permissions failed.");
1535 return PC_OPERATION_SUCCESS;
1538 API int app_reset_permissions(const char* pkg_id)//deprecated
1540 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
1543 return perm_app_reset_permissions(pkg_id);
1546 API int perm_app_reset_permissions(const char* pkg_id)
1548 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
1553 if (!smack_label_is_valid(pkg_id)) {
1554 C_LOGE("Invalid param pkg_id.");
1555 return PC_ERR_INVALID_PARAM;
1558 ret = app_revoke_permissions_internal(pkg_id, false);
1560 C_LOGE("Revoking permissions failed.");
1564 /* Add empty permissions set to trigger re-read of rules */
1565 return perm_app_enable_permissions(pkg_id, APP_TYPE_OTHER, (const char*[]){NULL}, 0);
1568 API int app_label_dir(const char* label, const char* path)//deprecated
1570 SECURE_C_LOGD("Entering function: %s. Params: label=%s, path=%s",
1571 __func__, label, path);
1573 int ret = PC_OPERATION_SUCCESS;
1576 C_LOGE("Invalid argument path (NULL).");
1577 return PC_ERR_INVALID_PARAM;
1580 if (!smack_label_is_valid(label)) {
1581 C_LOGE("Invalid param label.");
1582 return PC_ERR_INVALID_PARAM;
1585 //setting access label on everything in given directory and below
1586 ret = dir_set_smack_r(path, label, SMACK_LABEL_ACCESS, &label_all);
1587 if (PC_OPERATION_SUCCESS != ret)
1589 C_LOGE("dir_set_smack_r failed.");
1593 //setting execute label for everything with permission to execute
1594 ret = dir_set_smack_r(path, label, SMACK_LABEL_EXEC, &label_execs);
1595 if (PC_OPERATION_SUCCESS != ret)
1597 C_LOGE("dir_set_smack_r failed.");
1601 //setting execute label for everything with permission to execute
1602 ret = dir_set_smack_r(path, label, SMACK_LABEL_EXEC, &label_links_to_execs);
1606 int smack_get_access_new(const char* subject, const char* object, char** label)
1608 SECURE_C_LOGD("Entering function: %s. Params: subject=%s, object=%s",
1609 __func__, subject, object);
1611 char buff[ACC_LEN] = {'r', 'w', 'x', 'a', 't', 'l'};
1612 char perm[2] = {'-'};
1615 if(!smack_label_is_valid(subject)) {
1616 C_LOGE("Invalid param subject.");
1617 return PC_ERR_INVALID_PARAM;
1620 if(!smack_label_is_valid(object)) {
1621 C_LOGE("Invalid param object.");
1622 return PC_ERR_INVALID_PARAM;
1626 C_LOGE("Invalid param label (NULL).");
1627 return PC_ERR_INVALID_PARAM;
1630 for (i=0; i<ACC_LEN; ++i) {
1632 int ret = smack_have_access(subject, object, perm);
1634 C_LOGE("smack_have_access failed during %c check.", perm[0]);
1635 return PC_ERR_INVALID_OPERATION;
1641 *label = malloc(ACC_LEN+1);
1643 return PC_ERR_MEM_OPERATION;
1645 memcpy(*label, buff, ACC_LEN);
1646 (*label)[ACC_LEN] = 0;
1647 return PC_OPERATION_SUCCESS;
1650 static int app_uninstall_remove_early_rules(const char *app_id)
1652 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1659 char *data, *data_end;
1660 char *line_begin, *line_end, *write_pos;
1661 char subject[SMACK_LABEL_LEN + 1];
1662 char object[SMACK_LABEL_LEN + 1];
1664 SECURE_C_LOGD("Opening file %s.", SMACK_STARTUP_RULES_FILE);
1665 fd = open(SMACK_STARTUP_RULES_FILE, O_RDWR);
1667 SECURE_C_LOGE("Unable to open file %s: %s", SMACK_STARTUP_RULES_FILE, strerror(errno));
1668 return PC_ERR_FILE_OPERATION;
1671 if (flock(fd, LOCK_EX)) {
1672 SECURE_C_LOGE("flock failed, error %s", strerror(errno));
1673 return PC_ERR_FILE_OPERATION;
1676 size = lseek(fd, 0, SEEK_END);
1678 SECURE_C_LOGE("Unable to read file %s: %s", SMACK_STARTUP_RULES_FILE, strerror(errno));
1679 return PC_ERR_FILE_OPERATION;
1683 return PC_OPERATION_SUCCESS;
1685 data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1686 if (data == MAP_FAILED) {
1687 SECURE_C_LOGE("Unable to read file %s: %s", SMACK_STARTUP_RULES_FILE, strerror(errno));
1688 return PC_ERR_FILE_OPERATION;
1690 data_end = data + size;
1692 line_begin = write_pos = data;
1693 while (line_begin < data_end) {
1694 line_end = memchr(line_begin, '\n', data_end - line_begin);
1695 if (line_end == NULL)
1696 line_end = data_end - 1;
1700 SECURE_C_LOGD("Considering early rule: %s", line_begin);
1702 ret = sscanf(line_begin, "%" TOSTRING(SMACK_LABEL_LEN) "s %" TOSTRING(SMACK_LABEL_LEN) "s", subject, object);
1704 C_LOGD("Rule format is invalid, skipping it.");
1708 if (!strcmp(subject, app_id) || !strcmp(object, app_id)) {
1709 C_LOGD("Rule belongs to an app being removed, skipping it.");
1713 C_LOGD("Rule still needed, keeping it.");
1715 if (write_pos != line_begin)
1716 memcpy(write_pos, line_begin, line_end - line_begin + 1);
1717 write_pos += (line_end - line_begin + 1);
1721 line_begin = line_end + 1;
1725 ret = ftruncate(fd, write_pos - data);
1727 SECURE_C_LOGE("Unable to truncate file %s to %d bytes: %s", SMACK_STARTUP_RULES_FILE, write_pos, strerror(errno));
1729 return PC_ERR_FILE_OPERATION;
1732 return PC_OPERATION_SUCCESS;
1735 API int app_label_shared_dir(const char* app_label, const char* shared_label, const char* path)//deprecated
1737 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, shared_label=%s, path=%s",
1738 __func__, app_label, shared_label, path);
1742 C_LOGE("Invalid param path.");
1743 return PC_ERR_INVALID_PARAM;
1746 if(!smack_label_is_valid(app_label)) {
1747 C_LOGE("Invalid param app_label");
1748 return PC_ERR_INVALID_PARAM;
1751 if(!smack_label_is_valid(shared_label)) {
1752 C_LOGE("Invalid param shared_label");
1753 return PC_ERR_INVALID_PARAM;
1756 if (strcmp(app_label, shared_label) == 0) {
1757 C_LOGE("app_label equals shared_label");
1758 return PC_ERR_INVALID_PARAM;
1761 //setting label on everything in given directory and below
1762 ret = dir_set_smack_r(path, shared_label, SMACK_LABEL_ACCESS, label_all);
1763 if(ret != PC_OPERATION_SUCCESS){
1764 C_LOGE("dir_set_smack_r failed.");
1768 //setting transmute on dir
1769 ret = dir_set_smack_r(path, "1", SMACK_LABEL_TRANSMUTE, label_dirs);
1770 if (ret != PC_OPERATION_SUCCESS) {
1771 C_LOGE("dir_set_smack_r failed");
1775 ret = app_add_rule(app_label, shared_label, "rwxat");
1776 if (ret != PC_OPERATION_SUCCESS) {
1777 C_LOGE("app_add_rule failed");
1781 return PC_OPERATION_SUCCESS;
1784 API int add_shared_dir_readers(const char* shared_label, const char** app_list)//deprecated
1786 SECURE_C_LOGD("Entering function: %s. Params: shared_label=%s",
1787 __func__, shared_label);
1791 if(app_list == NULL) {
1792 C_LOGE("Invalid param app_list.");
1793 return PC_ERR_INVALID_PARAM;
1796 if (!smack_label_is_valid(shared_label)) {
1797 C_LOGE("Invalid param shared_label.");
1798 return PC_ERR_INVALID_PARAM;
1801 for (i = 0; app_list[i] != NULL; i++) {
1802 if (!smack_label_is_valid(app_list[i])) {
1803 C_LOGE("Invalid %d element from param app_list.", i);
1804 return PC_ERR_INVALID_PARAM;
1807 ret = app_add_rule(app_list[i], shared_label, "rx");
1808 if (ret != PC_OPERATION_SUCCESS) {
1809 C_LOGE("app_add_rule failed.");
1814 return PC_OPERATION_SUCCESS;
1817 static char* smack_label_for_path(const char *app_id, const char *path)
1819 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, path=%s",
1820 __func__, app_id, path);
1822 char *salt AUTO_FREE;
1826 /* Prefix $1$ causes crypt() to use MD5 function */
1827 if (-1 == asprintf(&salt, "$1$%s", app_id)) {
1828 C_LOGE("asprintf failed");
1832 label = crypt(path, salt);
1833 if (label == NULL) {
1834 C_LOGE("crypt failed");
1838 /* crypt() output may contain slash character,
1839 * which is not legal in Smack labels */
1840 for (x = label; *x; ++x) {
1848 * This function should be called in perm_app_setup_path_internal().
1849 * After installation of new application (pkg_id) and labeling its shared directory (RW or RO),
1850 * all others apps installed in system should get rules to this shared directory.
1851 * This function will add and store those rules in rule-file of new installed app (pkg_id)
1853 static int add_other_apps_rules_for_shared_dir(const char *pkg_id, const char *type_of_shared_dir, const char *shared_dir_label)
1855 C_LOGD("Enter function: %s", __func__);
1859 char *smack_path AUTO_FREE;
1860 char *smack_rules_file_path AUTO_FREE;
1861 struct smack_accesses* smack AUTO_SMACK_FREE;
1863 ret = load_smack_from_file(pkg_id, &smack, &fd, &smack_path);
1864 if (ret != PC_OPERATION_SUCCESS ) {
1865 C_LOGE("load_smack_from_file failed: %d", ret);
1869 ret = asprintf(&smack_rules_file_path, TOSTRING(SHAREDIR)"/%s", type_of_shared_dir);
1871 C_LOGE("asprintf failed");
1872 return PC_ERR_MEM_OPERATION;
1875 ret = perm_to_smack_from_file(smack, shared_dir_label, SMACK_SHARED_DIR_LABEL_TEMPLATE, smack_rules_file_path);
1876 if (ret != PC_OPERATION_SUCCESS ) {
1877 C_LOGE("perm_to_smack_from_file failed: %d", ret);
1880 if (have_smack() && smack_accesses_apply(smack)) {
1881 C_LOGE("smack_accesses_apply failed");
1882 return PC_ERR_INVALID_OPERATION;
1885 if (smack_accesses_save(smack, fd)) {
1886 C_LOGE("smack_accesses_save failed");
1887 return PC_ERR_INVALID_OPERATION;
1890 return PC_OPERATION_SUCCESS;
1893 /* FIXME: remove this pragma once deprecated API is deleted */
1894 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1895 static int perm_app_setup_path_internal(const char* pkg_id, const char* path, app_path_type_t app_path_type, va_list ap)
1897 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
1898 __func__, pkg_id, path, app_path_type);
1901 C_LOGE("Invalid argument path.");
1902 return PC_ERR_INVALID_PARAM;
1905 if (!smack_label_is_valid(pkg_id)) {
1906 C_LOGE("Invalid pkg_id.");
1907 SECURE_C_LOGE("Invalid pkg_id %s", pkg_id);
1908 return PC_ERR_INVALID_PARAM;
1911 switch (app_path_type) {
1912 case APP_PATH_PRIVATE:
1913 C_LOGD("app_path_type is APP_PATH_PRIVATE.");
1914 return app_label_dir(pkg_id, path);
1916 case APP_PATH_GROUP_RW: {
1917 C_LOGD("app_path_type is APP_PATH_GROUP_RW.");
1919 const char *shared_label;
1921 shared_label = va_arg(ap, const char *);
1923 if (!smack_label_is_valid(shared_label)) {
1924 C_LOGE("Invalid shared_label.");
1925 return PC_ERR_INVALID_PARAM;
1928 if (strcmp(pkg_id, shared_label) == 0) {
1929 C_LOGE("pkg_id equals shared_label.");
1930 return PC_ERR_INVALID_PARAM;
1933 ret = app_label_shared_dir(pkg_id, shared_label, path);
1934 if (ret != PC_OPERATION_SUCCESS) {
1935 C_LOGE("app_label_shared_dir failed: %d", ret);
1939 return add_other_apps_rules_for_shared_dir(pkg_id, PATH_RULES_GROUP_RW, shared_label);
1942 case APP_PATH_PUBLIC_RO: {
1943 C_LOGD("app_path_type is APP_PATH_PUBLIC_RO.");
1944 char **app_ids AUTO_FREE;
1945 int app_ids_cnt = 0;
1949 C_LOGD("New public RO path %s", path);
1950 label = smack_label_for_path(pkg_id, path);
1951 if (label == NULL) {
1952 C_LOGE("smack_label_for_path failed.");
1953 return PC_ERR_INVALID_OPERATION;
1956 C_LOGD("Generated label '%s' for public RO path %s", label, path);
1957 ret = app_label_shared_dir(pkg_id, label, path);
1958 if (ret != PC_OPERATION_SUCCESS) {
1959 C_LOGE("app_label_shared_dir failed.");
1963 /* FIXME: This should be in some kind of transaction/lock */
1964 ret = db_add_public_dir(label);
1965 if (ret != PC_OPERATION_SUCCESS) {
1966 C_LOGE("db_add_public_dir failed.");
1970 ret = get_all_apps_ids(&app_ids, &app_ids_cnt);
1971 if (ret != PC_OPERATION_SUCCESS) {
1972 C_LOGE("get_all_aps_ids failed.");
1976 for (i = 0; i < app_ids_cnt; ++i) {
1977 SECURE_C_LOGD("Allowing app %s to access public path %s", app_ids[i], path);
1978 ret = app_add_rule(app_ids[i], label, "rx");
1979 if (ret != PC_OPERATION_SUCCESS) {
1980 C_LOGE("smack_accesses_new failed");
1981 while (i < app_ids_cnt)
1988 return add_other_apps_rules_for_shared_dir(pkg_id, PATH_RULES_PUBLIC_RO, label);
1991 case APP_PATH_SETTINGS_RW:
1993 C_LOGD("app_path_type is APP_PATH_SETTINGS_RW.");
1994 char **app_ids AUTO_FREE;
1995 int app_ids_cnt = 0;
2001 label = smack_label_for_path(pkg_id, path);
2002 if (label == NULL) {
2003 C_LOGE("smack_label_for_path failed.");
2004 return PC_ERR_INVALID_OPERATION;
2007 /*set id for path and all subfolders*/
2008 C_LOGD("Appsetting: generated label '%s' for setting path %s", label, path);
2009 ret = app_label_shared_dir(pkg_id, label, path);
2010 if (ret != PC_OPERATION_SUCCESS) {
2011 C_LOGE("Appsetting: app_label_shared_dir failed (%d)", ret);
2015 /* add path to database */
2016 /* FIXME: This should be in some kind of transaction/lock */
2017 ret = add_setting_dir_id_to_databse(label);
2018 if (ret != PC_OPERATION_SUCCESS) {
2019 C_LOGE("Appsetting: add_setting_dir_id_to_databse failed");
2023 /*read all apps with appsetting privilege*/
2024 ret = get_all_appsetting_ids(&app_ids, &app_ids_cnt);
2025 if (ret != PC_OPERATION_SUCCESS) {
2026 C_LOGE("Appsetting: get_all_appsetting_ids failed");
2029 C_LOGD("Appsetting: %d appsetting privileged apps registered",
2032 /*give RWX rights to all apps that have appsetting privilege*/
2033 for (i = 0; i < app_ids_cnt; ++i) {
2034 C_LOGD("Appsetting: allowing app %s to access setting path %s",
2036 ret = app_add_rule(app_ids[i], label, "rwx");
2037 if (ret != PC_OPERATION_SUCCESS) {
2038 C_LOGE("app_add_rule failed");
2039 while (i < app_ids_cnt)
2046 return PC_OPERATION_SUCCESS;
2049 case APP_PATH_ANY_LABEL: {
2050 C_LOGD("app_path_type is APP_PATH_ANY_LABEL.");
2051 const char *label = NULL;
2052 label = va_arg(ap, const char *);
2053 return app_label_dir(label, path);
2057 C_LOGE("app_path_type is invalid.");
2058 return PC_ERR_INVALID_PARAM;
2061 return PC_OPERATION_SUCCESS;
2063 /* FIXME: remove this pragma once deprecated API is deleted */
2064 #pragma GCC diagnostic warning "-Wdeprecated-declarations"
2066 API int app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)//deprecated
2068 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
2069 __func__, pkg_id, path, app_path_type);
2073 va_start( ap, app_path_type );
2074 ret = perm_app_setup_path_internal( pkg_id, path, app_path_type, ap );
2080 API int perm_app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)
2082 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
2083 __func__, pkg_id, path, app_path_type);
2087 va_start( ap, app_path_type );
2088 ret = perm_app_setup_path_internal( pkg_id, path, app_path_type, ap );
2093 API int app_add_friend(const char* pkg_id1, const char* pkg_id2)//deprecated
2095 SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
2096 __func__, pkg_id1, pkg_id2);
2098 return perm_app_add_friend(pkg_id1, pkg_id2);
2101 API int perm_app_add_friend(const char* pkg_id1, const char* pkg_id2)
2103 SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
2104 __func__, pkg_id1, pkg_id2);
2108 if (!smack_label_is_valid(pkg_id1) || !smack_label_is_valid(pkg_id2)) {
2109 C_LOGE("Invalid pkg_id1 or pkg_id2.");
2110 return PC_ERR_INVALID_PARAM;
2113 ret = app_add_rule(pkg_id1, pkg_id2, "rwxat");
2114 if (ret != PC_OPERATION_SUCCESS) {
2115 C_LOGE("app_add_rule failed");
2119 ret = app_add_rule(pkg_id2, pkg_id1, "rwxat");
2120 if (ret != PC_OPERATION_SUCCESS) {
2121 C_LOGE("app_add_rule failed");
2125 return PC_OPERATION_SUCCESS;
2128 API int app_install(const char* pkg_id)//deprecated
2130 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
2133 return perm_app_install(pkg_id);
2136 API int perm_app_install(const char* pkg_id)
2138 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
2143 char* smack_path AUTO_FREE;
2144 struct smack_accesses *smack AUTO_SMACK_FREE;
2146 if (!smack_label_is_valid(pkg_id)) {
2147 C_LOGE("Invalid param pkg_id.");
2148 return PC_ERR_INVALID_PARAM;
2151 ret = smack_file_name(pkg_id, &smack_path);
2152 if (ret != PC_OPERATION_SUCCESS) {
2153 C_LOGE("smack_file_name failed.");
2157 ret = load_smack_from_file(pkg_id, &smack, &fd, &smack_path);
2158 if (ret != PC_OPERATION_SUCCESS) {
2159 C_LOGE("load_smack_from_file failed");
2163 ret = add_app_id_to_databse(pkg_id);
2164 if (ret != PC_OPERATION_SUCCESS ) {
2165 SECURE_C_LOGE("Error while adding app %s to database: %s ", pkg_id, strerror(errno));
2169 ret = register_app_for_av(pkg_id);
2170 if (ret != PC_OPERATION_SUCCESS) {
2171 SECURE_C_LOGE("Error while adding rules for anti viruses to app %s: %s ", pkg_id, strerror(errno));
2175 ret = register_app_for_appsetting(pkg_id);
2176 if (ret != PC_OPERATION_SUCCESS) {
2177 SECURE_C_LOGE("Error while adding rules for setting managers to app %s: %s ", pkg_id, strerror(errno));
2181 ret = register_app_for_public_dirs(pkg_id, smack);
2182 if (ret != PC_OPERATION_SUCCESS) {
2183 SECURE_C_LOGE("Error while adding rules for access to public dirs for app %s: %s ", pkg_id, strerror(errno));
2187 if (have_smack() && smack_accesses_apply(smack)) {
2188 C_LOGE("smack_accesses_apply failed");
2189 return PC_ERR_INVALID_OPERATION;
2192 if (smack_accesses_save(smack, fd)) {
2193 C_LOGE("smack_accesses_save failed");
2194 return PC_ERR_INVALID_OPERATION;
2197 return PC_OPERATION_SUCCESS;
2200 API int app_uninstall(const char* pkg_id)//deprecated
2202 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
2205 return perm_app_uninstall(pkg_id);
2208 API int perm_app_uninstall(const char* pkg_id)
2210 // TODO: When real database will be used, then this function should remove app_id
2212 // It also should remove rules like: "anti_virus_label app_id rwx".
2213 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
2214 char* smack_path AUTO_FREE;
2217 if (!smack_label_is_valid(pkg_id)) {
2218 C_LOGE("Invalid param pkg_id.");
2219 return PC_ERR_INVALID_PARAM;
2222 ret = smack_file_name(pkg_id, &smack_path);
2223 if (ret != PC_OPERATION_SUCCESS) {
2224 C_LOGE("smack_file_name failed.");
2228 if (unlink(smack_path)) {
2229 C_LOGE("unlink failed (error: %s)", strerror(errno));
2230 return PC_OPERATION_SUCCESS;
2233 ret = app_uninstall_remove_early_rules(pkg_id);
2234 if (ret != PC_OPERATION_SUCCESS) {
2235 C_LOGE("app_uninstall_remove_early_rules failed.");
2239 return PC_OPERATION_SUCCESS;
2242 static int save_rules(int fd, struct smack_accesses* accesses) {
2243 SECURE_C_LOGD("Entering function: %s. Params: fd=%d", __func__, fd);
2245 if (flock(fd, LOCK_EX)) {
2246 C_LOGE("flock failed (error: %s)", strerror(errno));
2247 return PC_ERR_FILE_OPERATION;
2250 if (smack_accesses_save(accesses, fd)) {
2251 C_LOGE("smack_accesses_save failed");
2252 return PC_ERR_FILE_OPERATION;
2254 return PC_OPERATION_SUCCESS ;
2257 static int validate_and_add_rule(char* rule, struct smack_accesses* accesses) {
2258 SECURE_C_LOGD("Entering function: %s. Params: rule=%s",
2261 const char* subject = NULL;
2262 const char* object = NULL;
2263 const char* access = NULL;
2264 char* saveptr = NULL;
2266 subject = strtok_r(rule, " \t\n", &saveptr);
2267 object = strtok_r(NULL, " \t\n", &saveptr);
2268 access = strtok_r(NULL, " \t\n", &saveptr);
2270 // check rule validity
2271 if (subject == NULL ||
2274 strtok_r(NULL, " \t\n", &saveptr) != NULL ||
2275 !smack_label_is_valid(subject) ||
2276 !smack_label_is_valid(object))
2278 C_LOGE("Incorrect rule format: %s", rule);
2279 return PC_ERR_INVALID_PARAM;
2282 if (smack_accesses_add_modify(accesses, subject, object, access, "")) {
2283 C_LOGE("smack_accesses_add_modify failed");
2284 return PC_ERR_INVALID_OPERATION;
2286 return PC_OPERATION_SUCCESS ;
2289 static int parse_and_save_rules(const char** smack_rules,
2290 struct smack_accesses* accesses, const char* feature_file) {
2291 SECURE_C_LOGD("Entering function: %s. Params: feature_file=%s",
2292 __func__, feature_file);
2296 int ret = PC_OPERATION_SUCCESS;
2299 for (i = 0; smack_rules[i] != NULL ; i++) {
2300 // ignore empty lines
2301 if (strspn(smack_rules[i], " \t\n") == strlen(smack_rules[i]))
2304 tmp = strdup(smack_rules[i]);
2305 ret = validate_and_add_rule(tmp, accesses);
2307 if (ret != PC_OPERATION_SUCCESS )
2312 fd = open(feature_file, O_CREAT | O_WRONLY, 0644);
2314 SECURE_C_LOGE("Unable to create file %s. (error: %s)", feature_file, strerror(errno));
2315 return PC_ERR_FILE_OPERATION;
2318 ret = save_rules(fd, accesses);
2323 static int save_gids(FILE* file, const gid_t* list_of_db_gids, size_t list_size) {
2324 SECURE_C_LOGD("Entering function: %s.", __func__);
2325 int ret = PC_OPERATION_SUCCESS;
2330 C_LOGE("Unable to create file. Error: %s", strerror(errno));
2331 return PC_ERR_FILE_OPERATION; // TODO remove smack accesses?
2334 if(-1 == fchmod(fileno(file), 0644)) {
2335 C_LOGE("Unable to chmod file. Error: %s", strerror(errno));
2336 return PC_ERR_FILE_OPERATION;
2339 for (i = 0; i < list_size ; ++i) {
2340 written = fprintf(file, "%u\n", list_of_db_gids[i]);
2342 C_LOGE("fprintf failed for file. Error: %s", strerror(errno));
2343 ret = PC_ERR_FILE_OPERATION;
2350 API int add_api_feature(app_type_t app_type,
2351 const char* api_feature_name,
2352 const char** smack_rules,
2353 const gid_t* list_of_db_gids,
2354 size_t list_size)//deprecated
2356 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, api_feature_name=%s",
2357 __func__, app_type, api_feature_name);
2359 return perm_add_api_feature(app_type, api_feature_name, smack_rules, list_of_db_gids, list_size);
2362 API int perm_add_api_feature(app_type_t app_type,
2363 const char* api_feature_name,
2364 const char** smack_rules,
2365 const gid_t* list_of_db_gids,
2367 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, api_feature_name=%s",
2368 __func__, app_type, api_feature_name);
2370 int ret = PC_OPERATION_SUCCESS;
2371 char* smack_file AUTO_FREE;
2372 char* dac_file AUTO_FREE;
2373 struct smack_accesses* accesses = NULL;
2376 // TODO check process capabilities
2378 // get feature SMACK file name
2379 ret = perm_file_path(&smack_file, app_type, api_feature_name, ".smack", 0);
2380 if (ret != PC_OPERATION_SUCCESS || !smack_file ) {
2381 C_LOGE("perm_file_path failed.");
2385 // check if feature exists
2386 if (file_exists(smack_file)) {
2387 C_LOGE("Feature file %s already exists", smack_file);
2388 return PC_ERR_INVALID_PARAM;
2391 // check .dac existence only if gids are supported
2392 if (list_of_db_gids && list_size > 0) {
2393 // get feature DAC file name
2394 ret = perm_file_path(&dac_file, app_type, api_feature_name, ".dac", 0);
2395 if (ret != PC_OPERATION_SUCCESS || !dac_file ) {
2396 C_LOGE("perm_file_path failed.");
2400 // check if feature exists
2401 if (file_exists(dac_file)) {
2402 C_LOGE("Feature file %s already exists", dac_file);
2403 return PC_ERR_INVALID_PARAM;
2407 // parse & save rules
2409 if (smack_accesses_new(&accesses)) {
2410 C_LOGE("smack_acceses_new failed");
2411 return PC_ERR_MEM_OPERATION;
2414 ret = parse_and_save_rules(smack_rules, accesses, smack_file);
2415 smack_accesses_free(accesses);
2418 // go through gid list
2419 if (ret == PC_OPERATION_SUCCESS && list_of_db_gids && list_size > 0) {
2421 SECURE_C_LOGD("Opening file %s.", dac_file);
2422 file = fopen(dac_file, "w+");
2423 ret = save_gids(file, list_of_db_gids, list_size);
2427 // remove both files in case of failure
2428 if (ret != PC_OPERATION_SUCCESS) {
2439 * This function is marked as deprecated and will be removed
2441 API int app_register_av(const char* app_av_id)//deprecated
2443 SECURE_C_LOGD("Entering function: %s. Params: app_av_id=%s",
2444 __func__, app_av_id);
2448 char* smack_path AUTO_FREE;
2449 struct smack_accesses* smack AUTO_SMACK_FREE;
2451 if(app_av_id == NULL) {
2452 C_LOGE("Invalid param app_av_id.");
2453 return PC_ERR_INVALID_PARAM;
2456 ret = load_smack_from_file(app_av_id, &smack, &fd, &smack_path);
2457 if (ret != PC_OPERATION_SUCCESS ) {
2458 C_LOGE("load_smack_from_file failed");
2462 ret = app_register_av_internal(app_av_id, smack);
2463 if (PC_OPERATION_SUCCESS != ret) {
2464 C_LOGE("app_register_av_internal failed");
2468 // Add permisions from OSP_antivirus.smack file
2469 ret = perm_to_smack(smack, app_av_id, APP_TYPE_OSP, TIZEN_PRIVILEGE_ANTIVIRUS);
2470 if (PC_OPERATION_SUCCESS != ret) {
2471 C_LOGE("perm_to_smack failed");
2475 // Add permisions from OSP_antivirus.dac file
2476 ret = perm_to_dac(app_av_id, APP_TYPE_OSP, TIZEN_PRIVILEGE_ANTIVIRUS);
2477 if (ret != PC_OPERATION_SUCCESS) {
2478 C_LOGE("perm_to_dac failed");
2482 if (have_smack() && smack_accesses_apply(smack)) {
2483 C_LOGE("smack_accesses_apply failed");
2484 ret = PC_ERR_INVALID_OPERATION;
2488 if (smack_accesses_save(smack, fd)) {
2489 C_LOGE("smack_accesses_save failed");
2490 ret = PC_ERR_INVALID_OPERATION;