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)
580 were_rules_loaded = check_if_rules_were_loaded(smack_label);
581 if (were_rules_loaded < 0) {
582 C_LOGE("check_if_rules_was_loaded failed.");
583 return PC_ERR_INVALID_OPERATION;
585 if (!were_rules_loaded) { // first run of application
586 C_LOGD("This is first run of this application. Adding SMACK rules.");
587 ret = add_app_first_run_rules(smack_label);
588 if (ret != PC_OPERATION_SUCCESS ) {
589 C_LOGW("add_app_first_run_rules failed");
590 // should we return here with error code?
592 mark_rules_as_loaded(smack_label);
595 ret = set_smack_for_self(smack_label);
596 if (ret != PC_OPERATION_SUCCESS)
600 if (path != NULL && !have_smack()) {
601 ret = get_smack_from_binary(&smack_label, path, verify_app_type(type, path));
602 if (ret != PC_OPERATION_SUCCESS)
606 return set_dac(smack_label, name);
609 API int set_privilege(const char* pkg_name)//deprecated
611 SECURE_C_LOGD("Entering function: %s. Params: pkg_name=%s",
614 return perm_app_set_privilege(pkg_name, NULL, NULL);
617 static inline const char* app_type_name(app_type_t app_type)
619 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d",
624 C_LOGD("App type = APP_TYPE_WGT");
627 C_LOGD("App type = APP_TYPE_OSP");
629 case APP_TYPE_WGT_PARTNER:
630 C_LOGD("App type = APP_TYPE_WGT_PARTNER");
631 return "WRT_partner";
632 case APP_TYPE_WGT_PLATFORM:
633 C_LOGD("App type = APP_TYPE_WGT_PLATFORM");
634 return "WRT_platform";
635 case APP_TYPE_OSP_PARTNER:
636 C_LOGD("App type = APP_TYPE_OSP_PARTNER");
637 return "OSP_partner";
638 case APP_TYPE_OSP_PLATFORM:
639 C_LOGD("App type = APP_TYPE_OSP_PLATFORM");
640 return "OSP_platform";
644 C_LOGD("App type = other");
649 static inline const char* app_type_group_name(app_type_t app_type)
651 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d",
656 case APP_TYPE_WGT_PARTNER:
657 case APP_TYPE_WGT_PLATFORM:
658 C_LOGD("App type group name = WRT");
661 case APP_TYPE_OSP_PARTNER:
662 case APP_TYPE_OSP_PLATFORM:
663 C_LOGD("App type group name = OST");
673 * This function changes permission URI to basename for file name.
674 * For e.g. from http://tizen.org/privilege/contact.read will be
675 * created basename : org.tizen.privilege.contact.read
678 static int base_name_from_perm(const char *perm, char **name)
680 SECURE_C_LOGD("Entering function: %s. Params: perm=%s",
684 char *host_dot = NULL;
685 char *rest_slash = NULL;
688 ip = iri_parse(perm);
689 if (ip == NULL || ip->host == NULL) {
690 SECURE_C_LOGE("Bad permission format : %s", perm);
692 return PC_ERR_INVALID_PARAM;
695 if (ip->path == NULL) {
701 host_dot = strrchr(ip->host, '.');
708 while ((rest_slash = strchr(ip->path, '/'))) {
712 ret = asprintf(name, "%s%s%s%s",
713 host_dot ? host_dot : "", host_dot ? "." : "",
714 ip->host ? ip->host : "", ip->path);
716 C_LOGE("asprintf failed");
718 return PC_ERR_MEM_OPERATION;
722 return PC_OPERATION_SUCCESS;
725 static int perm_file_path(char** path, app_type_t app_type, const char* perm, const char *suffix, bool is_early)
727 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, perm=%s, suffix=%s, is_early=%d",
728 __func__, app_type, perm, suffix, is_early);
730 const char* app_type_prefix = NULL;
731 char* perm_basename = NULL;
734 if (perm == NULL || strlen(perm) == 0) {
735 C_LOGE("Empty permission name.");
736 return PC_ERR_INVALID_PARAM;
739 app_type_prefix = app_type_group_name(app_type);
741 ret = base_name_from_perm(perm, &perm_basename);
742 if (ret != PC_OPERATION_SUCCESS) {
743 C_LOGE("Couldn't get permission basename.");
748 ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s%s",
749 app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
750 perm_basename, "_early", suffix);
753 ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s",
754 app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
755 perm_basename, suffix);
758 C_LOGE("asprintf failed.");
759 return PC_ERR_MEM_OPERATION;
762 C_LOGD("Path=%s", *path);
764 return PC_OPERATION_SUCCESS;
767 static int perm_to_smack_from_file(struct smack_accesses* smack,
768 const char* app_label,
769 const char* app_label_template,
770 const char* rules_file_path)
772 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_label_template=%s, rules_file_path=%s",
773 __func__, app_label, app_label_template, rules_file_path);
775 char smack_subject[SMACK_LABEL_LEN + 1];
776 char smack_object[SMACK_LABEL_LEN + 1];
777 char smack_accesses[ACC_LEN + 1];
778 FILE* file AUTO_FCLOSE;
780 SECURE_C_LOGD("Opening file %s.", rules_file_path);
781 file = fopen(rules_file_path, "r");
783 SECURE_C_LOGW("fopen failed [%s] %s", rules_file_path, strerror(errno));
784 return PC_OPERATION_SUCCESS;
788 "%" TOSTRING(SMACK_LABEL_LEN) "s "
789 "%" TOSTRING(SMACK_LABEL_LEN) "s "
790 "%" TOSTRING(ACC_LEN) "s\n",
791 smack_subject, smack_object, smack_accesses) == 3) {
792 if (!strcmp(smack_subject, app_label_template))
793 strcpy(smack_subject, app_label);
795 if (!strcmp(smack_object, app_label_template))
796 strcpy(smack_object, app_label);
798 C_LOGD("smack_accesses_add_modify (subject: %s, object: %s, access: %s)", smack_subject, smack_object, smack_accesses);
799 if (smack_accesses_add_modify(smack, smack_subject, smack_object, smack_accesses, "") != 0) {
800 C_LOGE("smack_accesses_add_modify failed.");
801 return PC_ERR_INVALID_OPERATION;
805 return PC_OPERATION_SUCCESS;
808 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)
810 C_LOGD("Enter function: %s", __func__);
813 char* path AUTO_FREE;
815 // get file name for permission (devcap)
816 ret = perm_file_path(&path, app_type, perm, ".smack", is_early);
817 if (ret != PC_OPERATION_SUCCESS) {
818 C_LOGD("No smack config file for permission %s", perm);
822 ret = perm_to_smack_from_file(smack, app_label, SMACK_APP_LABEL_TEMPLATE, path);
823 if (ret != PC_OPERATION_SUCCESS) {
827 return PC_OPERATION_SUCCESS;
830 static int perm_to_smack_early(struct smack_accesses* smack, const char* app_label, app_type_t app_type, const char* perm)
832 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_type=%d, perm=%s",
833 __func__, app_label, app_type, perm);
835 return perm_to_smack_generic(smack, app_label, app_type, perm, 1);
838 static int perm_to_smack(struct smack_accesses* smack, const char* app_label, app_type_t app_type, const char* perm)
840 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_type=%d, perm=%s",
841 __func__, app_label, app_type, perm);
843 return perm_to_smack_generic(smack, app_label, app_type, perm, 0);
846 static int perm_to_dac(const char* app_label, app_type_t app_type, const char* perm)
848 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_type=%d, perm=%s",
849 __func__, app_label, app_type, perm);
852 char* path AUTO_FREE;
853 FILE* file AUTO_FCLOSE;
856 ret = perm_file_path(&path, app_type, perm, ".dac", 0);
857 if (ret != PC_OPERATION_SUCCESS) {
858 C_LOGD("No dac config file for permission %s", perm);
862 SECURE_C_LOGD("Opening file %s.", path);
863 file = fopen(path, "r");
865 C_LOGW("fopen failed.");
866 return PC_OPERATION_SUCCESS;
869 while (fscanf(file, "%d\n", &gid) == 1) {
870 SECURE_C_LOGD("Adding app_id %s to group %d", app_label, gid);
871 ret = add_app_gid(app_label, gid);
872 if (ret != PC_OPERATION_SUCCESS) {
873 C_LOGE("add_app_gid failed");
878 return PC_OPERATION_SUCCESS;
881 static int label_all(const FTSENT* ftsent)
883 SECURE_C_LOGD("Entering function: %s.", __func__);
885 return DECISION_LABEL;
888 static int label_execs(const FTSENT* ftsent)
890 SECURE_C_LOGD("Entering function: %s.", __func__);
892 C_LOGD("Mode = %d", ftsent->fts_statp->st_mode);
893 // label only regular executable files
894 if (S_ISREG(ftsent->fts_statp->st_mode) && (ftsent->fts_statp->st_mode & S_IXUSR))
895 return DECISION_LABEL;
896 return DECISION_SKIP;
899 static int label_dirs(const FTSENT* ftsent)
901 SECURE_C_LOGD("Entering function: %s.", __func__);
903 // label only directories
904 if (S_ISDIR(ftsent->fts_statp->st_mode))
905 return DECISION_LABEL;
906 return DECISION_SKIP;
909 static int label_links_to_execs(const FTSENT* ftsent)
911 SECURE_C_LOGD("Entering function: %s.", __func__);
914 char* target AUTO_FREE;
916 // check if it's a link
917 if ( !S_ISLNK(ftsent->fts_statp->st_mode))
918 return DECISION_SKIP;
920 target = realpath(ftsent->fts_path, NULL);
922 SECURE_C_LOGE("Getting link target for %s failed (Error = %s)", ftsent->fts_path, strerror(errno));
923 return PC_ERR_FILE_OPERATION;
925 if (-1 == stat(target, &buf)) {
926 SECURE_C_LOGE("stat failed for %s (Error = %s", target, strerror(errno));
927 return PC_ERR_FILE_OPERATION;
929 // skip if link target is not a regular executable file
930 if (buf.st_mode != (buf.st_mode | S_IXUSR | S_IFREG)) {
931 SECURE_C_LOGD("%s is not a regular executable file. Skipping.", target);
932 return DECISION_SKIP;
935 return DECISION_LABEL;
938 static int dir_set_smack_r(const char *path, const char* label,
939 enum smack_label_type type, label_decision_fn fn)
941 SECURE_C_LOGD("Entering function: %s. Params: path=%s, label=%s, type=%d",
942 __func__, path, label, type);
944 const char* path_argv[] = {path, NULL};
945 FTS *fts AUTO_FTS_CLOSE;
949 fts = fts_open((char * const *) path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
951 C_LOGE("fts_open failed.");
952 return PC_ERR_FILE_OPERATION;
955 while ((ftsent = fts_read(fts)) != NULL) {
956 /* Check for error (FTS_ERR) or failed stat(2) (FTS_NS) */
957 if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
958 C_LOGE("FTS_ERR error or failed stat(2) (FTS_NS)");
959 return PC_ERR_FILE_OPERATION;
964 C_LOGE("fn(ftsent) failed.");
968 if (ret == DECISION_LABEL) {
969 C_LOGD("smack_lsetlabel (label: %s (type: %d), path: %s)", label, type, ftsent->fts_path);
970 if (smack_lsetlabel(ftsent->fts_path, label, type) != 0) {
971 C_LOGE("smack_lsetlabel failed.");
972 return PC_ERR_FILE_OPERATION;
977 /* If last call to fts_read() set errno, we need to return error. */
979 C_LOGE("Last errno from fts_read: %s", strerror(errno));
980 return PC_ERR_FILE_OPERATION;
982 return PC_OPERATION_SUCCESS;
985 API char* app_id_from_socket(int sockfd)//deprecated
987 SECURE_C_LOGD("Entering function: %s. Params: sockfd=%d",
990 return perm_app_id_from_socket(sockfd);
993 API char* perm_app_id_from_socket(int sockfd)
995 SECURE_C_LOGD("Entering function: %s. Params: sockfd=%d",
999 C_LOGD("No SMACK. Returning NULL.");
1006 ret = smack_new_label_from_socket(sockfd, &app_id);
1008 C_LOGE("smack_new_label_from_socket failed");
1012 SECURE_C_LOGD("app_id = %s", app_id);
1017 static int app_add_rule(const char *app_id, const char *object, const char *perm)
1019 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, object=%s, perm=%s",
1020 __func__, app_id, object, perm);
1024 char *smack_path AUTO_FREE;
1025 struct smack_accesses* smack AUTO_SMACK_FREE;
1027 ret = load_smack_from_file(app_id, &smack, &fd, &smack_path);
1028 if (ret != PC_OPERATION_SUCCESS) {
1029 C_LOGE("load_smack_from_file failed.");
1033 ret = smack_accesses_add_modify(smack, app_id, object, perm, "");
1035 C_LOGE("smack_accesses_add_modify failed.");
1036 return PC_ERR_INVALID_OPERATION;
1039 if (have_smack() && smack_accesses_apply(smack)) {
1040 C_LOGE("smack_accesses_apply failed.");
1041 return PC_ERR_INVALID_OPERATION;
1044 if (smack_accesses_save(smack, fd)) {
1045 C_LOGE("smack_accesses_save failed.");
1046 return PC_ERR_INVALID_OPERATION;
1049 return PC_OPERATION_SUCCESS;
1054 app_register_appsetting(const char *app_id, struct smack_accesses *smack)
1056 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1062 char **label_app_list AUTO_FREE;
1063 char **label_dir_list AUTO_FREE;
1064 int app_list_len = 0;
1065 int dir_list_len = 0;
1067 if (!smack_label_is_valid(app_id)) {
1068 C_LOGE("Invalid param app_id.");
1069 return PC_ERR_INVALID_PARAM;
1072 /* writing appsetting_id (app_id) to "database"*/
1073 ret = add_appsetting_id_to_databse(app_id);
1074 if (ret != PC_OPERATION_SUCCESS)
1078 /* Reading labels of all installed apps from "database"*/
1079 ret = get_all_apps_ids(&label_app_list, &app_list_len);
1080 if (ret != PC_OPERATION_SUCCESS) {
1081 C_LOGE("Error while getting data from database");
1085 /*Add smack rules with rx access to each app*/
1086 for (i = 0; i < app_list_len; ++i) {
1087 C_LOGD("Appsetting: applying rx rule for %s", label_app_list[i]);
1088 if (smack_accesses_add_modify(smack, app_id,
1089 label_app_list[i], "rx", "") == -1) {
1090 C_LOGE("smack_accesses_add_modify failed.");
1091 ret = PC_ERR_INVALID_OPERATION;
1096 /* Reading labels of all registered settings dirs from "database"*/
1097 ret = get_all_settings_dir_ids(
1098 &label_dir_list, &dir_list_len);
1099 if (ret != PC_OPERATION_SUCCESS) {
1100 C_LOGE("Error while getting data from database");
1103 /*Add smack rules with rwx access to each app*/
1104 for (i = 0; i < dir_list_len; ++i) {
1105 C_LOGD("Appsetting: applying rwx rule for %s", label_dir_list[i]);
1106 if (smack_accesses_add_modify(smack, app_id,
1107 label_dir_list[i], "rwx", "") == -1) {
1108 C_LOGE("smack_accesses_add_modify failed.");
1109 ret = PC_ERR_INVALID_OPERATION;
1111 /* Should we abort adding rules if
1112 * smack_accesses_add_modify fails once?*/
1117 for (i = 0; i < app_list_len; ++i) {
1118 free(label_app_list[i]);
1120 for (i = 0; i < dir_list_len; ++i) {
1121 free(label_dir_list[i]);
1127 static int app_register_av_internal(const char *app_av_id, struct smack_accesses* smack)
1129 SECURE_C_LOGD("Entering function: %s. Params: app_av_id=%s.",
1130 __func__, app_av_id);
1135 char** smack_label_app_list AUTO_FREE;
1136 int smack_label_app_list_len = 0;
1138 if (!smack_label_is_valid(app_av_id)) {
1139 C_LOGE("Invalid param app_av_id.");
1140 return PC_ERR_INVALID_PARAM;
1144 C_LOGE("Invalid param smack (NULL).");
1145 return PC_ERR_INVALID_PARAM;
1148 // writing anti_virus_id (app_av_id) to "database"
1149 ret = add_av_id_to_databse(app_av_id);
1150 if (ret != PC_OPERATION_SUCCESS )
1153 // Reading labels of all installed apps from "database"
1154 ret = get_all_apps_ids(&smack_label_app_list, &smack_label_app_list_len);
1155 if (ret != PC_OPERATION_SUCCESS ) {
1156 C_LOGE("Error while geting data from database.");
1159 for (i = 0; i < smack_label_app_list_len; ++i) {
1160 SECURE_C_LOGD("Applying rwx rule for %s", smack_label_app_list[i]);
1161 if (smack_accesses_add_modify(smack, app_av_id, smack_label_app_list[i], "wrx", "") == -1) {
1162 C_LOGE("smack_accesses_add_modify failed.");
1163 ret = PC_ERR_INVALID_OPERATION;
1165 // Should we abort adding rules once smack_accesses_add_modify will fail?
1170 for (i = 0; i < smack_label_app_list_len; ++i) {
1171 free(smack_label_app_list[i]);
1178 * This function will find labels of all anti viruses in database
1179 * and for all of them will add a rule "anti_virus_label app_id rwx".
1180 * This should be called in app_install function.
1182 static int register_app_for_av(const char * app_id)
1184 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s.",
1188 char** smack_label_av_list AUTO_FREE;
1189 int smack_label_av_list_len = 0;
1191 // Reading labels of all installed anti viruses from "database"
1192 ret = get_all_avs_ids(&smack_label_av_list, &smack_label_av_list_len);
1193 if (ret != PC_OPERATION_SUCCESS) {
1194 C_LOGE("Error while geting data from database.");
1198 // for each anti-virus label put rule: "anti_virus_label app_id rwx"
1199 for (i = 0; i < smack_label_av_list_len; ++i) {
1200 SECURE_C_LOGD("Antivirus: app_add_rule (%s, %s rx)", smack_label_av_list[i], app_id);
1201 if (strcmp(app_id, smack_label_av_list[i])==0) {
1202 SECURE_C_LOGW("Trying to add antivirus rule for self. Skipping");
1205 ret = app_add_rule(smack_label_av_list[i], app_id, "wrx");
1206 if (ret != PC_OPERATION_SUCCESS) {
1207 C_LOGE("app_add_rule failed.");
1211 free(smack_label_av_list[i]);
1214 ret = PC_OPERATION_SUCCESS;
1217 // If something failed, then no entry of smack_label_av_list[i]
1218 // was deallocated. They all must be freed.
1219 for(; i<smack_label_av_list_len; ++i) {
1220 free(smack_label_av_list[i]);
1227 * This function will find labels of all setting applications in database
1228 * and for all of them will add a rule "appsetting_id app_id rwx".
1229 * This should be called in app_install function.
1231 static int register_app_for_appsetting(const char *app_id)
1233 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1237 char **smack_label_list AUTO_FREE;
1238 int smack_label_list_len = 0;
1240 /* Reading labels of all installed setting managers from "database"*/
1241 ret = get_all_appsetting_ids(&smack_label_list, &smack_label_list_len);
1242 if (ret != PC_OPERATION_SUCCESS) {
1243 C_LOGE("Error while geting data from database.");
1247 /* for each appsetting put rule: "appsetting_id app_id rx"*/
1248 for (i = 0; i < smack_label_list_len; ++i) {
1249 SECURE_C_LOGD("Appsetting: app_add_rule (%s, %s rx)", smack_label_list[i], app_id);
1250 if (strcmp(app_id, smack_label_list[i])==0) {
1251 SECURE_C_LOGW("Trying to add setting rule for self. Skipping");
1255 ret = app_add_rule(smack_label_list[i], app_id, "rx");
1256 if (ret != PC_OPERATION_SUCCESS) {
1257 C_LOGE("app_add_rule failed");
1261 free(smack_label_list[i]);
1264 ret = PC_OPERATION_SUCCESS;
1267 /* If something failed, then no entry of smack_label_list[i]
1268 was deallocated. They all must be freed.*/
1269 for (; i < smack_label_list_len; ++i) {
1270 free(smack_label_list[i]);
1278 * This function will grant app_id rx access to all public directories and
1279 * files previously designated by app_setup_path(APP_PATH_PUBLIC_RO)
1280 * This should be called in app_install function.
1282 static int register_app_for_public_dirs(const char *app_id, struct smack_accesses *smack)
1284 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1287 char **public_dirs AUTO_FREE;
1288 int public_dirs_cnt = 0;
1290 ret = db_get_public_dirs(&public_dirs, &public_dirs_cnt);
1291 if (ret != PC_OPERATION_SUCCESS) {
1292 C_LOGE("Error while getting data from database");
1296 for (i = 0; i < public_dirs_cnt; ++i) {
1297 SECURE_C_LOGD("Allowing app %s to access public path %s", app_id, public_dirs[i]);
1298 if (smack_accesses_add_modify(smack, app_id, public_dirs[i], "rx", "")) {
1299 C_LOGE("app_add_rule_modify failed");
1300 while (i < public_dirs_cnt)
1301 free(public_dirs[i++]);
1302 return PC_ERR_INVALID_OPERATION;
1304 free(public_dirs[i]);
1307 return PC_OPERATION_SUCCESS;
1310 static int app_add_permissions_internal(const char* app_id, app_type_t app_type, const char** perm_list, int permanent)
1312 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, app_type=%d, permanent=%d",
1313 __func__, app_id, app_type, permanent);
1316 char* smack_path AUTO_FREE;
1317 char* smack_path_early AUTO_FREE;
1319 int fd_early AUTO_CLOSE;
1320 struct smack_accesses *smack AUTO_SMACK_FREE;
1321 struct smack_accesses *smack_early AUTO_SMACK_FREE;
1322 const char* base_perm = NULL;
1324 if (!smack_label_is_valid(app_id)) {
1325 C_LOGE("Invalid param app_id.");
1326 return PC_ERR_INVALID_PARAM;
1329 if(perm_list == NULL) {
1330 C_LOGE("Invalid perm_list (NULL).");
1331 return PC_ERR_INVALID_PARAM;
1334 ret = load_smack_from_file(app_id, &smack, &fd, &smack_path);
1335 if (ret != PC_OPERATION_SUCCESS) {
1336 C_LOGE("load_smack_from_file failed");
1340 ret = load_smack_from_file_early(app_id, &smack_early, &fd_early, &smack_path_early);
1341 if (ret != PC_OPERATION_SUCCESS) {
1342 C_LOGE("load_smack_from_file failed");
1346 /* Implicitly enable base permission for an app_type */
1347 base_perm = app_type_name(app_type);
1349 SECURE_C_LOGD("perm_to_smack params: app_id: %s, %s", app_id, base_perm);
1350 ret = perm_to_smack(smack, app_id, APP_TYPE_OTHER, base_perm);
1351 if (ret != PC_OPERATION_SUCCESS){
1352 C_LOGE("perm_to_smack failed");
1356 // Add early permission - such permissions should be enabled right after system boot
1357 SECURE_C_LOGD("perm_to_smack params: app_id: %s, %s", app_id, base_perm);
1358 ret = perm_to_smack_early(smack_early, app_id, APP_TYPE_OTHER, base_perm);
1359 if (ret != PC_OPERATION_SUCCESS){
1360 C_LOGE("perm_to_smack failed");
1365 for (i = 0; perm_list[i] != NULL; ++i) {
1366 SECURE_C_LOGD("perm_to_smack params: app_id: %s, perm_list[%d]: %s", app_id, i, perm_list[i]);
1367 if (strcmp(perm_list[i], TIZEN_PRIVILEGE_ANTIVIRUS) == 0) {
1368 ret = app_register_av_internal(app_id, smack);
1369 if (ret != PC_OPERATION_SUCCESS) {
1370 C_LOGE("app_register_av_internal failed");
1374 if (strcmp(perm_list[i], TIZEN_PRIVILEGE_APPSETTING) == 0) {
1375 ret = app_register_appsetting(app_id, smack);
1376 if (ret != PC_OPERATION_SUCCESS) {
1377 C_LOGE("app_register_appsetting failed");
1382 ret = perm_to_smack(smack, app_id, app_type, perm_list[i]);
1383 if (ret != PC_OPERATION_SUCCESS){
1384 C_LOGE("perm_to_smack failed");
1388 ret = perm_to_smack_early(smack_early, app_id, app_type, perm_list[i]);
1389 if (ret != PC_OPERATION_SUCCESS){
1390 C_LOGE("perm_to_smack_early failed");
1394 ret = perm_to_dac(app_id, app_type, perm_list[i]);
1395 if (ret != PC_OPERATION_SUCCESS){
1396 C_LOGE("perm_to_dac failed");
1401 if (have_smack() && smack_accesses_apply(smack)) {
1402 C_LOGE("smack_accesses_apply failed");
1403 return PC_ERR_INVALID_OPERATION;
1406 if (have_smack() && smack_accesses_apply(smack_early)) {
1407 C_LOGE("smack_accesses_apply (early) failed");
1408 return PC_ERR_INVALID_OPERATION;
1411 if (permanent && smack_accesses_save(smack, fd)) {
1412 C_LOGE("smack_accesses_save failed");
1413 return PC_ERR_INVALID_OPERATION;
1416 if (permanent && smack_accesses_save(smack_early, fd_early)) {
1417 C_LOGE("smack_accesses_save (early) failed");
1418 return PC_ERR_INVALID_OPERATION;
1421 return PC_OPERATION_SUCCESS;
1424 API int app_add_permissions(const char* app_id, const char** perm_list)//deprecated
1426 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1429 return app_add_permissions_internal(app_id, APP_TYPE_OTHER, perm_list, 1);
1432 API int app_add_volatile_permissions(const char* app_id, const char** perm_list)//deprecated
1434 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1437 return app_add_permissions_internal(app_id, APP_TYPE_OTHER, perm_list, 0);
1440 API int app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)//deprecated
1442 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
1443 __func__, pkg_id, app_type, persistent);
1445 return app_add_permissions_internal(pkg_id, app_type, perm_list, persistent);
1448 API int perm_app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)
1450 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
1451 __func__, pkg_id, app_type, persistent);
1453 return app_add_permissions_internal(pkg_id, app_type, perm_list, persistent);
1456 API int app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)//deprecated
1458 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
1459 __func__, pkg_id, app_type);
1461 return perm_app_disable_permissions(pkg_id, app_type, perm_list);
1464 /* FIXME: this function is only a stub */
1465 API int perm_app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)
1467 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
1468 __func__, pkg_id, app_type);
1470 return PC_OPERATION_SUCCESS;
1473 static int app_revoke_permissions_internal(const char* app_id, bool persistent)
1475 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, persistent=%d",
1476 __func__, app_id, persistent);
1478 char* smack_path AUTO_FREE;
1481 struct smack_accesses *smack AUTO_SMACK_FREE;
1483 if (!smack_label_is_valid(app_id)) {
1484 C_LOGE("Invalid param app_id.");
1485 return PC_ERR_INVALID_PARAM;
1488 ret = load_smack_from_file(app_id, &smack, &fd, &smack_path);
1489 if (ret != PC_OPERATION_SUCCESS) {
1490 C_LOGE("load_smack_from_file failed.");
1494 if (have_smack() && smack_accesses_clear(smack)) {
1495 ret = PC_ERR_INVALID_OPERATION;
1496 C_LOGE("smack_accesses_clear failed.");
1500 if (have_smack() && smack_revoke_subject(app_id)) {
1501 ret = PC_ERR_INVALID_OPERATION;
1502 C_LOGE("smack_revoke_subject failed.");
1506 if (persistent && ftruncate(fd, 0) == -1)
1507 C_LOGW("file truncation failed");
1509 return PC_OPERATION_SUCCESS;
1512 API int app_revoke_permissions(const char* pkg_id)//deprecated
1514 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
1515 return perm_app_revoke_permissions(pkg_id);
1518 API int perm_app_revoke_permissions(const char* pkg_id)
1520 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
1523 if (!smack_label_is_valid(pkg_id)) {
1524 C_LOGE("Invalid param app_id.");
1525 return PC_ERR_INVALID_PARAM;
1528 ret = app_revoke_permissions_internal(pkg_id, true);
1530 C_LOGE("Revoking permissions failed.");
1534 return PC_OPERATION_SUCCESS;
1537 API int app_reset_permissions(const char* pkg_id)//deprecated
1539 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
1542 return perm_app_reset_permissions(pkg_id);
1545 API int perm_app_reset_permissions(const char* pkg_id)
1547 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
1552 if (!smack_label_is_valid(pkg_id)) {
1553 C_LOGE("Invalid param pkg_id.");
1554 return PC_ERR_INVALID_PARAM;
1557 ret = app_revoke_permissions_internal(pkg_id, false);
1559 C_LOGE("Revoking permissions failed.");
1563 /* Add empty permissions set to trigger re-read of rules */
1564 return perm_app_enable_permissions(pkg_id, APP_TYPE_OTHER, (const char*[]){NULL}, 0);
1567 API int app_label_dir(const char* label, const char* path)//deprecated
1569 SECURE_C_LOGD("Entering function: %s. Params: label=%s, path=%s",
1570 __func__, label, path);
1572 int ret = PC_OPERATION_SUCCESS;
1575 C_LOGE("Invalid argument path (NULL).");
1576 return PC_ERR_INVALID_PARAM;
1579 if (!smack_label_is_valid(label)) {
1580 C_LOGE("Invalid param label.");
1581 return PC_ERR_INVALID_PARAM;
1584 //setting access label on everything in given directory and below
1585 ret = dir_set_smack_r(path, label, SMACK_LABEL_ACCESS, &label_all);
1586 if (PC_OPERATION_SUCCESS != ret)
1588 C_LOGE("dir_set_smack_r failed.");
1592 //setting execute label for everything with permission to execute
1593 ret = dir_set_smack_r(path, label, SMACK_LABEL_EXEC, &label_execs);
1594 if (PC_OPERATION_SUCCESS != ret)
1596 C_LOGE("dir_set_smack_r failed.");
1600 //setting execute label for everything with permission to execute
1601 ret = dir_set_smack_r(path, label, SMACK_LABEL_EXEC, &label_links_to_execs);
1605 int smack_get_access_new(const char* subject, const char* object, char** label)
1607 SECURE_C_LOGD("Entering function: %s. Params: subject=%s, object=%s",
1608 __func__, subject, object);
1610 char buff[ACC_LEN] = {'r', 'w', 'x', 'a', 't', 'l'};
1611 char perm[2] = {'-'};
1614 if(!smack_label_is_valid(subject)) {
1615 C_LOGE("Invalid param subject.");
1616 return PC_ERR_INVALID_PARAM;
1619 if(!smack_label_is_valid(object)) {
1620 C_LOGE("Invalid param object.");
1621 return PC_ERR_INVALID_PARAM;
1625 C_LOGE("Invalid param label (NULL).");
1626 return PC_ERR_INVALID_PARAM;
1629 for (i=0; i<ACC_LEN; ++i) {
1631 int ret = smack_have_access(subject, object, perm);
1633 C_LOGE("smack_have_access failed during %c check.", perm[0]);
1634 return PC_ERR_INVALID_OPERATION;
1640 *label = malloc(ACC_LEN+1);
1642 return PC_ERR_MEM_OPERATION;
1644 memcpy(*label, buff, ACC_LEN);
1645 (*label)[ACC_LEN] = 0;
1646 return PC_OPERATION_SUCCESS;
1649 static int app_uninstall_remove_early_rules(const char *app_id)
1651 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
1658 char *data, *data_end;
1659 char *line_begin, *line_end, *write_pos;
1660 char subject[SMACK_LABEL_LEN + 1];
1661 char object[SMACK_LABEL_LEN + 1];
1663 SECURE_C_LOGD("Opening file %s.", SMACK_STARTUP_RULES_FILE);
1664 fd = open(SMACK_STARTUP_RULES_FILE, O_RDWR);
1666 SECURE_C_LOGE("Unable to open file %s: %s", SMACK_STARTUP_RULES_FILE, strerror(errno));
1667 return PC_ERR_FILE_OPERATION;
1670 if (flock(fd, LOCK_EX)) {
1671 SECURE_C_LOGE("flock failed, error %s", strerror(errno));
1672 return PC_ERR_FILE_OPERATION;
1675 size = lseek(fd, 0, SEEK_END);
1677 SECURE_C_LOGE("Unable to read file %s: %s", SMACK_STARTUP_RULES_FILE, strerror(errno));
1678 return PC_ERR_FILE_OPERATION;
1682 return PC_OPERATION_SUCCESS;
1684 data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1685 if (data == MAP_FAILED) {
1686 SECURE_C_LOGE("Unable to read file %s: %s", SMACK_STARTUP_RULES_FILE, strerror(errno));
1687 return PC_ERR_FILE_OPERATION;
1689 data_end = data + size;
1691 line_begin = write_pos = data;
1692 while (line_begin < data_end) {
1693 line_end = memchr(line_begin, '\n', data_end - line_begin);
1694 if (line_end == NULL)
1695 line_end = data_end - 1;
1699 SECURE_C_LOGD("Considering early rule: %s", line_begin);
1701 ret = sscanf(line_begin, "%" TOSTRING(SMACK_LABEL_LEN) "s %" TOSTRING(SMACK_LABEL_LEN) "s", subject, object);
1703 C_LOGD("Rule format is invalid, skipping it.");
1707 if (!strcmp(subject, app_id) || !strcmp(object, app_id)) {
1708 C_LOGD("Rule belongs to an app being removed, skipping it.");
1712 C_LOGD("Rule still needed, keeping it.");
1714 if (write_pos != line_begin)
1715 memcpy(write_pos, line_begin, line_end - line_begin + 1);
1716 write_pos += (line_end - line_begin + 1);
1720 line_begin = line_end + 1;
1724 ret = ftruncate(fd, write_pos - data);
1726 SECURE_C_LOGE("Unable to truncate file %s to %d bytes: %s", SMACK_STARTUP_RULES_FILE, write_pos, strerror(errno));
1728 return PC_ERR_FILE_OPERATION;
1731 return PC_OPERATION_SUCCESS;
1734 API int app_label_shared_dir(const char* app_label, const char* shared_label, const char* path)//deprecated
1736 SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, shared_label=%s, path=%s",
1737 __func__, app_label, shared_label, path);
1741 C_LOGE("Invalid param path.");
1742 return PC_ERR_INVALID_PARAM;
1745 if(!smack_label_is_valid(app_label)) {
1746 C_LOGE("Invalid param app_label");
1747 return PC_ERR_INVALID_PARAM;
1750 if(!smack_label_is_valid(shared_label)) {
1751 C_LOGE("Invalid param shared_label");
1752 return PC_ERR_INVALID_PARAM;
1755 if (strcmp(app_label, shared_label) == 0) {
1756 C_LOGE("app_label equals shared_label");
1757 return PC_ERR_INVALID_PARAM;
1760 //setting label on everything in given directory and below
1761 ret = dir_set_smack_r(path, shared_label, SMACK_LABEL_ACCESS, label_all);
1762 if(ret != PC_OPERATION_SUCCESS){
1763 C_LOGE("dir_set_smack_r failed.");
1767 //setting transmute on dir
1768 ret = dir_set_smack_r(path, "1", SMACK_LABEL_TRANSMUTE, label_dirs);
1769 if (ret != PC_OPERATION_SUCCESS) {
1770 C_LOGE("dir_set_smack_r failed");
1774 ret = app_add_rule(app_label, shared_label, "rwxat");
1775 if (ret != PC_OPERATION_SUCCESS) {
1776 C_LOGE("app_add_rule failed");
1780 return PC_OPERATION_SUCCESS;
1783 API int add_shared_dir_readers(const char* shared_label, const char** app_list)//deprecated
1785 SECURE_C_LOGD("Entering function: %s. Params: shared_label=%s",
1786 __func__, shared_label);
1790 if(app_list == NULL) {
1791 C_LOGE("Invalid param app_list.");
1792 return PC_ERR_INVALID_PARAM;
1795 if (!smack_label_is_valid(shared_label)) {
1796 C_LOGE("Invalid param shared_label.");
1797 return PC_ERR_INVALID_PARAM;
1800 for (i = 0; app_list[i] != NULL; i++) {
1801 if (!smack_label_is_valid(app_list[i])) {
1802 C_LOGE("Invalid %d element from param app_list.", i);
1803 return PC_ERR_INVALID_PARAM;
1806 ret = app_add_rule(app_list[i], shared_label, "rx");
1807 if (ret != PC_OPERATION_SUCCESS) {
1808 C_LOGE("app_add_rule failed.");
1813 return PC_OPERATION_SUCCESS;
1816 static char* smack_label_for_path(const char *app_id, const char *path)
1818 SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, path=%s",
1819 __func__, app_id, path);
1821 char *salt AUTO_FREE;
1825 /* Prefix $1$ causes crypt() to use MD5 function */
1826 if (-1 == asprintf(&salt, "$1$%s", app_id)) {
1827 C_LOGE("asprintf failed");
1831 label = crypt(path, salt);
1832 if (label == NULL) {
1833 C_LOGE("crypt failed");
1837 /* crypt() output may contain slash character,
1838 * which is not legal in Smack labels */
1839 for (x = label; *x; ++x) {
1847 * This function should be called in perm_app_setup_path_internal().
1848 * After installation of new application (pkg_id) and labeling its shared directory (RW or RO),
1849 * all others apps installed on system should get rules to this shared directory.
1850 * This function will add and store those rules in rule-file of new installed app (pkg_id)
1852 static int add_other_apps_rules_for_shared_dir(const char *pkg_id, const char *type_of_shared_dir, const char *shared_dir_label)
1854 C_LOGD("Enter function: %s", __func__);
1858 char *smack_path AUTO_FREE;
1859 char *smack_rules_file_path AUTO_FREE;
1860 struct smack_accesses* smack AUTO_SMACK_FREE;
1862 ret = load_smack_from_file(pkg_id, &smack, &fd, &smack_path);
1863 if (ret != PC_OPERATION_SUCCESS ) {
1864 C_LOGE("load_smack_from_file failed: %d", ret);
1868 ret = asprintf(&smack_rules_file_path, TOSTRING(SHAREDIR)"/%s", type_of_shared_dir);
1870 C_LOGE("asprintf failed");
1871 return PC_ERR_MEM_OPERATION;
1874 ret = perm_to_smack_from_file(smack, shared_dir_label, SMACK_SHARED_DIR_LABEL_TEMPLATE, smack_rules_file_path);
1875 if (ret != PC_OPERATION_SUCCESS ) {
1876 C_LOGE("perm_to_smack_from_file failed: %d", ret);
1879 if (have_smack() && smack_accesses_apply(smack)) {
1880 C_LOGE("smack_accesses_apply failed");
1881 return PC_ERR_INVALID_OPERATION;
1884 if (smack_accesses_save(smack, fd)) {
1885 C_LOGE("smack_accesses_save failed");
1886 return PC_ERR_INVALID_OPERATION;
1889 return PC_OPERATION_SUCCESS;
1892 /* FIXME: remove this pragma once deprecated API is deleted */
1893 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1894 static int perm_app_setup_path_internal(const char* pkg_id, const char* path, app_path_type_t app_path_type, va_list ap)
1896 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
1897 __func__, pkg_id, path, app_path_type);
1900 C_LOGE("Invalid argument path.");
1901 return PC_ERR_INVALID_PARAM;
1904 if (!smack_label_is_valid(pkg_id)) {
1905 C_LOGE("Invalid pkg_id.");
1906 SECURE_C_LOGE("Invalid pkg_id %s", pkg_id);
1907 return PC_ERR_INVALID_PARAM;
1910 switch (app_path_type) {
1911 case APP_PATH_PRIVATE:
1912 C_LOGD("app_path_type is APP_PATH_PRIVATE.");
1913 return app_label_dir(pkg_id, path);
1915 case APP_PATH_GROUP_RW: {
1916 C_LOGD("app_path_type is APP_PATH_GROUP_RW.");
1918 const char *shared_label;
1920 shared_label = va_arg(ap, const char *);
1922 if (!smack_label_is_valid(shared_label)) {
1923 C_LOGE("Invalid shared_label.");
1924 return PC_ERR_INVALID_PARAM;
1927 if (strcmp(pkg_id, shared_label) == 0) {
1928 C_LOGE("pkg_id equals shared_label.");
1929 return PC_ERR_INVALID_PARAM;
1932 ret = app_label_shared_dir(pkg_id, shared_label, path);
1933 if (ret != PC_OPERATION_SUCCESS) {
1934 C_LOGE("app_label_shared_dir failed: %d", ret);
1938 return add_other_apps_rules_for_shared_dir(pkg_id, PATH_RULES_GROUP_RW, shared_label);
1941 case APP_PATH_PUBLIC_RO: {
1942 C_LOGD("app_path_type is APP_PATH_PUBLIC_RO.");
1943 char **app_ids AUTO_FREE;
1944 int app_ids_cnt = 0;
1948 C_LOGD("New public RO path %s", path);
1949 label = smack_label_for_path(pkg_id, path);
1950 if (label == NULL) {
1951 C_LOGE("smack_label_for_path failed.");
1952 return PC_ERR_INVALID_OPERATION;
1955 C_LOGD("Generated label '%s' for public RO path %s", label, path);
1956 ret = app_label_shared_dir(pkg_id, label, path);
1957 if (ret != PC_OPERATION_SUCCESS) {
1958 C_LOGE("app_label_shared_dir failed.");
1962 /* FIXME: This should be in some kind of transaction/lock */
1963 ret = db_add_public_dir(label);
1964 if (ret != PC_OPERATION_SUCCESS) {
1965 C_LOGE("db_add_public_dir failed.");
1969 ret = get_all_apps_ids(&app_ids, &app_ids_cnt);
1970 if (ret != PC_OPERATION_SUCCESS) {
1971 C_LOGE("get_all_aps_ids failed.");
1975 for (i = 0; i < app_ids_cnt; ++i) {
1976 SECURE_C_LOGD("Allowing app %s to access public path %s", app_ids[i], path);
1977 ret = app_add_rule(app_ids[i], label, "rx");
1978 if (ret != PC_OPERATION_SUCCESS) {
1979 C_LOGE("smack_accesses_new failed");
1980 while (i < app_ids_cnt)
1987 return add_other_apps_rules_for_shared_dir(pkg_id, PATH_RULES_PUBLIC_RO, label);
1990 case APP_PATH_SETTINGS_RW:
1992 C_LOGD("app_path_type is APP_PATH_SETTINGS_RW.");
1993 char **app_ids AUTO_FREE;
1994 int app_ids_cnt = 0;
2000 label = smack_label_for_path(pkg_id, path);
2001 if (label == NULL) {
2002 C_LOGE("smack_label_for_path failed.");
2003 return PC_ERR_INVALID_OPERATION;
2006 /*set id for path and all subfolders*/
2007 C_LOGD("Appsetting: generated label '%s' for setting path %s", label, path);
2008 ret = app_label_shared_dir(pkg_id, label, path);
2009 if (ret != PC_OPERATION_SUCCESS) {
2010 C_LOGE("Appsetting: app_label_shared_dir failed (%d)", ret);
2014 /* add path to database */
2015 /* FIXME: This should be in some kind of transaction/lock */
2016 ret = add_setting_dir_id_to_databse(label);
2017 if (ret != PC_OPERATION_SUCCESS) {
2018 C_LOGE("Appsetting: add_setting_dir_id_to_databse failed");
2022 /*read all apps with appsetting privilege*/
2023 ret = get_all_appsetting_ids(&app_ids, &app_ids_cnt);
2024 if (ret != PC_OPERATION_SUCCESS) {
2025 C_LOGE("Appsetting: get_all_appsetting_ids failed");
2028 C_LOGD("Appsetting: %d appsetting privileged apps registered",
2031 /*give RWX rights to all apps that have appsetting privilege*/
2032 for (i = 0; i < app_ids_cnt; ++i) {
2033 C_LOGD("Appsetting: allowing app %s to access setting path %s",
2035 ret = app_add_rule(app_ids[i], label, "rwx");
2036 if (ret != PC_OPERATION_SUCCESS) {
2037 C_LOGE("app_add_rule failed");
2038 while (i < app_ids_cnt)
2045 return PC_OPERATION_SUCCESS;
2048 case APP_PATH_ANY_LABEL: {
2049 C_LOGD("app_path_type is APP_PATH_ANY_LABEL.");
2050 const char *label = NULL;
2051 label = va_arg(ap, const char *);
2052 return app_label_dir(label, path);
2056 C_LOGE("app_path_type is invalid.");
2057 return PC_ERR_INVALID_PARAM;
2060 return PC_OPERATION_SUCCESS;
2062 /* FIXME: remove this pragma once deprecated API is deleted */
2063 #pragma GCC diagnostic warning "-Wdeprecated-declarations"
2065 API int app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)//deprecated
2067 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
2068 __func__, pkg_id, path, app_path_type);
2072 va_start( ap, app_path_type );
2073 ret = perm_app_setup_path_internal( pkg_id, path, app_path_type, ap );
2079 API int perm_app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)
2081 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
2082 __func__, pkg_id, path, app_path_type);
2086 va_start( ap, app_path_type );
2087 ret = perm_app_setup_path_internal( pkg_id, path, app_path_type, ap );
2092 API int app_add_friend(const char* pkg_id1, const char* pkg_id2)//deprecated
2094 SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
2095 __func__, pkg_id1, pkg_id2);
2097 return perm_app_add_friend(pkg_id1, pkg_id2);
2100 API int perm_app_add_friend(const char* pkg_id1, const char* pkg_id2)
2102 SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
2103 __func__, pkg_id1, pkg_id2);
2107 if (!smack_label_is_valid(pkg_id1) || !smack_label_is_valid(pkg_id2)) {
2108 C_LOGE("Invalid pkg_id1 or pkg_id2.");
2109 return PC_ERR_INVALID_PARAM;
2112 ret = app_add_rule(pkg_id1, pkg_id2, "rwxat");
2113 if (ret != PC_OPERATION_SUCCESS) {
2114 C_LOGE("app_add_rule failed");
2118 ret = app_add_rule(pkg_id2, pkg_id1, "rwxat");
2119 if (ret != PC_OPERATION_SUCCESS) {
2120 C_LOGE("app_add_rule failed");
2124 return PC_OPERATION_SUCCESS;
2127 API int app_install(const char* pkg_id)//deprecated
2129 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
2132 return perm_app_install(pkg_id);
2135 API int perm_app_install(const char* pkg_id)
2137 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
2142 char* smack_path AUTO_FREE;
2143 struct smack_accesses *smack AUTO_SMACK_FREE;
2145 if (!smack_label_is_valid(pkg_id)) {
2146 C_LOGE("Invalid param pkg_id.");
2147 return PC_ERR_INVALID_PARAM;
2150 ret = smack_file_name(pkg_id, &smack_path);
2151 if (ret != PC_OPERATION_SUCCESS) {
2152 C_LOGE("smack_file_name failed.");
2156 ret = load_smack_from_file(pkg_id, &smack, &fd, &smack_path);
2157 if (ret != PC_OPERATION_SUCCESS) {
2158 C_LOGE("load_smack_from_file failed");
2162 ret = add_app_id_to_databse(pkg_id);
2163 if (ret != PC_OPERATION_SUCCESS ) {
2164 SECURE_C_LOGE("Error while adding app %s to database: %s ", pkg_id, strerror(errno));
2168 ret = register_app_for_av(pkg_id);
2169 if (ret != PC_OPERATION_SUCCESS) {
2170 SECURE_C_LOGE("Error while adding rules for anti viruses to app %s: %s ", pkg_id, strerror(errno));
2174 ret = register_app_for_appsetting(pkg_id);
2175 if (ret != PC_OPERATION_SUCCESS) {
2176 SECURE_C_LOGE("Error while adding rules for setting managers to app %s: %s ", pkg_id, strerror(errno));
2180 ret = register_app_for_public_dirs(pkg_id, smack);
2181 if (ret != PC_OPERATION_SUCCESS) {
2182 SECURE_C_LOGE("Error while adding rules for access to public dirs for app %s: %s ", pkg_id, strerror(errno));
2186 if (have_smack() && smack_accesses_apply(smack)) {
2187 C_LOGE("smack_accesses_apply failed");
2188 return PC_ERR_INVALID_OPERATION;
2191 if (smack_accesses_save(smack, fd)) {
2192 C_LOGE("smack_accesses_save failed");
2193 return PC_ERR_INVALID_OPERATION;
2196 return PC_OPERATION_SUCCESS;
2199 API int app_uninstall(const char* pkg_id)//deprecated
2201 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
2204 return perm_app_uninstall(pkg_id);
2207 API int perm_app_uninstall(const char* pkg_id)
2209 // TODO: When real database will be used, then this function should remove app_id
2211 // It also should remove rules like: "anti_virus_label app_id rwx".
2212 SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
2213 char* smack_path AUTO_FREE;
2216 if (!smack_label_is_valid(pkg_id)) {
2217 C_LOGE("Invalid param pkg_id.");
2218 return PC_ERR_INVALID_PARAM;
2221 ret = smack_file_name(pkg_id, &smack_path);
2222 if (ret != PC_OPERATION_SUCCESS) {
2223 C_LOGE("smack_file_name failed.");
2227 if (unlink(smack_path)) {
2228 C_LOGE("unlink failed (error: %s)", strerror(errno));
2229 return PC_OPERATION_SUCCESS;
2232 ret = app_uninstall_remove_early_rules(pkg_id);
2233 if (ret != PC_OPERATION_SUCCESS) {
2234 C_LOGE("app_uninstall_remove_early_rules failed.");
2238 return PC_OPERATION_SUCCESS;
2241 static int save_rules(int fd, struct smack_accesses* accesses) {
2242 SECURE_C_LOGD("Entering function: %s. Params: fd=%d", __func__, fd);
2244 if (flock(fd, LOCK_EX)) {
2245 C_LOGE("flock failed (error: %s)", strerror(errno));
2246 return PC_ERR_FILE_OPERATION;
2249 if (smack_accesses_save(accesses, fd)) {
2250 C_LOGE("smack_accesses_save failed");
2251 return PC_ERR_FILE_OPERATION;
2253 return PC_OPERATION_SUCCESS ;
2256 static int validate_and_add_rule(char* rule, struct smack_accesses* accesses) {
2257 SECURE_C_LOGD("Entering function: %s. Params: rule=%s",
2260 const char* subject = NULL;
2261 const char* object = NULL;
2262 const char* access = NULL;
2263 char* saveptr = NULL;
2265 subject = strtok_r(rule, " \t\n", &saveptr);
2266 object = strtok_r(NULL, " \t\n", &saveptr);
2267 access = strtok_r(NULL, " \t\n", &saveptr);
2269 // check rule validity
2270 if (subject == NULL ||
2273 strtok_r(NULL, " \t\n", &saveptr) != NULL ||
2274 !smack_label_is_valid(subject) ||
2275 !smack_label_is_valid(object))
2277 C_LOGE("Incorrect rule format: %s", rule);
2278 return PC_ERR_INVALID_PARAM;
2281 if (smack_accesses_add_modify(accesses, subject, object, access, "")) {
2282 C_LOGE("smack_accesses_add_modify failed");
2283 return PC_ERR_INVALID_OPERATION;
2285 return PC_OPERATION_SUCCESS ;
2288 static int parse_and_save_rules(const char** smack_rules,
2289 struct smack_accesses* accesses, const char* feature_file) {
2290 SECURE_C_LOGD("Entering function: %s. Params: feature_file=%s",
2291 __func__, feature_file);
2295 int ret = PC_OPERATION_SUCCESS;
2298 for (i = 0; smack_rules[i] != NULL ; i++) {
2299 // ignore empty lines
2300 if (strspn(smack_rules[i], " \t\n") == strlen(smack_rules[i]))
2303 tmp = strdup(smack_rules[i]);
2304 ret = validate_and_add_rule(tmp, accesses);
2306 if (ret != PC_OPERATION_SUCCESS )
2311 fd = open(feature_file, O_CREAT | O_WRONLY, 0644);
2313 SECURE_C_LOGE("Unable to create file %s. (error: %s)", feature_file, strerror(errno));
2314 return PC_ERR_FILE_OPERATION;
2317 ret = save_rules(fd, accesses);
2322 static int save_gids(FILE* file, const gid_t* list_of_db_gids, size_t list_size) {
2323 SECURE_C_LOGD("Entering function: %s.", __func__);
2324 int ret = PC_OPERATION_SUCCESS;
2329 C_LOGE("Unable to create file. Error: %s", strerror(errno));
2330 return PC_ERR_FILE_OPERATION; // TODO remove smack accesses?
2333 if(-1 == fchmod(fileno(file), 0644)) {
2334 C_LOGE("Unable to chmod file. Error: %s", strerror(errno));
2335 return PC_ERR_FILE_OPERATION;
2338 for (i = 0; i < list_size ; ++i) {
2339 written = fprintf(file, "%u\n", list_of_db_gids[i]);
2341 C_LOGE("fprintf failed for file. Error: %s", strerror(errno));
2342 ret = PC_ERR_FILE_OPERATION;
2349 API int add_api_feature(app_type_t app_type,
2350 const char* api_feature_name,
2351 const char** smack_rules,
2352 const gid_t* list_of_db_gids,
2353 size_t list_size)//deprecated
2355 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, api_feature_name=%s",
2356 __func__, app_type, api_feature_name);
2358 return perm_add_api_feature(app_type, api_feature_name, smack_rules, list_of_db_gids, list_size);
2361 API int perm_add_api_feature(app_type_t app_type,
2362 const char* api_feature_name,
2363 const char** smack_rules,
2364 const gid_t* list_of_db_gids,
2366 SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, api_feature_name=%s",
2367 __func__, app_type, api_feature_name);
2369 int ret = PC_OPERATION_SUCCESS;
2370 char* smack_file AUTO_FREE;
2371 char* dac_file AUTO_FREE;
2372 struct smack_accesses* accesses = NULL;
2375 // TODO check process capabilities
2377 // get feature SMACK file name
2378 ret = perm_file_path(&smack_file, app_type, api_feature_name, ".smack", 0);
2379 if (ret != PC_OPERATION_SUCCESS || !smack_file ) {
2380 C_LOGE("perm_file_path failed.");
2384 // check if feature exists
2385 if (file_exists(smack_file)) {
2386 C_LOGE("Feature file %s already exists", smack_file);
2387 return PC_ERR_INVALID_PARAM;
2390 // check .dac existence only if gids are supported
2391 if (list_of_db_gids && list_size > 0) {
2392 // get feature DAC file name
2393 ret = perm_file_path(&dac_file, app_type, api_feature_name, ".dac", 0);
2394 if (ret != PC_OPERATION_SUCCESS || !dac_file ) {
2395 C_LOGE("perm_file_path failed.");
2399 // check if feature exists
2400 if (file_exists(dac_file)) {
2401 C_LOGE("Feature file %s already exists", dac_file);
2402 return PC_ERR_INVALID_PARAM;
2406 // parse & save rules
2408 if (smack_accesses_new(&accesses)) {
2409 C_LOGE("smack_acceses_new failed");
2410 return PC_ERR_MEM_OPERATION;
2413 ret = parse_and_save_rules(smack_rules, accesses, smack_file);
2414 smack_accesses_free(accesses);
2417 // go through gid list
2418 if (ret == PC_OPERATION_SUCCESS && list_of_db_gids && list_size > 0) {
2420 SECURE_C_LOGD("Opening file %s.", dac_file);
2421 file = fopen(dac_file, "w+");
2422 ret = save_gids(file, list_of_db_gids, list_size);
2426 // remove both files in case of failure
2427 if (ret != PC_OPERATION_SUCCESS) {
2438 * This function is marked as deprecated and will be removed
2440 API int app_register_av(const char* app_av_id)//deprecated
2442 SECURE_C_LOGD("Entering function: %s. Params: app_av_id=%s",
2443 __func__, app_av_id);
2447 char* smack_path AUTO_FREE;
2448 struct smack_accesses* smack AUTO_SMACK_FREE;
2450 if(app_av_id == NULL) {
2451 C_LOGE("Invalid param app_av_id.");
2452 return PC_ERR_INVALID_PARAM;
2455 ret = load_smack_from_file(app_av_id, &smack, &fd, &smack_path);
2456 if (ret != PC_OPERATION_SUCCESS ) {
2457 C_LOGE("load_smack_from_file failed");
2461 ret = app_register_av_internal(app_av_id, smack);
2462 if (PC_OPERATION_SUCCESS != ret) {
2463 C_LOGE("app_register_av_internal failed");
2467 // Add permisions from OSP_antivirus.smack file
2468 ret = perm_to_smack(smack, app_av_id, APP_TYPE_OSP, TIZEN_PRIVILEGE_ANTIVIRUS);
2469 if (PC_OPERATION_SUCCESS != ret) {
2470 C_LOGE("perm_to_smack failed");
2474 // Add permisions from OSP_antivirus.dac file
2475 ret = perm_to_dac(app_av_id, APP_TYPE_OSP, TIZEN_PRIVILEGE_ANTIVIRUS);
2476 if (ret != PC_OPERATION_SUCCESS) {
2477 C_LOGE("perm_to_dac failed");
2481 if (have_smack() && smack_accesses_apply(smack)) {
2482 C_LOGE("smack_accesses_apply failed");
2483 ret = PC_ERR_INVALID_OPERATION;
2487 if (smack_accesses_save(smack, fd)) {
2488 C_LOGE("smack_accesses_save failed");
2489 ret = PC_ERR_INVALID_OPERATION;