オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Contents of /branches/ccs-patch/security/ccsecurity/environ.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 853 - (show annotations) (download) (as text)
Wed Jan 2 07:32:11 2008 UTC (16 years, 5 months ago) by kumaneko
Original Path: trunk/1.5.x/ccs-patch/fs/tomoyo_env.c
File MIME type: text/x-csrc
File size: 5838 byte(s)


1 /*
2 * fs/tomoyo_env.c
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 *
8 * Version: 1.5.3-pre 2008/01/02
9 *
10 * This file is applicable to both 2.4.30 and 2.6.11 and later.
11 * See README.ccs for ChangeLog.
12 *
13 */
14 /***** TOMOYO Linux start. *****/
15
16 #include <linux/ccs_common.h>
17 #include <linux/tomoyo.h>
18 #include <linux/realpath.h>
19
20 /************************* VARIABLES *************************/
21
22 extern struct mutex domain_acl_lock;
23
24 /************************* AUDIT FUNCTIONS *************************/
25
26 static int AuditEnvLog(const char *env, const bool is_granted, const u8 profile, const u8 mode)
27 {
28 char *buf;
29 int len;
30 if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;
31 len = strlen(env) + 8;
32 if ((buf = InitAuditLog(&len, profile, mode)) == NULL) return -ENOMEM;
33 snprintf(buf + strlen(buf), len - strlen(buf) - 1, KEYWORD_ALLOW_ENV "%s\n", env);
34 return WriteAuditLog(buf, is_granted);
35 }
36
37 /***** The structure for globally usable environments. *****/
38
39 struct globally_usable_env_entry {
40 struct list1_head list;
41 const struct path_info *env;
42 bool is_deleted;
43 };
44
45 /************************* GLOBALLY USABLE ENVIRONMENT HANDLER *************************/
46
47 static LIST1_HEAD(globally_usable_env_list);
48
49 static int AddGloballyUsableEnvEntry(const char *env, const bool is_delete)
50 {
51 struct globally_usable_env_entry *new_entry, *ptr;
52 static DEFINE_MUTEX(lock);
53 const struct path_info *saved_env;
54 int error = -ENOMEM;
55 if (!IsCorrectPath(env, 0, 0, 0, __FUNCTION__)) return -EINVAL;
56 if ((saved_env = SaveName(env)) == NULL) return -ENOMEM;
57 mutex_lock(&lock);
58 list1_for_each_entry(ptr, &globally_usable_env_list, list) {
59 if (ptr->env == saved_env) {
60 ptr->is_deleted = is_delete;
61 error = 0;
62 goto out;
63 }
64 }
65 if (is_delete) {
66 error = -ENOENT; goto out;
67 }
68 if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;
69 new_entry->env = saved_env;
70 list1_add_tail_mb(&new_entry->list, &globally_usable_env_list);
71 error = 0;
72 out: ;
73 mutex_unlock(&lock);
74 return error;
75 }
76
77 static bool IsGloballyUsableEnv(const struct path_info *env)
78 {
79 struct globally_usable_env_entry *ptr;
80 list1_for_each_entry(ptr, &globally_usable_env_list, list) {
81 if (!ptr->is_deleted && PathMatchesToPattern(env, ptr->env)) return 1;
82 }
83 return 0;
84 }
85
86 int AddGloballyUsableEnvPolicy(char *env, const bool is_delete)
87 {
88 return AddGloballyUsableEnvEntry(env, is_delete);
89 }
90
91 int ReadGloballyUsableEnvPolicy(struct io_buffer *head)
92 {
93 struct list1_head *pos;
94 list1_for_each_cookie(pos, head->read_var2, &globally_usable_env_list) {
95 struct globally_usable_env_entry *ptr;
96 ptr = list1_entry(pos, struct globally_usable_env_entry, list);
97 if (ptr->is_deleted) continue;
98 if (io_printf(head, KEYWORD_ALLOW_ENV "%s\n", ptr->env->name)) return -ENOMEM;
99 }
100 return 0;
101 }
102
103 /************************* ENVIRONMENT VARIABLE CHECKING HANDLER *************************/
104
105 static int AddEnvEntry(const char *env, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
106 {
107 struct acl_info *ptr;
108 struct env_acl_record *acl;
109 const struct path_info *saved_env;
110 int error = -ENOMEM;
111 if (!IsCorrectPath(env, 0, 0, 0, __FUNCTION__)) return -EINVAL;
112 if ((saved_env = SaveName(env)) == NULL) return -ENOMEM;
113 if (!is_delete && IsGloballyUsableEnv(saved_env)) return 0;
114
115 mutex_lock(&domain_acl_lock);
116 if (!is_delete) {
117 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
118 acl = container_of(ptr, struct env_acl_record, head);
119 if (ptr->type == TYPE_ENV_ACL && ptr->cond == condition) {
120 if (acl->env == saved_env) {
121 ptr->is_deleted = 0;
122 /* Found. Nothing to do. */
123 error = 0;
124 goto out;
125 }
126 }
127 }
128 /* Not found. Append it to the tail. */
129 if ((acl = alloc_element(sizeof(*acl))) == NULL) goto out;
130 acl->head.type = TYPE_ENV_ACL;
131 acl->head.cond = condition;
132 acl->env = saved_env;
133 error = AddDomainACL(domain, &acl->head);
134 } else {
135 error = -ENOENT;
136 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
137 acl = container_of(ptr, struct env_acl_record, head);
138 if (ptr->type != TYPE_ENV_ACL || ptr->is_deleted || ptr->cond != condition) continue;
139 if (acl->env != saved_env) continue;
140 error = DelDomainACL(ptr);
141 break;
142 }
143 }
144 out: ;
145 mutex_unlock(&domain_acl_lock);
146 return error;
147 }
148
149 static int CheckEnvACL(const char *env_)
150 {
151 const struct domain_info *domain = current->domain_info;
152 int error = -EPERM;
153 struct acl_info *ptr;
154 struct path_info env;
155 env.name = env_;
156 fill_path_info(&env);
157 if (IsGloballyUsableEnv(&env)) return 0;
158 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
159 struct env_acl_record *acl;
160 acl = container_of(ptr, struct env_acl_record, head);
161 if (ptr->type == TYPE_ENV_ACL && ptr->is_deleted == 0 && CheckCondition(ptr->cond, NULL) == 0 &&
162 PathMatchesToPattern(&env, acl->env)) {
163 error = 0;
164 break;
165 }
166 }
167 return error;
168 }
169
170 int CheckEnvPerm(const char *env, const u8 profile, const u8 mode)
171 {
172 int error = 0;
173 if (!env || !*env) return 0;
174 error = CheckEnvACL(env);
175 AuditEnvLog(env, !error, profile, mode);
176 if (error) {
177 struct domain_info * const domain = current->domain_info;
178 const bool is_enforce = (mode == 3);
179 if (TomoyoVerboseMode()) {
180 printk("TOMOYO-%s: Environ %s denied for %s\n", GetMSG(is_enforce), env, GetLastName(domain));
181 }
182 if (is_enforce) error = CheckSupervisor("%s\n" KEYWORD_ALLOW_ENV "%s\n", domain->domainname->name, env);
183 else if (mode == 1 && CheckDomainQuota(domain)) AddEnvEntry(env, domain, NULL, 0);
184 if (!is_enforce) error = 0;
185 }
186 return error;
187 }
188
189 int AddEnvPolicy(char *data, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
190 {
191 return AddEnvEntry(data, domain, condition, is_delete);
192 }
193
194 /***** TOMOYO Linux end. *****/

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26