#include <sys/stat.h>
#include <sys/file.h>
#include <sys/smack.h>
+#include <linux/capability.h>
+#include <linux/xattr.h>
+#include <sys/capability.h>
+#include <sys/mman.h>
#include <stdbool.h>
#include <search.h>
#include "privilege-control.h"
#include "access-db.h"
#include "common.h"
+#include "rules-db.h"
#define APP_GID 5000
#define APP_UID 5000
#define APP_HOME_DIR TOSTRING(HOMEDIR) "/app"
#define DEV_HOME_DIR TOSTRING(HOMEDIR) "/developer"
-#define APP_GROUP_PATH TOSTRING(SHAREDIR) "/app_group_list"
-#define DEV_GROUP_PATH TOSTRING(SHAREDIR) "/dev_group_list"
-
-#define SMACK_RULES_DIR "/etc/smack/accesses.d/"
-
-#define SMACK_APP_LABEL_TEMPLATE "~APP~"
-#define SMACK_SRC_FILE_SUFFIX "_src_file"
-#define SMACK_SRC_DIR_SUFFIX "_src_dir"
-#define SMACK_DATA_SUFFIX "_data"
-#define WRT_BASE_DEVCAP "WRT"
-#define WRT_CLIENT_PATH "/usr/bin/wrt-client"
-#define ACC_LEN 5
-#define SMACK_ANTIVIRUS_PERM "antivirus"
-
-static int set_smack_for_wrt(char **smack_label, const char* widget_id);
+/* Macro defined below is used to label links to executables */
+#define XATTR_NAME_TIZENEXEC XATTR_SECURITY_PREFIX "TIZEN_EXEC_LABEL"
typedef struct {
char user_name[10];
int uid;
int gid;
char home_dir[64];
- char group_list[64];
} new_user;
-typedef struct state_node_t {
- char *key, *value;
-} state_node;
-
-static void *state_tree = NULL;
-
-int state_tree_cmp(const void *first, const void *second)
+/**
+ * Return values
+ * <0 - error
+ * 0 - skip
+ * 1 - label
+ */
+typedef int (*label_decision_fn)(const FTSENT*);
+enum {
+ DECISION_SKIP = 0,
+ DECISION_LABEL = 1
+};
+
+__attribute__ ((destructor))
+static void libprivilege_destructor()
{
- return strcmp(((state_node*)first)->key,
- ((state_node*)second)->key);
+ SECURE_C_LOGD("Entering function: %s.", __func__);
+ perm_end();
}
-int state_tree_push(const char* key_param, const char* value_param)
+API int perm_begin(void)
{
- state_node *node = malloc(sizeof(state_node));
- char *key = strdup(key_param);
- char *value = strdup(value_param);
-
- if (!node || !key || !value) {
- free(node);
- free(key);
- free(value);
- return PC_ERR_MEM_OPERATION;
- }
-
- node->key = key;
- node->value = value;
-
- if (NULL != tfind(node, &state_tree, state_tree_cmp)){
- free(node);
- free(key);
- free(value);
- return PC_OPERATION_SUCCESS; // 04.2013 Temporary fix. Allow for multiple call of app_give_access
- }
-
- tsearch(node, &state_tree, state_tree_cmp);
- return PC_OPERATION_SUCCESS;
+ SECURE_C_LOGD("Entering function: %s.", __func__);
+ return rdb_modification_start();
}
-char* state_tree_pop_new(char *key)
+API int perm_end(void)
{
- state_node search, *node;
- void *wtf;
- char *value;
- search.key = key;
- search.value = NULL;
-
- wtf = tfind(&search, &state_tree, state_tree_cmp);
- if (!wtf)
- return NULL;
-
- node = *(state_node**)wtf;
- if (!node)
- return NULL;
-
- tdelete(node, &state_tree, state_tree_cmp);
-
- value = node->value;
- free(node->key);
- free(node);
- return value;
-}
+ SECURE_C_LOGD("Entering function: %s.", __func__);
-int state_save(const char *subject, const char *object, const char *perm)
-{
- char *key = NULL;
- if (-1 == asprintf(&key, "%s|%s", subject, object))
- return PC_ERR_INVALID_OPERATION;
- int ret = state_tree_push(key, perm);
- free(key);
- return ret;
+ return rdb_modification_finish();
}
-int state_restore(const char* subject, const char* object)
+API int perm_rollback(void)
{
- char *key AUTO_FREE;
- char *perm AUTO_FREE;
- struct smack_accesses *smack AUTO_SMACK_FREE;
-
- if (-1 == asprintf(&key, "%s|%s", subject, object))
- return PC_ERR_INVALID_OPERATION;
-
- perm = state_tree_pop_new(key);
- if (!perm)
- return PC_ERR_INVALID_OPERATION;
-
- if (smack_accesses_new(&smack))
- return PC_ERR_MEM_OPERATION;
+ SECURE_C_LOGD("Entering function: %s.", __func__);
- if (smack_accesses_add(smack, subject, object, perm))
- return PC_ERR_MEM_OPERATION;
+ int ret = rdb_modification_rollback();
- if (smack_accesses_apply(smack))
- return PC_ERR_NOT_PERMITTED;
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("RDB %s failed with: %d", __func__, ret);
+ return ret;
+ }
return PC_OPERATION_SUCCESS;
}
-static inline int have_smack(void)
+API int control_privilege(void)//deprecated
{
- static int have_smack = -1;
-
- if (-1 == have_smack) {
- if (NULL == smack_smackfs_path()) {
- C_LOGD("Libprivilage-control: no smack found on phone");
- have_smack = 0;
- } else {
- C_LOGD("Libprivilege-control: found smack on phone");
- have_smack = 1;
- }
- }
+ SECURE_C_LOGD("Entering function: %s.", __func__);
- return have_smack;
-}
-
-API int control_privilege(void)
-{
- C_LOGD("Enter function: %s", __func__);
if(getuid() == APP_UID) // current user is 'app'
return PC_OPERATION_SUCCESS;
- if(set_app_privilege("org.tizen.", NULL, NULL) == PC_OPERATION_SUCCESS)
+ if(perm_app_set_privilege("org.tizen.", NULL, NULL) == PC_OPERATION_SUCCESS)
return PC_OPERATION_SUCCESS;
- else
+ else {
+ C_LOGE("perm_app_set_privilege failed (not permitted).");
return PC_ERR_NOT_PERMITTED;
+ }
}
-
-
static int get_user_groups(uid_t user_id, int *nbgroup, gid_t **groups_list)
{
gid_t *groups = NULL;
static int set_dac(const char *smack_label, const char *pkg_name)
{
- C_LOGD("Enter function: %s", __func__);
+ SECURE_C_LOGD("Entering function: %s. Params: smack_label=%s, pkg_name=%s",
+ __func__, smack_label, pkg_name);
+
uid_t t_uid = -1; // uid of current process
gid_t *glist = NULL; // group list
int glist_cnt = 0; // for group list
/*
* initialize user structure
*/
- C_LOGD("initialize user structure");
+ C_LOGD("Initialize user structure");
memset(usr.user_name, 0x00, 10);
memset(usr.home_dir, 0x00, 64);
- memset(usr.group_list, 0x00, 64);
usr.uid = -1;
usr.gid = -1;
usr.uid = DEVELOPER_UID;
usr.gid = DEVELOPER_GID;
strncpy(usr.home_dir, DEV_HOME_DIR, sizeof(usr.home_dir));
- strncpy(usr.group_list, DEV_GROUP_PATH, sizeof(usr.group_list));
}
else
{
glist_new = (gid_t*)realloc(glist, sizeof(gid_t) * (glist_cnt + cnt));
if (glist_new == NULL) {
result = PC_ERR_MEM_OPERATION; // return -2
- C_LOGE("Cannot allocate memory");
+ C_LOGE("Memory allocation failed");
goto error;
}
glist = glist_new;
*/
C_LOGD("Adding process to the following groups:");
for(i=0; i<glist_cnt; ++i) {
- C_LOGD("glist [ %d ] = %d", i, glist[i]);
+ SECURE_C_LOGD("glist [ %d ] = %d", i, glist[i]);
}
- C_LOGD("setgroups()");
+ C_LOGD("Calling setgroups()");
if(setgroups(glist_cnt, glist) != 0)
{
- C_LOGE("[ERR] setgrouops fail\n");
+ C_LOGE("setgroups failed");
result = PC_ERR_NOT_PERMITTED; // return -3
goto error;
}
C_LOGD("setgid( %d ) & setuid( %d )", usr.gid, usr.uid);
if(setgid(usr.gid) != 0) // fail
{
- C_LOGE("[ERR] fail to execute setgid().");
+ C_LOGE("Failed to execute setgid().");
result = PC_ERR_INVALID_OPERATION;
goto error;
}
if(setuid(usr.uid) != 0) // fail
{
- C_LOGE("[ERR] fail to execute setuid().");
+ C_LOGE("Failed to execute setuid().");
result = PC_ERR_INVALID_OPERATION;
goto error;
}
- C_LOGD("setenv(): USER = %s, HOME = %s", usr.user_name, usr.home_dir);
+ SECURE_C_LOGD("setenv(): USER = %s, HOME = %s", usr.user_name, usr.home_dir);
if(setenv("USER", usr.user_name, 1) != 0) //fail
{
- C_LOGE("[ERR] fail to execute setenv() [USER].");
+ C_LOGE("Failed to execute setenv() [USER].");
result = PC_ERR_INVALID_OPERATION;
goto error;
}
if(setenv("HOME", usr.home_dir, 1) != 0) // fail
{
- C_LOGE("[ERR] fail to execute setenv() [HOME].");
+ C_LOGE("Failed to execute setenv() [HOME].");
result = PC_ERR_INVALID_OPERATION;
goto error;
}
}
else // current user is not only 'root' but 'app'
{
- C_LOGE("[ERR] current user is NOT root\n");
+ C_LOGE("Current user is NOT root");
result = PC_ERR_NOT_PERMITTED; // return -3
goto error;
}
}
/**
- * Set process SMACK label from EXEC label of a file.
- * This function is emulating EXEC label behaviour of SMACK for programs
- * run by dlopen/dlsym instead of execv.
+ * Get SMACK label from EXEC label of a file.
+ * SMACK label should be freed by caller
*
* @param path file path to take label from
* @return PC_OPERATION_SUCCESS on success, PC_ERR_* on error
*/
-static int set_smack_from_binary(char **smack_label, const char* path)
+static int get_smack_from_binary(char **smack_label, const char* path)
{
- C_LOGD("Enter function: %s", __func__);
+ SECURE_C_LOGD("Entering function: %s. Params: path=%s", __func__, path);
+ char value[SMACK_LABEL_LEN + 1];
int ret;
- C_LOGD("Path: %s", path);
+ /* First try: check SMACKEXEC label on binary */
+ ret = getxattr(path, XATTR_NAME_SMACKEXEC, value, SMACK_LABEL_LEN + 1);
+ if (ret > 0)
+ goto finalize;
+ if (errno != ENODATA)
+ goto error;
+
+ /* Second try: check TIZENEXEC label on binary */
+ ret = getxattr(path, XATTR_NAME_TIZENEXEC, value, SMACK_LABEL_LEN + 1);
+ if (ret > 0)
+ goto finalize;
+ if (errno != ENODATA)
+ goto error;
+
+ /* Third try: check TIZENEXEC label on symbolic link */
+ ret = lgetxattr(path, XATTR_NAME_TIZENEXEC, value, SMACK_LABEL_LEN + 1);
+ if (ret > 0)
+ goto finalize;
+ if (errno != ENODATA)
+ goto error;
+ /* None of labels found return NULL*/
*smack_label = NULL;
- ret = smack_getlabel(path, smack_label, SMACK_LABEL_EXEC);
- if (ret != 0) {
- C_LOGE("Getting exec label from file %s failed", path);
- return PC_ERR_INVALID_OPERATION;
- }
+ return PC_OPERATION_SUCCESS;
+finalize:
+ /* Success! */
+ value[ret] = '\0'; /* because getxattr does not add 0 at the end! */
+ *smack_label = strdup(value);
if (*smack_label == NULL) {
+ C_LOGE("Cannot allocate memory for smack_label");
+ return PC_ERR_MEM_OPERATION;
+ }
+ return PC_OPERATION_SUCCESS;
+
+error:
+ C_LOGE("Getting exec label from file %s failed", path);
+ return PC_ERR_INVALID_OPERATION;
+}
+
+/**
+ * Set process SMACK label.
+ * This function is emulating EXEC label behavior of SMACK for programs
+ * run by dlopen/dlsym instead of execv.
+ *
+ * @param smack label
+ * @return PC_OPERATION_SUCCESS on success, PC_ERR_* on error
+ */
+static int set_smack_for_self (char *smack_label)
+{
+ SECURE_C_LOGD("Entering function: %s. Params: smack_label=%s",
+ __func__, smack_label);
+ int ret;
+
+ if (smack_label == NULL) {
/* No label to set, just return with success */
- C_LOGD("No label to set, just return with success");
+ C_LOGD("No label to set, just return with success.");
ret = PC_OPERATION_SUCCESS;
}
else {
- C_LOGD("label = %s", *smack_label);
+ SECURE_C_LOGD("smack_label=%s", smack_label);
if (have_smack()) {
- ret = smack_set_label_for_self(*smack_label);
+ ret = smack_set_label_for_self(smack_label);
C_LOGD("smack_set_label_for_self returned %d", ret);
} else
ret = PC_OPERATION_SUCCESS;
return ret;
}
-static int is_widget(const char* path)
+API int set_app_privilege(const char* name, const char* type, const char* path)//deprecated
{
- C_LOGD("Enter function: %s", __func__);
- char buf[sizeof(WRT_CLIENT_PATH)];
- int ret;
+ SECURE_C_LOGD("Entering function: %s. Params: name=%s, type=%s, path=%s",
+ __func__, name, type, path);
- ret = readlink(path, buf, sizeof(WRT_CLIENT_PATH));
- if (ret == -1)
- C_LOGD("readlink(%s) returned error: %s. Assuming that app is not a widget", path, strerror(errno));
- else if (ret == sizeof(WRT_CLIENT_PATH))
- C_LOGD("%s is not a widget", path);
- if (ret == -1 || ret == sizeof(WRT_CLIENT_PATH))
- return 0;
- buf[ret] = '\0';
- C_LOGD("buf = %s", buf);
-
- ret = !strcmp(WRT_CLIENT_PATH, buf);
- C_LOGD("%s is %s widget", path, ret ? "a" : "not a");
- return (ret);
+ return perm_app_set_privilege(name, type, path);
}
-/**
- * Partially verify, that the type given for app is correct.
- * This function will use some heuristics to check whether the app type is right.
- * It is intended for security hardening to catch privilege setting for the
- * app type not corresponding to the actual binary.
- * Beware - when it detects an anomaly, the whole process will be terminated.
- *
- * @param type claimed application type
- * @param path file path to executable
- * @return return void on success, terminate the process on error
- */
-static app_type_t verify_app_type(const char* type, const char* path)
-{
- C_LOGD("Enter function: %s", __func__);
- /* TODO: this should actually be treated as error, but until the old
- * set_privilege API is removed, it must be ignored */
- if (path == NULL) {
- C_LOGD("PKG_TYPE_OTHER");
- return APP_TYPE_OTHER; /* good */
- }
-
- if (is_widget(path)) {
- if (!strcmp(type, "wgt")) {
- C_LOGD("PKG_TYPE_WGT");
- return APP_TYPE_WGT; /* good */
- }
- } else {
- if (type == NULL || strcmp(type, "wgt")){
- C_LOGD("PKG_TYPE_OTHER");
- return APP_TYPE_OTHER; /* good */
- }
- }
-
- /* bad */
- C_LOGE("EXIT_FAILURE");
- exit(EXIT_FAILURE);
-}
-/*
-static const char* parse_widget_id(const char* path)
+API int perm_app_set_privilege(const char* name, const char* type UNUSED, const char* path)
{
- C_LOGD("Enter function: %s", __func__);
- const char* basename = strrchr(path, '/');
+ SECURE_C_LOGD("Entering function: %s. Params: name=%s, type=%s, path=%s",
+ __func__, name, type, path);
- if (basename == NULL)
- basename = path;
- else
- ++basename;
-
- C_LOGD("return widget id: %s", basename);
- return basename;
-}*/
+ //SECURE_C_LOGD("Function params: name = %s, type = %s, path = %s", name, type, path);
+ int ret = PC_OPERATION_SUCCESS;
+ char *smack_label AUTO_FREE;
-API int perm_app_set_privilege(const char* name, const char* type, const char* path)
-{
- return PC_ERR_INVALID_OPERATION;
-}
+ if (name == NULL) {
+ C_LOGE("Error invalid parameter");
+ return PC_ERR_INVALID_PARAM;
+ }
-API int set_app_privilege(const char* name, const char* type, const char* path)
-{
- C_LOGD("Enter function: %s", __func__);
- C_LOGD("Function params: name = %s, type = %s, path = %s", name, type, path);
- const char* widget_id;
- char *smack_label AUTO_FREE;
- int ret = PC_OPERATION_SUCCESS;
+ if (path != NULL && have_smack()) {
+ ret = get_smack_from_binary(&smack_label, path);
+ if (ret != PC_OPERATION_SUCCESS)
+ return ret;
- switch(verify_app_type(type, path)) {
- case APP_TYPE_WGT:
- //widget_id = parse_widget_id(path);
- widget_id = name;
- if (widget_id == NULL) {
- C_LOGE("PC_ERR_INVALID_PARAM");
- ret = PC_ERR_INVALID_PARAM;
- }
- else
- {
- smack_label = strdup(widget_id);
- ret = set_smack_from_binary(&smack_label, path);
- }
- break;
- default:
- if (path != NULL)
- ret = set_smack_from_binary(&smack_label, path);
- break;
+ ret = set_smack_for_self(smack_label);
+ if (ret != PC_OPERATION_SUCCESS)
+ return ret;
}
- if (ret != PC_OPERATION_SUCCESS)
- return ret;
+ if (path != NULL && !have_smack()) {
+ ret = get_smack_from_binary(&smack_label, path);
+ if (ret != PC_OPERATION_SUCCESS)
+ return ret;
+ }
return set_dac(smack_label, name);
}
-API int set_privilege(const char* pkg_name)
+API int set_privilege(const char* pkg_name)//deprecated
{
- C_LOGD("Enter function: %s", __func__);
- return set_app_privilege(pkg_name, NULL, NULL);
-}
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_name=%s",
+ __func__, pkg_name);
-static inline const char* app_type_name(app_type_t app_type)
-{
- switch (app_type) {
- case APP_TYPE_WGT:
- return "WRT";
- case APP_TYPE_OSP:
- return "OSP";
- default:
- return NULL;
- }
+ return perm_app_set_privilege(pkg_name, NULL, NULL);
}
-static int perm_file_path(char** path, app_type_t app_type, const char* perm, const char *suffix)
+static int perm_file_path(char** path, app_type_t app_type, const char* perm, const char *suffix, bool is_early)
{
+ SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, perm=%s, suffix=%s, is_early=%d",
+ __func__, app_type, perm, suffix, is_early);
+
const char* app_type_prefix = NULL;
- const char* perm_basename = NULL;
+ char* perm_basename = NULL;
int ret = 0;
if (perm == NULL || strlen(perm) == 0) {
- C_LOGE("empty permission name");
+ C_LOGE("Empty permission name.");
return PC_ERR_INVALID_PARAM;
}
- app_type_prefix = app_type_name(app_type);
-
- perm_basename = strrchr(perm, '/');
- if (perm_basename)
- ++perm_basename;
- else
- perm_basename = perm;
-
- ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s",
- app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
- perm_basename, suffix);
- if (ret == -1) {
- C_LOGE("asprintf failed");
- return PC_ERR_MEM_OPERATION;
- }
-
- return PC_OPERATION_SUCCESS;
-}
-
-static bool file_exists(const char* path) {
- FILE* file = fopen(path, "r");
- if (file) {
- fclose(file);
- return true;
- }
- return false;
-}
-
-static int perm_to_smack(struct smack_accesses* smack, const char* app_label, app_type_t app_type, const char* perm)
-{
- C_LOGD("Enter function: %s", __func__);
- int ret;
- char* path AUTO_FREE;
- char* format_string AUTO_FREE;
- FILE* file AUTO_FCLOSE;
- char smack_subject[SMACK_LABEL_LEN + 1];
- char smack_object[SMACK_LABEL_LEN + 1];
- char smack_accesses[10];
+ app_type_prefix = app_type_group_name(app_type);
- // get file name for permission (devcap)
- ret = perm_file_path(&path, app_type, perm, ".smack");
+ ret = base_name_from_perm(perm, &perm_basename);
if (ret != PC_OPERATION_SUCCESS) {
- C_LOGD("No smack config file for permission %s", perm);
+ C_LOGE("Couldn't get permission basename.");
return ret;
}
- if (asprintf(&format_string,"%%%ds %%%ds %%%lus\n",
- SMACK_LABEL_LEN, SMACK_LABEL_LEN, (unsigned long)sizeof(smack_accesses)) == -1) {
- C_LOGE("asprintf failed");
- return PC_ERR_MEM_OPERATION;
+ if (is_early) {
+ ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s%s",
+ app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
+ perm_basename, "_early", suffix);
}
-
- file = fopen(path, "r");
- C_LOGD("path = %s", path);
- if (file == NULL) {
- C_LOGE("fopen failed");
- return PC_OPERATION_SUCCESS;
+ else {
+ ret = asprintf(path, TOSTRING(SHAREDIR) "/%s%s%s%s",
+ app_type_prefix ? app_type_prefix : "", app_type_prefix ? "_" : "",
+ perm_basename, suffix);
}
-
- while (fscanf(file, format_string, smack_subject, smack_object, smack_accesses) == 3) {
- if (!strcmp(smack_subject, SMACK_APP_LABEL_TEMPLATE))
- strcpy(smack_subject, app_label);
-
- if (!strcmp(smack_object, SMACK_APP_LABEL_TEMPLATE))
- strcpy(smack_object, app_label);
-
- C_LOGD("smack_accesses_add_modify (subject: %s, object: %s, access: %s)", smack_subject, smack_object, smack_accesses);
- if (smack_accesses_add_modify(smack, smack_subject, smack_object, smack_accesses, "") != 0) {
- C_LOGE("smack_accesses_add_modify failed");
- return PC_ERR_INVALID_OPERATION;
- }
+ if (ret == -1) {
+ C_LOGE("asprintf failed.");
+ return PC_ERR_MEM_OPERATION;
}
+ C_LOGD("Path=%s", *path);
+
return PC_OPERATION_SUCCESS;
}
static int perm_to_dac(const char* app_label, app_type_t app_type, const char* perm)
{
- C_LOGD("Enter function: %s", __func__);
+ SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, app_type=%d, perm=%s",
+ __func__, app_label, app_type, perm);
+
int ret;
char* path AUTO_FREE;
FILE* file AUTO_FCLOSE;
int gid;
- ret = perm_file_path(&path, app_type, perm, ".dac");
+ ret = perm_file_path(&path, app_type, perm, ".dac", 0);
if (ret != PC_OPERATION_SUCCESS) {
C_LOGD("No dac config file for permission %s", perm);
return ret;
}
+ SECURE_C_LOGD("Opening file %s.", path);
file = fopen(path, "r");
- C_LOGD("path = %s", path);
if (file == NULL) {
- C_LOGE("fopen failed");
+ C_LOGW("fopen failed.");
return PC_OPERATION_SUCCESS;
}
while (fscanf(file, "%d\n", &gid) == 1) {
- C_LOGD("Adding app_id %s to group %d", app_label, gid);
+ SECURE_C_LOGD("Adding app_id %s to group %d", app_label, gid);
ret = add_app_gid(app_label, gid);
if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("sadd_app_gid failed");
+ C_LOGE("add_app_gid failed");
return ret;
}
}
return PC_OPERATION_SUCCESS;
}
+static int label_all(const FTSENT* ftsent UNUSED)
+{
+ SECURE_C_LOGD("Entering function: %s.", __func__);
+
+ return DECISION_LABEL;
+}
+
+static int label_execs(const FTSENT* ftsent)
+{
+ SECURE_C_LOGD("Entering function: %s.", __func__);
+
+ C_LOGD("Mode = %d", ftsent->fts_statp->st_mode);
+ // label only regular executable files
+ if (S_ISREG(ftsent->fts_statp->st_mode) && (ftsent->fts_statp->st_mode & S_IXUSR))
+ return DECISION_LABEL;
+ return DECISION_SKIP;
+}
+
+static int label_dirs(const FTSENT* ftsent)
+{
+ SECURE_C_LOGD("Entering function: %s.", __func__);
+
+ // label only directories
+ if (S_ISDIR(ftsent->fts_statp->st_mode))
+ return DECISION_LABEL;
+ return DECISION_SKIP;
+}
+
+static int label_links_to_execs(const FTSENT* ftsent)
+{
+ SECURE_C_LOGD("Entering function: %s.", __func__);
+
+ struct stat buf;
+ char* target AUTO_FREE;
+
+ // check if it's a link
+ if ( !S_ISLNK(ftsent->fts_statp->st_mode))
+ return DECISION_SKIP;
+
+ target = realpath(ftsent->fts_path, NULL);
+ if (!target) {
+ SECURE_C_LOGE("Getting link target for %s failed (Error = %s)", ftsent->fts_path, strerror(errno));
+ return PC_ERR_FILE_OPERATION;
+ }
+ if (-1 == stat(target, &buf)) {
+ SECURE_C_LOGE("stat failed for %s (Error = %s", target, strerror(errno));
+ return PC_ERR_FILE_OPERATION;
+ }
+ // skip if link target is not a regular executable file
+ if (buf.st_mode != (buf.st_mode | S_IXUSR | S_IFREG)) {
+ SECURE_C_LOGD("%s is not a regular executable file. Skipping.", target);
+ return DECISION_SKIP;
+ }
+
+ return DECISION_LABEL;
+}
+
static int dir_set_smack_r(const char *path, const char* label,
- enum smack_label_type type, mode_t type_mask)
+ const char *xattr_name, label_decision_fn fn)
{
- C_LOGD("Enter function: %s", __func__);
- int ret;
+ SECURE_C_LOGD("Entering function: %s. Params: path=%s, label=%s, xattr_name=%s",
+ __func__, path, label, xattr_name);
+
const char* path_argv[] = {path, NULL};
- FTS *fts = NULL;
+ FTS *fts AUTO_FTS_CLOSE;
FTSENT *ftsent;
+ int ret;
- ret = PC_ERR_FILE_OPERATION;
+ int len = strnlen(label, SMACK_LABEL_LEN + 1);
+ if (len > SMACK_LABEL_LEN) {
+ C_LOGE("parameter \"label\" is to long.");
+ return PC_ERR_INVALID_PARAM;
+ }
fts = fts_open((char * const *) path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
if (fts == NULL) {
- C_LOGE("fts_open failed");
- goto out;
+ C_LOGE("fts_open failed.");
+ return PC_ERR_FILE_OPERATION;
}
while ((ftsent = fts_read(fts)) != NULL) {
/* Check for error (FTS_ERR) or failed stat(2) (FTS_NS) */
if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
C_LOGE("FTS_ERR error or failed stat(2) (FTS_NS)");
- goto out;
+ return PC_ERR_FILE_OPERATION;
+ }
+
+ ret = fn(ftsent);
+ if (ret < 0) {
+ C_LOGE("fn(ftsent) failed.");
+ return ret;
}
- if (ftsent->fts_statp->st_mode & type_mask) {
- C_LOGD("smack_lsetlabel (label: %s (type: %d), path: %s)", label, type, ftsent->fts_path);
- if (smack_lsetlabel(ftsent->fts_path, label, type) != 0) {
- C_LOGE("smack_lsetlabel failed");
- goto out;
+ if (ret == DECISION_LABEL) {
+ C_LOGD("lsetxattr (path: %s, xattr_name: %s, label: %s len: %d, 0",
+ ftsent->fts_path, xattr_name, label, len);
+
+ if (lsetxattr(ftsent->fts_path, xattr_name, label, len, 0) != 0) {
+ C_LOGE("lsetxattr failed.");
+ return PC_ERR_FILE_OPERATION;
}
}
}
/* If last call to fts_read() set errno, we need to return error. */
- if (errno == 0)
- ret = PC_OPERATION_SUCCESS;
- else
- C_LOGE("Last errno: %s", strerror(errno));
-
-out:
- if (fts != NULL)
- fts_close(fts);
- return ret;
+ if (errno != 0) {
+ C_LOGE("Last errno from fts_read: %s", strerror(errno));
+ return PC_ERR_FILE_OPERATION;
+ }
+ return PC_OPERATION_SUCCESS;
}
-
-static int set_smack_for_wrt(char **smack_label, const char* widget_id)
+API char* app_id_from_socket(int sockfd)//deprecated
{
- C_LOGD("Enter function: %s", __func__);
-
- *smack_label = strdup(widget_id);
- if (smack_label == NULL)
- return PC_ERR_MEM_OPERATION;
+ SECURE_C_LOGD("Entering function: %s. Params: sockfd=%d",
+ __func__, sockfd);
- if (!have_smack())
- return PC_OPERATION_SUCCESS;
-/*
- int ret;
- ret = app_reset_permissions(widget_id);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("app_reset_permissions failed");
- return ret;
- }
-*/
- if (smack_set_label_for_self(widget_id) != 0) {
- C_LOGE("smack_set_label_for_self failed");
- return PC_ERR_INVALID_OPERATION;
- }
- return PC_OPERATION_SUCCESS;
+ return perm_app_id_from_socket(sockfd);
}
API char* perm_app_id_from_socket(int sockfd)
{
- return NULL;
-}
+ SECURE_C_LOGD("Entering function: %s. Params: sockfd=%d",
+ __func__, sockfd);
-API char* app_id_from_socket(int sockfd)
-{
- C_LOGD("Enter function: %s", __func__);
- if (!have_smack())
+ if (!have_smack()) {
+ C_LOGD("No SMACK. Returning NULL.");
return NULL;
+ }
char* app_id;
int ret;
ret = smack_new_label_from_socket(sockfd, &app_id);
- if (ret != 0) {
+ if (ret < 0) {
C_LOGE("smack_new_label_from_socket failed");
return NULL;
}
- C_LOGD("app_id: %s", app_id);
+ SECURE_C_LOGD("app_id = %s", app_id);
return app_id;
}
-static int smack_file_name(const char* app_id, char** path)
+
+API int app_add_permissions(const char* app_id, const char** perm_list)//deprecated
{
- if (asprintf(path, SMACK_RULES_DIR "/%s", app_id) == -1) {
- C_LOGE("asprintf failed");
- *path = NULL;
- return PC_ERR_MEM_OPERATION;
- }
+ SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
+ __func__, app_id);
- return PC_OPERATION_SUCCESS;
+ return perm_app_enable_permissions(app_id, APP_TYPE_OTHER, perm_list, true);
}
-static int load_smack_from_file(const char* app_id, struct smack_accesses** smack, int *fd, char** path)
+API int app_add_volatile_permissions(const char* app_id, const char** perm_list)//deprecated
{
- C_LOGD("Enter function: %s", __func__);
- int ret;
+ SECURE_C_LOGD("Entering function: %s. Params: app_id=%s",
+ __func__, app_id);
- ret = smack_file_name(app_id, path);
- if (ret != PC_OPERATION_SUCCESS)
- return ret;
+ return perm_app_enable_permissions(app_id, APP_TYPE_OTHER, perm_list, false);
+}
- if (smack_accesses_new(smack)) {
- C_LOGE("smack_accesses_new failed");
- return PC_ERR_MEM_OPERATION;
- }
+API int app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)//deprecated
+{
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
+ __func__, pkg_id, app_type, persistent);
- *fd = open(*path, O_CREAT|O_RDWR, 0644);
- if (*fd == -1) {
- C_LOGE("file open failed: %s", strerror(errno));
- return PC_ERR_FILE_OPERATION;
- }
+ return perm_app_enable_permissions(pkg_id, app_type, perm_list, persistent);
+}
- if (flock(*fd, LOCK_EX)) {
- C_LOGE("flock failed");
- return PC_ERR_INVALID_OPERATION;
- }
+API int perm_app_enable_permissions(const char* pkg_id, app_type_t app_type,
+ const char** perm_list, bool persistent)
+{
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d, persistent=%d",
+ __func__, pkg_id, app_type, persistent);
- if (smack_accesses_add_from_file(*smack, *fd)) {
- C_LOGE("smack_accesses_add_from_file failed");
- return PC_ERR_INVALID_OPERATION;
+ int i, ret;
+ const char *app_label AUTO_FREE;
+
+ if (!smack_label_is_valid(pkg_id)) {
+ C_LOGE("Invalid param app_id.");
+ return PC_ERR_INVALID_PARAM;
}
- /* Rewind the file */
- if (lseek(*fd, 0, SEEK_SET) == -1) {
- C_LOGE("lseek failed");
- return PC_ERR_FILE_OPERATION;
+ if (perm_list == NULL) {
+ C_LOGE("Invalid perm_list (NULL).");
+ return PC_ERR_INVALID_PARAM;
}
- return PC_OPERATION_SUCCESS;
-}
+ if (app_type_group_name(app_type) == NULL) {
+ C_LOGE("Unknown app type.");
+ return PC_ERR_INVALID_PARAM;
+ }
-/**
- * This function will check in database labels of all anti viruses
- * and for all anti viruses will add a rule "anti_virus_label app_id rwx".
- * This should be call in app_install function.
- */
-static int register_app_for_av(const char * app_id)
-{
- int ret, i;
- char** smack_label_av_list AUTO_FREE;
- int smack_label_av_list_len = 0;
- struct smack_accesses* smack AUTO_SMACK_FREE;
+ app_label = generate_app_label(pkg_id);
+ if (app_label == NULL) {
+ C_LOGE("generate_app_label returned NULL.");
+ return PC_ERR_MEM_OPERATION;
+ }
- ret = smack_accesses_new(&smack);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("smack_accesses_new failed");
- return ret;
+ /* Add permission to DAC */
+ for (i = 0; perm_list[i] != NULL; ++i) {
+ ret = perm_to_dac(pkg_id, app_type, perm_list[i]);
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("perm_to_dac failed");
+ return ret;
+ }
}
- // Reading labels of all installed anti viruses from "database"
- ret = get_all_avs_ids(&smack_label_av_list, &smack_label_av_list_len);
+ /* Enable the permissions: */
+ ret = rdb_enable_app_permissions(app_label, app_type, perm_list,
+ !((bool)persistent));
if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("Error while geting data from database");
+ C_LOGE("RDB rdb_enable_app_permissions failed with: %d", ret);
return ret;
}
- // for each anti-virus put rule: "anti_virus_id app_id rwx"
- for (i = 0; i < smack_label_av_list_len; ++i) {
- int fd AUTO_CLOSE;
- char* smack_path AUTO_FREE;
- C_LOGD("Adding rwx rule for antivirus: %s", smack_label_av_list[i]);
+ return PC_OPERATION_SUCCESS;
+}
- ret = load_smack_from_file(smack_label_av_list[i], &smack, &fd, &smack_path);
- if (ret != PC_OPERATION_SUCCESS ) {
- C_LOGE("load_smack_from_file failed");
- goto out;
- }
+API int app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)//deprecated
+{
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
+ __func__, pkg_id, app_type);
- if (smack_accesses_add(smack, smack_label_av_list[i], app_id, "wrx") == -1) {
- C_LOGE("smack_accesses_add failed");
- ret = PC_ERR_INVALID_OPERATION;
- goto out; // Should we abort adding rules if once smack_accesses_add will fail?
- }
+ return perm_app_disable_permissions(pkg_id, app_type, perm_list);
+}
- if (have_smack() && smack_accesses_apply(smack)) {
- C_LOGE("smack_accesses_apply failed");
- ret = PC_ERR_INVALID_OPERATION;
- goto out;
- }
-
- if (smack_accesses_save(smack, fd)) {
- C_LOGE("smack_accesses_save failed");
- ret = PC_ERR_INVALID_OPERATION;
- goto out;
- }
- // Clearing char* smack_label_av_list[i] got from database.
- free(smack_label_av_list[i]);
- }
-
- ret = PC_OPERATION_SUCCESS;
-
-out:
- // If something failed, then no all char* smack_label_av_list[i]
- // are deallocated. They must be freed
- for(; i<smack_label_av_list_len; ++i) {
- free(smack_label_av_list[i]);
- }
-
- return ret;
-}
-
-static int app_add_permissions_internal(const char* app_id, app_type_t app_type, const char** perm_list, int permanent)
+API int perm_app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)
{
- C_LOGD("Enter function: %s", __func__);
- char* smack_path AUTO_FREE;
- int i, ret;
- int fd AUTO_CLOSE;
- struct smack_accesses *smack AUTO_SMACK_FREE;
- const char* base_perm = NULL;
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, app_type=%d",
+ __func__, pkg_id, app_type);
- if (!smack_label_is_valid(app_id))
+ int ret;
+ const char *app_label AUTO_FREE;
+ if (!smack_label_is_valid(pkg_id)) {
+ C_LOGE("Invalid param app_id.");
return PC_ERR_INVALID_PARAM;
-
- ret = load_smack_from_file(app_id, &smack, &fd, &smack_path);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("load_smack_from_file failed");
- return ret;
}
- /* Implicitly enable base permission for an app_type */
- base_perm = app_type_name(app_type);
- if (base_perm) {
- C_LOGD("perm_to_smack params: app_id: %s, %s", app_id, base_perm);
- ret = perm_to_smack(smack, app_id, APP_TYPE_OTHER, base_perm);
- if (ret != PC_OPERATION_SUCCESS){
- C_LOGE("perm_to_smack failed");
- return ret;
- }
+ if (perm_list == NULL) {
+ C_LOGE("Invalid perm_list (NULL).");
+ return PC_ERR_INVALID_PARAM;
}
- for (i = 0; perm_list[i] != NULL; ++i) {
- C_LOGD("perm_to_smack params: app_id: %s, perm_list[%d]: %s", app_id, i, perm_list[i]);
- ret = perm_to_smack(smack, app_id, app_type, perm_list[i]);
- if (ret != PC_OPERATION_SUCCESS){
- C_LOGE("perm_to_smack failed");
- return ret;
- }
- ret = perm_to_dac(app_id, app_type, perm_list[i]);
- if (ret != PC_OPERATION_SUCCESS){
- C_LOGE("perm_to_dac failed");
- return ret;
- }
+ if (app_type_group_name(app_type) == NULL) {
+ C_LOGE("Unknown app type.");
+ return PC_ERR_INVALID_PARAM;
}
- if (have_smack() && smack_accesses_apply(smack)) {
- C_LOGE("smack_accesses_apply failed");
- return PC_ERR_INVALID_OPERATION;
+ app_label = generate_app_label(pkg_id);
+ if (app_label == NULL) {
+ C_LOGE("generate_app_label returned NULL.");
+ return PC_ERR_MEM_OPERATION;
}
- if (permanent && smack_accesses_save(smack, fd)) {
- C_LOGE("smack_accesses_save failed");
- return PC_ERR_INVALID_OPERATION;
+ ret = rdb_disable_app_permissions(app_label, app_type, perm_list);
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
+ return ret;
}
return PC_OPERATION_SUCCESS;
}
-API int app_add_permissions(const char* app_id, const char** perm_list)
-{
- C_LOGD("Enter function: %s", __func__);
- return app_add_permissions_internal(app_id, APP_TYPE_OTHER, perm_list, 1);
-}
-
-API int app_add_volatile_permissions(const char* app_id, const char** perm_list)
+API int app_revoke_permissions(const char* pkg_id)//deprecated
{
- C_LOGD("Enter function: %s", __func__);
- return app_add_permissions_internal(app_id, APP_TYPE_OTHER, perm_list, 0);
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
+ return perm_app_revoke_permissions(pkg_id);
}
-API int app_enable_permissions(const char* app_id, app_type_t app_type, const char** perm_list, bool persistent)
-{
- C_LOGD("Enter function: %s", __func__);
- return app_add_permissions_internal(app_id, app_type, perm_list, persistent);
-}
-
-API int perm_app_enable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list, bool persistent)
-{
- C_LOGD("Enter function: %s", __func__);
- return PC_ERR_INVALID_OPERATION;
-}
-
-/* FIXME: this function is only a stub */
-API int perm_app_disable_permissions(const char* pkg_id, app_type_t app_type, const char** perm_list)
-{
- return PC_ERR_INVALID_OPERATION;
-}
-
-API int app_disable_permissions(const char* app_id, app_type_t app_type, const char** perm_list)
-{
- C_LOGD("Enter function: %s", __func__);
- return PC_OPERATION_SUCCESS;
-}
-
-static int app_revoke_permissions_internal(const char* app_id, bool persistent)
+API int perm_app_revoke_permissions(const char* pkg_id)
{
- C_LOGD("Enter function: %s", __func__);
- char* smack_path AUTO_FREE;
- int ret;
- int fd AUTO_CLOSE;
- struct smack_accesses *smack AUTO_SMACK_FREE;
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
+ /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
+ /*int ret;
+ const char *app_label AUTO_FREE;*/
- if (!smack_label_is_valid(app_id))
+ if (!smack_label_is_valid(pkg_id)) {
+ C_LOGE("Invalid param app_id.");
return PC_ERR_INVALID_PARAM;
-
- ret = load_smack_from_file(app_id, &smack, &fd, &smack_path);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("load_smack_from_file failed");
- return ret;
}
- if (have_smack() && smack_accesses_clear(smack)) {
- ret = PC_ERR_INVALID_OPERATION;
- C_LOGE("smack_accesses_clear failed");
- return ret;
+ SECURE_C_LOGD("This function is currently only a stub. Returning PC_OPERATION_SUCCESS.");
+ /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
+ /*app_label = generate_app_label(pkg_id);
+ if (app_label == NULL) {
+ C_LOGE("generate_app_label returned NULL.");
+ return PC_ERR_MEM_OPERATION;
}
- if (have_smack() && smack_revoke_subject(app_id)) {
- ret = PC_ERR_INVALID_OPERATION;
- C_LOGE("smack_revoke_subject failed");
+ ret = rdb_revoke_app_permissions(app_label);
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
return ret;
- }
-
- if (persistent && ftruncate(fd, 0) == -1)
- C_LOGE("file truncate failed");
+ }*/
return PC_OPERATION_SUCCESS;
}
-API int perm_app_revoke_permissions(const char* pkg_id)
+API int app_reset_permissions(const char* pkg_id)//deprecated
{
- return PC_ERR_INVALID_OPERATION;
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
+ __func__, pkg_id);
+
+ return perm_app_reset_permissions(pkg_id);
}
-API int app_revoke_permissions(const char* app_id)
+API int perm_app_reset_permissions(const char* pkg_id)
{
- C_LOGD("Enter function: %s", __func__);
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
+ __func__, pkg_id);
int ret;
+ const char *app_label AUTO_FREE;
- if (!smack_label_is_valid(app_id))
+ if (!smack_label_is_valid(pkg_id)) {
+ C_LOGE("Invalid param pkg_id.");
return PC_ERR_INVALID_PARAM;
+ }
- ret = app_revoke_permissions_internal(app_id, true);
- if (ret) {
- C_LOGE("Revoking permissions failed");
+ app_label = generate_app_label(pkg_id);
+ if (app_label == NULL) {
+ C_LOGE("generate_app_label returned NULL.");
+ return PC_ERR_MEM_OPERATION;
+ }
+
+ ret = rdb_reset_app_permissions(app_label);
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("RDB rdb_disable_app_permissions failed with: %d", ret);
return ret;
}
return PC_OPERATION_SUCCESS;
}
-API int perm_app_reset_permissions(const char* pkg_id)
+API int app_label_dir(const char* label, const char* path)//deprecated
{
- return PC_ERR_INVALID_OPERATION;
-}
+ SECURE_C_LOGD("Entering function: %s. Params: label=%s, path=%s",
+ __func__, label, path);
-API int app_reset_permissions(const char* app_id)
-{
- C_LOGD("Enter function: %s", __func__);
- int ret;
+ int ret = PC_OPERATION_SUCCESS;
- if (!smack_label_is_valid(app_id))
+ if(path == NULL) {
+ C_LOGE("Invalid argument path (NULL).");
return PC_ERR_INVALID_PARAM;
-
- ret = app_revoke_permissions_internal(app_id, false);
- if (ret) {
- C_LOGE("Revoking permissions failed");
- return ret;
}
- /* Add empty permissions set to trigger re-read of rules */
- return app_enable_permissions(app_id, APP_TYPE_OTHER, (const char*[]){NULL}, 0);
-}
-
-API int app_label_dir(const char* label, const char* path)
-{
- C_LOGD("Enter function: %s", __func__);
-
- int ret = PC_OPERATION_SUCCESS;
-
- if (!smack_label_is_valid(label))
+ if (!smack_label_is_valid(label)) {
+ C_LOGE("Invalid param label.");
return PC_ERR_INVALID_PARAM;
+ }
//setting access label on everything in given directory and below
- ret = dir_set_smack_r(path, label, SMACK_LABEL_ACCESS, ~0);
+ ret = dir_set_smack_r(path, label, XATTR_NAME_SMACK, &label_all);
if (PC_OPERATION_SUCCESS != ret)
+ {
+ C_LOGE("dir_set_smack_r failed.");
return ret;
+ }
//setting execute label for everything with permission to execute
- ret = dir_set_smack_r(path, label, SMACK_LABEL_EXEC, S_IXUSR);
+ ret = dir_set_smack_r(path, label, XATTR_NAME_SMACKEXEC, &label_execs);
if (PC_OPERATION_SUCCESS != ret)
+ {
+ C_LOGE("dir_set_smack_r failed.");
return ret;
+ }
- //removing execute label from directories
- ret = dir_set_smack_r(path, "", SMACK_LABEL_EXEC, S_IFMT & ~S_IFREG);
-
+ //setting execute label for everything with permission to execute
+ ret = dir_set_smack_r(path, label, XATTR_NAME_TIZENEXEC, &label_links_to_execs);
return ret;
}
-int smack_get_access_new(const char* subject, const char* object, char** label)
+API int app_label_shared_dir(const char* app_label, const char* shared_label, const char* path)//deprecated
{
- char buff[ACC_LEN] = {'r', 'w', 'x', 'a', 't'};
- char perm[2] = {'-'};
- int i;
+ SECURE_C_LOGD("Entering function: %s. Params: app_label=%s, shared_label=%s, path=%s",
+ __func__, app_label, shared_label, path);
+ int ret;
- if(!smack_label_is_valid(subject) || !smack_label_is_valid(object) || !label)
+ if(path == NULL) {
+ C_LOGE("Invalid param path.");
return PC_ERR_INVALID_PARAM;
-
- for (i=0; i<ACC_LEN; ++i) {
- perm[0] = buff[i];
- int ret = smack_have_access(subject, object, perm);
- if (-1 == ret)
- return PC_ERR_INVALID_OPERATION;
- if (0 == ret)
- buff[i] = '-';
}
- *label = malloc(ACC_LEN+1);
- if (NULL == *label)
- return PC_ERR_MEM_OPERATION;
-
- memcpy(*label, buff, ACC_LEN);
- (*label)[ACC_LEN] = 0;
- return PC_OPERATION_SUCCESS;
-}
-
-/*
- * This function will be used to allow direct communication between 2 OSP application.
- * This function requires to store "state" with list of added label.
- *
- * Full implementation requires some kind of database. This implemetation works without
- * database so you wont be able to revoke permissions added by different process.
- */
-API int app_give_access(const char* subject, const char* object, const char* permissions)
-{
- C_LOGD("Enter function: %s", __func__);
- int ret = PC_OPERATION_SUCCESS;
- struct smack_accesses *smack AUTO_SMACK_FREE;
- static const char * const revoke = "-----";
- char *current_permissions AUTO_FREE;
+ if(!smack_label_is_valid(app_label)) {
+ C_LOGE("Invalid param app_label");
+ return PC_ERR_INVALID_PARAM;
+ }
- if (!have_smack())
- return PC_OPERATION_SUCCESS;
+ if(!smack_label_is_valid(shared_label)) {
+ C_LOGE("Invalid param shared_label");
+ return PC_ERR_INVALID_PARAM;
+ }
- if (!smack_label_is_valid(subject) || !smack_label_is_valid(object))
+ if (strcmp(app_label, shared_label) == 0) {
+ C_LOGE("app_label equals shared_label");
return PC_ERR_INVALID_PARAM;
+ }
- if (PC_OPERATION_SUCCESS != (ret = smack_get_access_new(subject, object, ¤t_permissions)))
+ //setting label on everything in given directory and below
+ ret = dir_set_smack_r(path, shared_label, XATTR_NAME_SMACK, label_all);
+ if(ret != PC_OPERATION_SUCCESS){
+ C_LOGE("dir_set_smack_r failed.");
return ret;
+ }
- if (smack_accesses_new(&smack))
- return PC_ERR_MEM_OPERATION;
-
- if (smack_accesses_add_modify(smack, subject, object, permissions, revoke))
- return PC_ERR_MEM_OPERATION;
-
- if (smack_accesses_apply(smack))
- return PC_ERR_NOT_PERMITTED;
-
- ret = state_save(subject, object, current_permissions);
+ //setting transmute on dir
+ ret = dir_set_smack_r(path, "TRUE", XATTR_NAME_SMACKTRANSMUTE, label_dirs);
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("dir_set_smack_r failed");
+ return ret;
+ }
- return ret;
+ return PC_OPERATION_SUCCESS;
}
-/*
- * This function will be used to revoke direct communication between 2 OSP application.
- *
- * Full implementation requires some kind of database. This implemetation works without
- * database so you wont be able to revoke permissions added by different process.
- */
-API int app_revoke_access(const char* subject, const char* object)
+API int add_shared_dir_readers(const char* shared_label UNUSED, const char** app_list UNUSED)//deprecated
{
- C_LOGD("Enter function: %s", __func__);
- if (!have_smack())
- return PC_OPERATION_SUCCESS;
+ SECURE_C_LOGD("Entering function: %s. Params: shared_label=%s",
+ __func__, shared_label);
- if (!smack_label_is_valid(subject) || !smack_label_is_valid(object))
- return PC_ERR_INVALID_PARAM;
+ C_LOGE("add_shared_dir_readers is deprecated and unimplemented!");
- return state_restore(subject, object);
+ // TODO: This function is not implemented with RDB.
+ return PC_ERR_INVALID_OPERATION;
}
-API int app_label_shared_dir(const char* app_label, const char* shared_label, const char* path)
+static char* smack_label_for_path(const char *app_id, const char *path)
{
- C_LOGD("Enter function: %s", __func__);
- char* smack_path AUTO_FREE;
- int ret;
- int fd AUTO_CLOSE;
- struct smack_accesses *smack AUTO_SMACK_FREE;
+ SECURE_C_LOGD("Entering function: %s. Params: app_id=%s, path=%s",
+ __func__, app_id, path);
- if (!smack_label_is_valid(app_label) || !smack_label_is_valid(shared_label))
- return PC_ERR_INVALID_PARAM;
+ char *salt AUTO_FREE;
+ char *label;
+ char *x;
- if (strcmp(app_label, shared_label) == 0) {
- C_LOGE("app_label equals shared_label");
- return PC_ERR_INVALID_PARAM;
+ /* Prefix $1$ causes crypt() to use MD5 function */
+ if (-1 == asprintf(&salt, "$1$%s", app_id)) {
+ C_LOGE("asprintf failed");
+ return NULL;
}
- //setting label on everything in given directory and below
- ret = dir_set_smack_r(path, shared_label, SMACK_LABEL_ACCESS, ~0);
- if(ret != PC_OPERATION_SUCCESS){
- C_LOGE("dir_set_smakc_r failed");
- return ret;
+ label = crypt(path, salt);
+ if (label == NULL) {
+ C_LOGE("crypt failed");
+ return NULL;
}
- //setting transmute on dir
- ret = dir_set_smack_r(path, "1", SMACK_LABEL_TRANSMUTE, S_IFDIR);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("dir_set_smakc_r failed");
- return ret;
+ /* crypt() output may contain slash character,
+ * which is not legal in Smack labels */
+ for (x = label; *x; ++x) {
+ if (*x == '/')
+ *x = '%';
}
- ret = load_smack_from_file(app_label, &smack, &fd, &smack_path);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("load_smack_from_file failed");
- return ret;
- }
+ return label;
+}
- //setting access rule for application
- if (smack_accesses_add(smack, app_label,shared_label, "wrxat") == -1) {
- C_LOGE("smack_accesses_add failed");
- return ret;
+/* FIXME: remove this pragma once deprecated API is deleted */
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+static int perm_app_setup_path_internal(const char* pkg_id, const char* path, app_path_type_t app_path_type, va_list ap)
+{
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
+ __func__, pkg_id, path, app_path_type);
+ const char *app_label AUTO_FREE;
+
+ if(path == NULL) {
+ C_LOGE("Invalid argument path.");
+ return PC_ERR_INVALID_PARAM;
}
- if (have_smack() && smack_accesses_apply(smack)) {
- C_LOGE("smack_accesses_apply failed");
- return PC_ERR_INVALID_OPERATION;
+ if (!smack_label_is_valid(pkg_id)) {
+ C_LOGE("Invalid pkg_id.");
+ SECURE_C_LOGE("Invalid pkg_id %s", pkg_id);
+ return PC_ERR_INVALID_PARAM;
}
- if (smack_accesses_save(smack, fd)) {
- C_LOGE("smack_accesses_save failed");
- return PC_ERR_INVALID_OPERATION;
+ app_label = generate_app_label(pkg_id);
+ if (app_label == NULL) {
+ C_LOGE("generate_app_label returned NULL.");
+ return PC_ERR_MEM_OPERATION;
}
- return PC_OPERATION_SUCCESS;
-}
+ switch (app_path_type) {
+ case APP_PATH_PRIVATE:
+ C_LOGD("app_path_type is APP_PATH_PRIVATE.");
+ return app_label_dir(app_label, path);
-API int add_shared_dir_readers(const char* shared_label, const char** app_list)
-{
- C_LOGD("Enter function: %s", __func__);
- int ret = PC_ERR_INVALID_PARAM;
- int i;
- int fd AUTO_CLOSE;
+ case APP_PATH_GROUP_RW: {
+ C_LOGD("app_path_type is APP_PATH_GROUP.");
+ int ret;
+ const char *shared_label;
- if (!smack_label_is_valid(shared_label))
- return PC_ERR_INVALID_PARAM;
+ shared_label = va_arg(ap, const char *);
- for (i = 0; app_list[i] != NULL; i++) {
- char *smack_path AUTO_FREE;
- struct smack_accesses *smack AUTO_SMACK_FREE;
+ if (!smack_label_is_valid(shared_label)) {
+ C_LOGE("Invalid shared_label.");
+ return PC_ERR_INVALID_PARAM;
+ }
- if (!smack_label_is_valid(app_list[i]))
- return PC_ERR_INVALID_PARAM;
+ if (strcmp(app_label, shared_label) == 0) {
+ C_LOGE("app_label equals shared_label.");
+ return PC_ERR_INVALID_PARAM;
+ }
- ret = load_smack_from_file(
- app_list[i], &smack, &fd, &smack_path);
+ ret = app_label_shared_dir(app_label, shared_label, path);
if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("load_smack_from_file failed");
+ C_LOGE("app_label_shared_dir failed: %d", ret);
return ret;
}
- if (smack_accesses_add_modify(smack, app_list[i], shared_label,
- "rx", "") == -1) {
- C_LOGE("smack_accesses_add failed");
- return PC_ERR_INVALID_OPERATION;
+
+ // Add the path to the database:
+ ret = rdb_add_path(app_label, shared_label, path, "rwxatl", "-", "GROUP_PATH");
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("RDB rdb_add_path failed with: %d", ret);
+ return ret;
}
- if (have_smack() && smack_accesses_apply(smack)) {
- C_LOGE("smack_accesses_apply failed");
+
+ return PC_OPERATION_SUCCESS;
+ }
+
+ case APP_PATH_PUBLIC_RO: {
+ C_LOGD("app_path_type is APP_PATH_PUBLIC.");
+ const char *label;
+ int ret;
+
+ C_LOGD("New public RO path %s", path);
+
+ // Generate label:
+ label = smack_label_for_path(app_label, path);
+ if (label == NULL) {
+ C_LOGE("smack_label_for_path failed.");
return PC_ERR_INVALID_OPERATION;
}
- if (smack_accesses_save(smack, fd)) {
- C_LOGE("smack_accesses_save failed");
- return PC_ERR_INVALID_OPERATION;
+ C_LOGD("Generated label '%s' for public RO path %s", label, path);
+
+ ret = app_label_shared_dir(app_label, label, path);
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("app_label_shared_dir failed.");
+ return ret;
}
- }
- return PC_OPERATION_SUCCESS;
-}
+ // Add the path to the database:
+ ret = rdb_add_path(app_label, label, path, "rwxatl", "-", "PUBLIC_PATH");
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("RDB rdb_add_path failed with: %d", ret);
+ return ret;
+ }
-API int perm_app_add_friend(const char* pkg_id1, const char* pkg_id2)
-{
- return PC_ERR_INVALID_OPERATION;
-}
+ return PC_OPERATION_SUCCESS;
+ }
-API int app_add_friend(const char* app_id1, const char* app_id2)
-{
- C_LOGD("Enter function: %s", __func__);
- int ret;
- int fd1 AUTO_CLOSE;
- int fd2 AUTO_CLOSE;
- char* smack_path1 AUTO_FREE;
- char* smack_path2 AUTO_FREE;
- struct smack_accesses* smack1 AUTO_SMACK_FREE;
- struct smack_accesses* smack2 AUTO_SMACK_FREE;
-
- if (!smack_label_is_valid(app_id1) || !smack_label_is_valid(app_id2))
- return PC_ERR_INVALID_PARAM;
+ case APP_PATH_SETTINGS_RW: {
+ C_LOGD("app_path_type is APP_PATH_SETTINGS.");
+ const char *label;
+ int ret;
- ret = load_smack_from_file(app_id1, &smack1, &fd1, &smack_path1);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("load_smack_from_file failed");
- return ret;
- }
+ // Generate label:
+ label = smack_label_for_path(app_label, path);
+ if (label == NULL) {
+ C_LOGE("smack_label_for_path failed.");
+ return PC_ERR_INVALID_OPERATION;
+ }
+ C_LOGD("Appsetting: generated label '%s' for setting path %s", label, path);
- ret = load_smack_from_file(app_id2, &smack2, &fd2, &smack_path2);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("load_smack_from_file failed");
- return ret;
- }
+ /*set id for path and all subfolders*/
+ ret = app_label_shared_dir(app_label, label, path);
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("Appsetting: app_label_shared_dir failed (%d)", ret);
+ return ret;
+ }
- if (smack_accesses_add(smack1, app_id1, app_id2, "wrxat") == -1 ||
- (smack_accesses_add(smack2, app_id2, app_id1, "wrxat") == -1)) {
- C_LOGE("smack_accesses_add failed");
- return ret;
+ // Add the path to the database:
+ ret = rdb_add_path(app_label, label, path, "rwxatl", "-", "SETTINGS_PATH");
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("RDB rdb_add_path failed with: %d", ret);
+ return ret;
+ }
+
+ return PC_OPERATION_SUCCESS;
}
- if (have_smack() &&
- (smack_accesses_apply(smack1) || smack_accesses_apply(smack2))) {
- C_LOGE("smack_accesses_apply failed");
- return PC_ERR_INVALID_OPERATION;
+ case APP_PATH_ANY_LABEL: {
+ C_LOGD("app_path_type is APP_PATH_ANY_LABEL.");
+ const char *label = NULL;
+ label = va_arg(ap, const char *);
+ return app_label_dir(label, path);
}
- if (smack_accesses_save(smack1, fd1) || smack_accesses_save(smack2, fd2)) {
- C_LOGE("smack_accesses_save failed");
- return PC_ERR_INVALID_OPERATION;
+ default:
+ C_LOGE("app_path_type is invalid.");
+ return PC_ERR_INVALID_PARAM;
}
return PC_OPERATION_SUCCESS;
}
+/* FIXME: remove this pragma once deprecated API is deleted */
+#pragma GCC diagnostic warning "-Wdeprecated-declarations"
-API int perm_app_install(const char* pkg_id)
+API int app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)//deprecated
{
- return PC_ERR_INVALID_OPERATION;
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
+ __func__, pkg_id, path, app_path_type);
+
+ va_list ap;
+ int ret;
+ va_start( ap, app_path_type );
+ ret = perm_app_setup_path_internal( pkg_id, path, app_path_type, ap );
+ va_end( ap );
+ return ret;
}
-API int app_install(const char* app_id)
+API int perm_app_setup_path(const char* pkg_id, const char* path, app_path_type_t app_path_type, ...)
{
- C_LOGD("Enter function: %s", __func__);
- int ret;
- int fd AUTO_CLOSE;
- char* smack_path AUTO_FREE;
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s, path=%s, app_path_type=%d",
+ __func__, pkg_id, path, app_path_type);
- if (!smack_label_is_valid(app_id))
- return PC_ERR_INVALID_PARAM;
+ va_list ap;
+ int ret;
+ va_start( ap, app_path_type );
+ ret = perm_app_setup_path_internal( pkg_id, path, app_path_type, ap );
+ va_end( ap );
+ return ret;
+}
- ret = smack_file_name(app_id, &smack_path);
- if (ret != PC_OPERATION_SUCCESS)
- return ret;
+API int app_add_friend(const char* pkg_id1, const char* pkg_id2)//deprecated
+{
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
+ __func__, pkg_id1, pkg_id2);
- fd = open(smack_path, O_RDWR|O_CREAT, 0644);
- if (fd == -1) {
- C_LOGE("file open failed: %s", strerror(errno));
- return PC_ERR_FILE_OPERATION;
- }
+ return perm_app_add_friend(pkg_id1, pkg_id2);
+}
- ret = add_app_id_to_databse(app_id);
- if (ret != PC_OPERATION_SUCCESS ) {
- C_LOGE("Error while adding app %s to database: %s ", app_id, strerror(errno));
- return ret;
- }
+API int perm_app_add_friend(const char* pkg_id1 UNUSED, const char* pkg_id2 UNUSED)
+{
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id1=%s, pkg_id2=%s",
+ __func__, pkg_id1, pkg_id2);
- ret = register_app_for_av(app_id);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("Error while adding rules for anti viruses to app %s: %s ", app_id, strerror(errno));
- return ret;
- }
+ C_LOGE("app_register_av is deprecated and unimplemented!");
- return PC_OPERATION_SUCCESS;
+ // TODO: This function is not implemented with RDB.
+ return PC_ERR_INVALID_OPERATION;
}
-API int perm_app_uninstall(const char* pkg_id)
+API int app_install(const char* pkg_id)//deprecated
{
- return PC_ERR_INVALID_OPERATION;
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
+ __func__, pkg_id);
+
+ return perm_app_install(pkg_id);
}
-API int app_uninstall(const char* app_id)
+API int perm_app_install(const char* pkg_id)
{
- // TODO: When real database will be used, then this function should remove app_id
- // from database.
- // It also should remove rules looks like: "anti_virus_label app_id rwx".
- C_LOGD("Enter function: %s", __func__);
- char* smack_path AUTO_FREE;
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
+ __func__, pkg_id);
int ret;
+ const char *app_label AUTO_FREE;
- if (!smack_label_is_valid(app_id))
+ if (!smack_label_is_valid(pkg_id)) {
+ C_LOGE("Invalid param pkg_id.");
return PC_ERR_INVALID_PARAM;
+ }
- ret = smack_file_name(app_id, &smack_path);
- if (ret != PC_OPERATION_SUCCESS)
- return ret;
+ app_label = generate_app_label(pkg_id);
+ if (app_label == NULL) {
+ C_LOGE("generate_app_label returned NULL.");
+ return PC_ERR_MEM_OPERATION;
+ }
- if (unlink(smack_path)) {
- C_LOGE("unlink failed: ", strerror(errno));
-// return PC_ERR_INVALID_OPERATION;
- return PC_OPERATION_SUCCESS;
+ // Add application to the database:
+ ret = rdb_add_application(app_label);
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("RDB rdb_add_application failed with: %d", ret);
+ return ret;
}
return PC_OPERATION_SUCCESS;
}
-static int save_rules(int fd, struct smack_accesses* accesses) {
- if (flock(fd, LOCK_EX)) {
- C_LOGE("flock failed, error %s", strerror(errno));
- return PC_ERR_FILE_OPERATION;
- }
+API int app_uninstall(const char* pkg_id)//deprecated
+{
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s",
+ __func__, pkg_id);
- if (smack_accesses_save(accesses, fd)) {
- C_LOGE("smack_accesses_save failed");
- return PC_ERR_FILE_OPERATION;
- }
- return PC_OPERATION_SUCCESS ;
+ return perm_app_uninstall(pkg_id);
}
-static int validate_and_add_rule(char* rule, struct smack_accesses* accesses) {
- const char* subject = NULL;
- const char* object = NULL;
- const char* access = NULL;
- char* saveptr = NULL;
-
- subject = strtok_r(rule, " \t\n", &saveptr);
- object = strtok_r(NULL, " \t\n", &saveptr);
- access = strtok_r(NULL, " \t\n", &saveptr);
-
- // check rule validity
- if (subject == NULL ||
- object == NULL ||
- access == NULL ||
- strtok_r(NULL, " \t\n", &saveptr) != NULL ||
- !smack_label_is_valid(subject) ||
- !smack_label_is_valid(object))
- {
- C_LOGE("Incorrect rule format: %s", rule);
- return PC_ERR_INVALID_PARAM;
- }
+API int perm_app_uninstall(const char* pkg_id)
+{
+ SECURE_C_LOGD("Entering function: %s. Params: pkg_id=%s", __func__, pkg_id);
+ /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
+ /*int ret;
+ const char *app_label AUTO_FREE;*/
- if (smack_accesses_add(accesses, subject, object, access)) {
- C_LOGE("smack_accesses_add failed");
- return PC_ERR_INVALID_OPERATION;
+ if (!smack_label_is_valid(pkg_id)) {
+ C_LOGE("Invalid param pkg_id.");
+ return PC_ERR_INVALID_PARAM;
}
- return PC_OPERATION_SUCCESS ;
-}
-
-static int parse_and_save_rules(const char** smack_rules,
- struct smack_accesses* accesses, const char* feature_file) {
- size_t i = 0;
- int fd = 0;
- int ret = PC_OPERATION_SUCCESS;
- char* tmp = NULL;
- for (i = 0; smack_rules[i] != NULL ; i++) {
- // ignore empty lines
- if (strspn(smack_rules[i], " \t\n") == strlen(smack_rules[i]))
- continue;
-
- tmp = strdup(smack_rules[i]);
- ret = validate_and_add_rule(tmp, accesses);
- free(tmp);
- if (ret != PC_OPERATION_SUCCESS )
- return ret;
+ SECURE_C_LOGD("This function is currently only a stub. Returning PC_OPERATION_SUCCESS.");
+ /* TODO Please uncomment this when db is prepared for single "User" label for all apps */
+ /*app_label = generate_app_label(pkg_id);
+ if (app_label == NULL) {
+ C_LOGE("generate_app_label returned NULL.");
+ return PC_ERR_MEM_OPERATION;
}
- // save to file
- fd = open(feature_file, O_CREAT | O_WRONLY, 0644);
- if (fd == -1) {
- C_LOGE("Unable to create file %s. Error: %s", feature_file, strerror(errno));
- return PC_ERR_FILE_OPERATION;
- }
+ // Remove application from the database
+ ret = rdb_remove_application(app_label);
+ if (ret != PC_OPERATION_SUCCESS) {
+ C_LOGE("RDB rdb_remove_application failed with: %d", ret);
+ return ret;
+ }*/
- ret = save_rules(fd, accesses);
- close(fd);
- return ret;
+ return PC_OPERATION_SUCCESS;
}
static int save_gids(FILE* file, const gid_t* list_of_db_gids, size_t list_size) {
+
+ SECURE_C_LOGD("Entering function: %s.", __func__);
int ret = PC_OPERATION_SUCCESS;
int written = 0;
size_t i = 0;
return ret;
}
-API int perm_add_api_feature(app_type_t app_type,
- const char* api_feature_name,
- const char** smack_rules,
- const gid_t* list_of_db_gids,
- size_t list_size)
+API int add_api_feature(app_type_t app_type,
+ const char* api_feature_name,
+ const char** smack_rules,
+ const gid_t* list_of_db_gids,
+ size_t list_size)//deprecated
{
- return PC_ERR_INVALID_OPERATION;
+ SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, api_feature_name=%s",
+ __func__, app_type, api_feature_name);
+
+ return perm_add_api_feature(app_type, api_feature_name, smack_rules, list_of_db_gids, list_size);
}
-API int add_api_feature(app_type_t app_type,
+API int perm_add_api_feature(app_type_t app_type,
const char* api_feature_name,
const char** smack_rules,
const gid_t* list_of_db_gids,
size_t list_size) {
- C_LOGD("Enter function: %s", __func__);
+ SECURE_C_LOGD("Entering function: %s. Params: app_type=%d, api_feature_name=%s",
+ __func__, app_type, api_feature_name);
int ret = PC_OPERATION_SUCCESS;
- char* smack_file AUTO_FREE;
char* dac_file AUTO_FREE;
- struct smack_accesses* accesses = NULL;
+ char * base_api_feature_name AUTO_FREE;
FILE* file = NULL;
+ // struct smack_accesses* accesses = NULL;
+ const char *s_type_name = app_type_name(app_type);
- // TODO check process capabilities
-
- // get feature SMACK file name
- ret = perm_file_path(&smack_file, app_type, api_feature_name, ".smack");
- if (ret != PC_OPERATION_SUCCESS || !smack_file ) {
- return ret;
+ // Check input values
+ if (s_type_name == NULL || !strcmp(s_type_name, "")) {
+ C_LOGE("Unknown api type");
+ return PC_ERR_INVALID_PARAM;
}
- // check if feature exists
- if (file_exists(smack_file)) {
- C_LOGE("Feature file %s already exists", smack_file);
+ if (api_feature_name == NULL || strlen(api_feature_name) == 0) {
+ C_LOGE("Api feature name is empty.");
return PC_ERR_INVALID_PARAM;
}
+ if (smack_rules && ((ret = validate_all_rules(smack_rules) ) != PC_OPERATION_SUCCESS) ) {
+ C_LOGE("Error in rules list.");
+ return ret;
+ }
+
// check .dac existence only if gids are supported
if (list_of_db_gids && list_size > 0) {
// get feature DAC file name
- ret = perm_file_path(&dac_file, app_type, api_feature_name, ".dac");
+ ret = perm_file_path(&dac_file, app_type, api_feature_name, ".dac", 0);
if (ret != PC_OPERATION_SUCCESS || !dac_file ) {
+ C_LOGE("perm_file_path failed.");
return ret;
}
- // check if feature exists
- if (file_exists(dac_file)) {
- C_LOGE("Feature file %s already exists", dac_file);
- return PC_ERR_INVALID_PARAM;
- }
- }
-
- // parse & save rules
- if (smack_rules) {
- if (smack_accesses_new(&accesses)) {
- C_LOGE("smack_acceses_new failed");
- return PC_ERR_MEM_OPERATION;
- }
-
- ret = parse_and_save_rules(smack_rules, accesses, smack_file);
- smack_accesses_free(accesses);
+ unlink(dac_file);
}
// go through gid list
if (ret == PC_OPERATION_SUCCESS && list_of_db_gids && list_size > 0) {
// save to file
+ SECURE_C_LOGD("Opening file %s.", dac_file);
file = fopen(dac_file, "w+");
ret = save_gids(file, list_of_db_gids, list_size);
- fclose(file);
+ if(file) fclose(file);
}
- // remove both files in case of failure
- if (ret != PC_OPERATION_SUCCESS) {
- unlink(smack_file);
+ // remove file in case of failure
+ if (ret != PC_OPERATION_SUCCESS && dac_file) {
unlink(dac_file);
}
- return ret;
-}
-
-API int app_register_av(const char* app_av_id)
-{
- C_LOGD("Enter function: %s", __func__);
- int ret;
- int i;
- int fd AUTO_CLOSE;
- FILE* file AUTO_FCLOSE;
-
- char** smack_label_app_list AUTO_FREE;
- int smack_label_app_list_len = 0;
- char* smack_path AUTO_FREE;
- struct smack_accesses* smack AUTO_SMACK_FREE;
-
- if (!smack_label_is_valid(app_av_id))
- return PC_ERR_INVALID_PARAM;
+ ret = base_name_from_perm(api_feature_name, &base_api_feature_name);
+ if (ret != PC_OPERATION_SUCCESS){
+ C_LOGE("Error during creating base name: ", ret);
+ return ret;
+ }
- ret = smack_accesses_new(&smack);
+ // Save api feature to the database.
+ ret = rdb_add_permission_rules(base_api_feature_name, s_type_name, smack_rules);
if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("smack_accesses_new failed");
- return PC_ERR_MEM_OPERATION;
+ C_LOGE("RDB rdb_add_permission_rules failed with: %d", ret);
+ return ret;
}
- // writing anti_virus_id (app_av_id) to "database"
- ret = add_av_id_to_databse(app_av_id);
- if (ret != PC_OPERATION_SUCCESS)
- goto out;
+ return ret;
+}
- ret = load_smack_from_file(app_av_id, &smack, &fd, &smack_path);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("load_smack_from_file failed");
- goto out;
- }
+/**
+ * This function is marked as deprecated and will be removed
+ */
+API int app_register_av(const char* app_av_id UNUSED)//deprecated
+{
+ SECURE_C_LOGD("Entering function: %s. Params: app_av_id=%s",
+ __func__, app_av_id);
- // Reading labels of all installed apps from "database"
- ret = get_all_apps_ids(&smack_label_app_list, &smack_label_app_list_len);
- if (ret != PC_OPERATION_SUCCESS) {
- C_LOGE("Error while geting data from database");
- goto out;
- }
- for (i=0; i<smack_label_app_list_len; ++i) {
- C_LOGD("Applying rwx rule for %s", smack_label_app_list[i]);
- if (smack_accesses_add(smack, app_av_id, smack_label_app_list[i], "wrx") == -1) {
- C_LOGE("smack_accesses_add failed");
- ret = PC_ERR_INVALID_OPERATION;
- goto out; // Should we abort adding rules if once smack_accesses_add will fail?
- }
- }
+ C_LOGE("app_register_av is deprecated and unimplemented!");
- // Add permisions from OSP_antivirus.samck file - only the OSP app can be an Anti Virus
- ret = perm_to_smack(smack, app_av_id, APP_TYPE_OSP, SMACK_ANTIVIRUS_PERM);
- if (PC_OPERATION_SUCCESS != ret) {
- C_LOGE("perm_to_smack failed");
- goto out;
- }
+ // TODO: This function is not implemented with RDB.
+ return PC_ERR_INVALID_OPERATION;
+}
- if (have_smack() && smack_accesses_apply(smack)) {
- C_LOGE("smack_accesses_apply failed");
- ret = PC_ERR_INVALID_OPERATION;
- goto out;
+API const char* perm_strerror(int errnum)
+{
+ switch (errnum) {
+ case PC_OPERATION_SUCCESS:
+ return "Success";
+ case PC_ERR_FILE_OPERATION:
+ return "File operation error";
+ case PC_ERR_MEM_OPERATION:
+ return "Memory operation error";
+ case PC_ERR_NOT_PERMITTED:
+ return "Operation not permitted";
+ case PC_ERR_INVALID_PARAM:
+ return "Invalid parameter";
+ case PC_ERR_INVALID_OPERATION:
+ return "Invalid operation";
+ case PC_ERR_DB_OPERATION:
+ return "Database operation error";
+ case PC_ERR_DB_LABEL_TAKEN:
+ return "Label taken by another application";
+ case PC_ERR_DB_QUERY_PREP:
+ return "Query failure during preparation";
+ case PC_ERR_DB_QUERY_BIND:
+ return "Query failure during binding";
+ case PC_ERR_DB_QUERY_STEP:
+ return "Query failure during stepping";
+ case PC_ERR_DB_CONNECTION:
+ return "Cannot establish a connection";
+ case PC_ERR_DB_NO_SUCH_APP:
+ return "No such application";
+ case PC_ERR_DB_PERM_FORBIDDEN:
+ return "Duplicate permission";
+ default:
+ return "Unknown error";
}
+}
- if (smack_accesses_save(smack, fd)) {
- C_LOGE("smack_accesses_save failed");
- ret = PC_ERR_INVALID_OPERATION;
- goto out;
- }
+int app_give_access(const char* subject UNUSED, const char* object UNUSED, const char* permission UNUSED) {
-out:
- for (i=0; i<smack_label_app_list_len; ++i) {
- free(smack_label_app_list[i]);
- }
+ return PC_ERR_INVALID_OPERATION;
+}
- return PC_OPERATION_SUCCESS;
+int app_revoke_access(const char* subject UNUSED, const char* object UNUSED) {
+ return PC_ERR_INVALID_OPERATION;
}