2 * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <sys/statfs.h>
20 #include <sys/types.h>
24 #include <sys/smack.h>
26 #include <download-provider.h>
27 #include <download-provider-log.h>
28 #include <download-provider-utils.h>
30 #define SMACKFS_MAGIC 0x43415d53
31 #define SMACKFS_MNT "/smack"
33 static int __dp_smack_is_transmute(char *path)
35 char *dir_label = NULL;
37 if (smack_getlabel(path, &dir_label, SMACK_LABEL_TRANSMUTE) == 0 && dir_label != NULL) {
38 if (strncmp(dir_label, "TRUE", strlen(dir_label)) == 0) {
43 if (smack_getlabel(path, &dir_label, SMACK_LABEL_ACCESS) == 0 && dir_label != NULL) {
44 if (strncmp(dir_label, "*", strlen(dir_label)) == 0) {
53 int dp_smack_is_mounted()
58 ret = statfs(SMACKFS_MNT, &sfs);
59 } while (ret < 0 && errno == EINTR);
61 TRACE_ERROR("[SMACK ERROR]");
64 if (sfs.f_type == SMACKFS_MAGIC) {
67 TRACE_ERROR("[SMACK DISABLE]");
71 int dp_smack_set_label(char *label, char *source, char *target)
73 if (label == NULL || source == NULL || target == NULL)
74 return DP_ERROR_PERMISSION_DENIED;
76 int is_setted_dir_label = 0;
77 int errorcode = DP_ERROR_NONE;
79 if (__dp_smack_is_transmute(source) < 0) {
80 TRACE_SECURE_ERROR("[SMACK] no transmute:%s", source);
82 char *dir_label = NULL;
83 if (smack_getlabel(source, &dir_label, SMACK_LABEL_ACCESS) == 0) {
84 if (smack_have_access(label, dir_label, "t") > 0) {
85 if (smack_setlabel(target, dir_label, SMACK_LABEL_ACCESS) != 0) {
86 TRACE_SECURE_ERROR("[SMACK ERROR] label:%s", dir_label);
87 errorcode = DP_ERROR_PERMISSION_DENIED;
89 is_setted_dir_label = 1;
92 TRACE_SECURE_ERROR("[SMACK ERROR] access:%s/%s", label, dir_label);
93 errorcode = DP_ERROR_PERMISSION_DENIED;
96 TRACE_SECURE_ERROR("[SMACK ERROR] no label:%s", source);
97 errorcode = DP_ERROR_PERMISSION_DENIED;
101 if (is_setted_dir_label == 0 &&
102 smack_setlabel(target, label, SMACK_LABEL_ACCESS) != 0) {
103 TRACE_SECURE_ERROR("[SMACK ERROR] label:%s", label);
104 errorcode = DP_ERROR_PERMISSION_DENIED;
106 if (dp_is_file_exist(target) == 0)
112 char *dp_smack_get_label_from_socket(int sock)
115 if (smack_new_label_from_socket(sock, &label) != 0) {
122 int dp_smack_is_valid_dir(int uid, int gid, char *smack_label, char *dir)
124 if (smack_label == NULL || dir == NULL) {
125 TRACE_ERROR("check parameter %s/%s", smack_label, dir);
130 if (stat(dir, &dstate) == 0) {
131 if ((dstate.st_uid == uid && (dstate.st_mode & (S_IRUSR | S_IWUSR)) == (S_IRUSR | S_IWUSR)) ||
132 (dstate.st_gid == gid && (dstate.st_mode & (S_IRGRP | S_IWGRP)) == (S_IRGRP | S_IWGRP)) ||
133 ((dstate.st_mode & (S_IROTH | S_IWOTH)) == (S_IROTH | S_IWOTH))) {
134 char *dir_label = NULL;
135 if (smack_getlabel(dir, &dir_label, SMACK_LABEL_ACCESS) == 0 &&
136 smack_have_access(smack_label, dir_label, "rw") > 0) {
145 int dp_is_valid_dir(const char *dirpath)
147 struct stat dir_state;
149 if (dirpath == NULL) {
150 TRACE_ERROR("check path");
153 stat_ret = stat(dirpath, &dir_state);
154 if (stat_ret == 0 && S_ISDIR(dir_state.st_mode)) {
160 void dp_rebuild_dir(const char *dirpath, mode_t mode)
162 if (dp_is_valid_dir(dirpath) < 0) {
163 if (mkdir(dirpath, mode) == 0) {
164 TRACE_INFO("check directory:%s", dirpath);
165 if (smack_setlabel(dirpath, "_", SMACK_LABEL_ACCESS) != 0) {
166 TRACE_SECURE_ERROR("failed to set smack label:%s", dirpath);
169 TRACE_ERROR("failed to create directory:%s", dirpath);