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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2544 - (hide annotations) (download) (as text)
Thu May 14 06:55:46 2009 UTC (15 years ago) by kumaneko
Original Path: branches/ccs-patch/fs/tomoyo_env.c
File MIME type: text/x-csrc
File size: 8958 byte(s)


1 kumaneko 581 /*
2     * fs/tomoyo_env.c
3     *
4     * Implementation of the Domain-Based Mandatory Access Control.
5     *
6 kumaneko 2030 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 kumaneko 581 *
8 kumaneko 2519 * Version: 1.6.8-pre 2009/05/08
9 kumaneko 581 *
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    
15     #include <linux/ccs_common.h>
16     #include <linux/tomoyo.h>
17     #include <linux/realpath.h>
18    
19 kumaneko 1052 /**
20 kumaneko 2002 * ccs_audit_env_log - Audit environment variable name log.
21 kumaneko 1052 *
22 kumaneko 1657 * @r: Pointer to "struct ccs_request_info".
23 kumaneko 1052 * @env: The name of environment variable.
24     * @is_granted: True if this is a granted log.
25     *
26     * Returns 0 on success, negative value otherwise.
27     */
28 kumaneko 2002 static int ccs_audit_env_log(struct ccs_request_info *r, const char *env,
29     const bool is_granted)
30 kumaneko 581 {
31 kumaneko 1657 return ccs_write_audit_log(is_granted, r, KEYWORD_ALLOW_ENV "%s\n",
32     env);
33 kumaneko 581 }
34    
35 kumaneko 2002 /* The list for "struct ccs_globally_usable_env_entry". */
36 kumaneko 2540 LIST_HEAD(ccs_globally_usable_env_list);
37 kumaneko 581
38 kumaneko 1052 /**
39 kumaneko 2002 * ccs_update_globally_usable_env_entry - Update "struct ccs_globally_usable_env_entry" list.
40 kumaneko 1052 *
41     * @env: The name of environment variable.
42     * @is_delete: True if it is a delete request.
43     *
44     * Returns 0 on success, negative value otherwise.
45     */
46 kumaneko 2002 static int ccs_update_globally_usable_env_entry(const char *env,
47     const bool is_delete)
48 kumaneko 581 {
49 kumaneko 2540 struct ccs_globally_usable_env_entry *entry = NULL;
50 kumaneko 2002 struct ccs_globally_usable_env_entry *ptr;
51     const struct ccs_path_info *saved_env;
52 kumaneko 2540 int error = is_delete ? -ENOENT : -ENOMEM;
53 kumaneko 1064 if (!ccs_is_correct_path(env, 0, 0, 0, __func__) || strchr(env, '='))
54 kumaneko 1052 return -EINVAL;
55 kumaneko 2540 saved_env = ccs_get_name(env);
56 kumaneko 1052 if (!saved_env)
57     return -ENOMEM;
58 kumaneko 2540 if (!is_delete)
59     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
60     /***** WRITER SECTION START *****/
61     down_write(&ccs_policy_lock);
62     list_for_each_entry(ptr, &ccs_globally_usable_env_list, list) {
63 kumaneko 1064 if (ptr->env != saved_env)
64     continue;
65     ptr->is_deleted = is_delete;
66     error = 0;
67 kumaneko 2540 break;
68 kumaneko 581 }
69 kumaneko 2540 if (!is_delete && error && ccs_memory_ok(entry)) {
70     entry->env = saved_env;
71     saved_env = NULL;
72     list_add_tail(&entry->list, &ccs_globally_usable_env_list);
73     entry = NULL;
74     error = 0;
75 kumaneko 581 }
76 kumaneko 2540 up_write(&ccs_policy_lock);
77     /***** WRITER SECTION END *****/
78     ccs_put_name(saved_env);
79     kfree(entry);
80 kumaneko 1064 ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
81 kumaneko 581 return error;
82     }
83    
84 kumaneko 1052 /**
85 kumaneko 2002 * ccs_is_globally_usable_env - Check whether the given environment variable is acceptable for all domains.
86 kumaneko 1052 *
87     * @env: The name of environment variable.
88     *
89     * Returns true if @env is globally permitted environment variable's name,
90     * false otherwise.
91     */
92 kumaneko 2002 static bool ccs_is_globally_usable_env(const struct ccs_path_info *env)
93 kumaneko 581 {
94 kumaneko 2002 struct ccs_globally_usable_env_entry *ptr;
95 kumaneko 2540 bool found = false;
96     /***** READER SECTION START *****/
97     down_read(&ccs_policy_lock);
98     list_for_each_entry(ptr, &ccs_globally_usable_env_list, list) {
99     if (ptr->is_deleted || !ccs_path_matches_pattern(env, ptr->env))
100     continue;
101     found = true;
102     break;
103 kumaneko 581 }
104 kumaneko 2540 up_read(&ccs_policy_lock);
105     /***** READER SECTION END *****/
106     return found;
107 kumaneko 581 }
108    
109 kumaneko 1052 /**
110 kumaneko 2002 * ccs_write_globally_usable_env_policy - Write "struct ccs_globally_usable_env_entry" list.
111 kumaneko 1052 *
112     * @data: String to parse.
113     * @is_delete: True if it is a delete request.
114     *
115     * Returns 0 on success, negative value otherwise.
116     */
117     int ccs_write_globally_usable_env_policy(char *data, const bool is_delete)
118 kumaneko 581 {
119 kumaneko 2002 return ccs_update_globally_usable_env_entry(data, is_delete);
120 kumaneko 581 }
121    
122 kumaneko 1052 /**
123 kumaneko 2002 * ccs_read_globally_usable_env_policy - Read "struct ccs_globally_usable_env_entry" list.
124 kumaneko 1052 *
125     * @head: Pointer to "struct ccs_io_buffer".
126     *
127     * Returns 0 on success, false otherwise.
128     */
129     bool ccs_read_globally_usable_env_policy(struct ccs_io_buffer *head)
130 kumaneko 581 {
131 kumaneko 2540 struct list_head *pos;
132     bool done = true;
133     /***** READER SECTION START *****/
134     down_read(&ccs_policy_lock);
135     list_for_each_cookie(pos, head->read_var2.u.list,
136 kumaneko 2002 &ccs_globally_usable_env_list) {
137     struct ccs_globally_usable_env_entry *ptr;
138 kumaneko 2540 ptr = list_entry(pos, struct ccs_globally_usable_env_entry,
139 kumaneko 2002 list);
140 kumaneko 1052 if (ptr->is_deleted)
141     continue;
142 kumaneko 2540 done = ccs_io_printf(head, KEYWORD_ALLOW_ENV "%s\n",
143     ptr->env->name);
144     if (!done)
145     break;
146 kumaneko 581 }
147 kumaneko 2540 up_read(&ccs_policy_lock);
148     /***** READER SECTION END *****/
149     return done;
150 kumaneko 581 }
151    
152 kumaneko 1052 /**
153 kumaneko 2002 * ccs_update_env_entry - Update "struct ccs_env_acl_record" list.
154 kumaneko 1052 *
155     * @env: The name of environment variable.
156 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info".
157 kumaneko 2002 * @condition: Pointer to "struct ccs_condition_list". May be NULL.
158 kumaneko 1052 * @is_delete: True if it is a delete request.
159     *
160     * Returns 0 on success, negative value otherwise.
161     */
162 kumaneko 2282 static int ccs_update_env_entry(const char *env, struct ccs_domain_info *domain,
163 kumaneko 2002 const struct ccs_condition_list *condition,
164     const bool is_delete)
165 kumaneko 581 {
166 kumaneko 2540 struct ccs_env_acl_record *entry = NULL;
167 kumaneko 2002 struct ccs_acl_info *ptr;
168     const struct ccs_path_info *saved_env;
169 kumaneko 2540 int error = is_delete ? -ENOENT : -ENOMEM;
170 kumaneko 1064 if (!ccs_is_correct_path(env, 0, 0, 0, __func__) || strchr(env, '='))
171 kumaneko 1052 return -EINVAL;
172 kumaneko 2540 saved_env = ccs_get_name(env);
173 kumaneko 1052 if (!saved_env)
174 kumaneko 2544 goto out;
175 kumaneko 1052 if (is_delete)
176     goto delete;
177 kumaneko 2540 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
178     /***** WRITER SECTION START *****/
179     down_write(&ccs_policy_lock);
180     list_for_each_entry(ptr, &domain->acl_info_list, list) {
181     struct ccs_env_acl_record *acl;
182 kumaneko 1064 if (ccs_acl_type1(ptr) != TYPE_ENV_ACL)
183 kumaneko 1052 continue;
184 kumaneko 2544 if (ptr->cond != condition)
185 kumaneko 1052 continue;
186 kumaneko 2002 acl = container_of(ptr, struct ccs_env_acl_record, head);
187 kumaneko 1052 if (acl->env != saved_env)
188     continue;
189     error = ccs_add_domain_acl(NULL, ptr);
190 kumaneko 2540 break;
191 kumaneko 581 }
192 kumaneko 2540 if (error && ccs_memory_ok(entry)) {
193     entry->head.type = TYPE_ENV_ACL;
194     entry->head.cond = condition;
195     entry->env = saved_env;
196     saved_env = NULL;
197     error = ccs_add_domain_acl(domain, &entry->head);
198     entry = NULL;
199     }
200     up_write(&ccs_policy_lock);
201     /***** WRITER SECTION END *****/
202 kumaneko 1052 goto out;
203     delete:
204 kumaneko 2540 /***** WRITER SECTION START *****/
205     down_write(&ccs_policy_lock);
206     list_for_each_entry(ptr, &domain->acl_info_list, list) {
207     struct ccs_env_acl_record *acl;
208 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_ENV_ACL)
209 kumaneko 1052 continue;
210 kumaneko 2544 if (ptr->cond != condition)
211 kumaneko 1052 continue;
212 kumaneko 2002 acl = container_of(ptr, struct ccs_env_acl_record, head);
213 kumaneko 1052 if (acl->env != saved_env)
214     continue;
215     error = ccs_del_domain_acl(ptr);
216     break;
217     }
218 kumaneko 2540 up_write(&ccs_policy_lock);
219     /***** WRITER SECTION END *****/
220 kumaneko 1052 out:
221 kumaneko 2540 ccs_put_name(saved_env);
222     kfree(entry);
223 kumaneko 581 return error;
224     }
225    
226 kumaneko 1052 /**
227 kumaneko 2002 * ccs_check_env_acl - Check permission for environment variable's name.
228 kumaneko 1052 *
229 kumaneko 1657 * @r: Pointer to "struct ccs_request_info".
230 kumaneko 1052 * @environ: The name of environment variable.
231     *
232     * Returns 0 on success, negative value otherwise.
233     */
234 kumaneko 2002 static int ccs_check_env_acl(struct ccs_request_info *r, const char *environ)
235 kumaneko 581 {
236 kumaneko 2540 const struct ccs_domain_info *domain = r->cookie.u.domain;
237 kumaneko 581 int error = -EPERM;
238 kumaneko 2002 struct ccs_acl_info *ptr;
239     struct ccs_path_info env;
240 kumaneko 1052 env.name = environ;
241     ccs_fill_path_info(&env);
242 kumaneko 2540 down_read(&ccs_policy_lock);
243     list_for_each_entry(ptr, &domain->acl_info_list, list) {
244 kumaneko 2002 struct ccs_env_acl_record *acl;
245 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_ENV_ACL)
246 kumaneko 1052 continue;
247 kumaneko 2002 acl = container_of(ptr, struct ccs_env_acl_record, head);
248 kumaneko 1657 if (!ccs_check_condition(r, ptr) ||
249 kumaneko 1052 !ccs_path_matches_pattern(&env, acl->env))
250     continue;
251 kumaneko 2544 r->condition_cookie.u.cond = ptr->cond;
252 kumaneko 856 error = 0;
253     break;
254 kumaneko 581 }
255 kumaneko 2540 up_read(&ccs_policy_lock);
256     if (error && !domain->ignore_global_allow_env &&
257 kumaneko 2002 ccs_is_globally_usable_env(&env))
258 kumaneko 1052 error = 0;
259 kumaneko 581 return error;
260     }
261    
262 kumaneko 1052 /**
263     * ccs_check_env_perm - Check permission for environment variable's name.
264     *
265 kumaneko 1657 * @r: Pointer to "struct ccs_request_info".
266 kumaneko 1052 * @env: The name of environment variable.
267     *
268     * Returns 0 on success, negative value otherwise.
269     */
270 kumaneko 1657 int ccs_check_env_perm(struct ccs_request_info *r, const char *env)
271 kumaneko 581 {
272     int error = 0;
273 kumaneko 1657 const bool is_enforce = (r->mode == 3);
274     if (!ccs_can_sleep())
275     return 0;
276 kumaneko 1052 if (!env || !*env)
277     return 0;
278 kumaneko 1561 retry:
279 kumaneko 2002 error = ccs_check_env_acl(r, env);
280     ccs_audit_env_log(r, env, !error);
281 kumaneko 1052 if (!error)
282     return 0;
283 kumaneko 2540 if (ccs_verbose_mode(r->cookie.u.domain))
284 kumaneko 1052 printk(KERN_WARNING "TOMOYO-%s: Environ %s denied for %s\n",
285 kumaneko 1657 ccs_get_msg(is_enforce), env,
286 kumaneko 2540 ccs_get_last_name(r->cookie.u.domain));
287 kumaneko 1561 if (is_enforce) {
288 kumaneko 1657 error = ccs_check_supervisor(r, KEYWORD_ALLOW_ENV "%s\n", env);
289 kumaneko 1781 if (error == 1)
290 kumaneko 1561 goto retry;
291     return error;
292     }
293 kumaneko 2540 if (r->mode == 1 && ccs_domain_quota_ok(r->cookie.u.domain))
294     ccs_update_env_entry(env, r->cookie.u.domain,
295     ccs_handler_cond(), false);
296 kumaneko 856 return 0;
297 kumaneko 581 }
298    
299 kumaneko 1052 /**
300 kumaneko 2002 * ccs_write_env_policy - Write "struct ccs_env_acl_record" list.
301 kumaneko 1052 *
302     * @data: String to parse.
303 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info".
304 kumaneko 2002 * @condition: Pointer to "struct ccs_condition_list". May be NULL.
305 kumaneko 1052 * @is_delete: True if it is a delete request.
306     *
307     * Returns 0 on success, negative value otherwise.
308     */
309 kumaneko 2282 int ccs_write_env_policy(char *data, struct ccs_domain_info *domain,
310 kumaneko 2002 const struct ccs_condition_list *condition,
311 kumaneko 1052 const bool is_delete)
312 kumaneko 581 {
313 kumaneko 2002 return ccs_update_env_entry(data, domain, condition, is_delete);
314 kumaneko 581 }

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