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

Subversion リポジトリの参照

Contents of /branches/ccs-patch/fs/tomoyo_exec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2828 - (show annotations) (download) (as text)
Mon Aug 3 05:36:36 2009 UTC (14 years, 10 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 6306 byte(s)


1 /*
2 * fs/tomoyo_exec.c
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 *
8 * Version: 1.7.0-pre 2009/07/03
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
15 #include <linux/ccs_common.h>
16 #include <linux/tomoyo.h>
17
18 /**
19 * ccs_audit_argv0_log - Audit argv[0] log.
20 *
21 * @r: Pointer to "struct ccs_request_info".
22 * @filename: The fullpath of program.
23 * @argv0: The basename of argv[0].
24 * @is_granted: True if this is a granted log.
25 *
26 * Returns 0 on success, negative value otherwise.
27 */
28 static int ccs_audit_argv0_log(struct ccs_request_info *r, const char *filename,
29 const char *argv0, const bool is_granted)
30 {
31 if (!is_granted && ccs_verbose_mode(r->domain))
32 printk(KERN_WARNING "TOMOYO-%s: Run %s as %s denied for %s\n",
33 ccs_get_msg(r->mode == 3), filename, argv0,
34 ccs_get_last_name(r->domain));
35 return ccs_write_audit_log(is_granted, r, KEYWORD_ALLOW_ARGV0
36 "%s %s\n", filename, argv0);
37 }
38
39 /**
40 * ccs_update_argv0_entry - Update "struct ccs_argv0_acl_record" list.
41 *
42 * @filename: The fullpath of the program.
43 * @argv0: The basename of argv[0].
44 * @domain: Pointer to "struct ccs_domain_info".
45 * @condition: Pointer to "struct ccs_condition". May be NULL.
46 * @is_delete: True if it is a delete request.
47 *
48 * Returns 0 on success, negative value otherwise.
49 */
50 static int ccs_update_argv0_entry(const char *filename, const char *argv0,
51 struct ccs_domain_info *domain,
52 struct ccs_condition *condition,
53 const bool is_delete)
54 {
55 struct ccs_argv0_acl_record *entry = NULL;
56 struct ccs_acl_info *ptr;
57 const struct ccs_path_info *saved_filename;
58 const struct ccs_path_info *saved_argv0;
59 int error = is_delete ? -ENOENT : -ENOMEM;
60 if (!ccs_is_correct_path(filename, 1, 0, -1) ||
61 !ccs_is_correct_path(argv0, -1, 0, -1) ||
62 strchr(argv0, '/'))
63 return -EINVAL;
64 saved_filename = ccs_get_name(filename);
65 saved_argv0 = ccs_get_name(argv0);
66 if (!saved_filename || !saved_argv0)
67 goto out;
68 if (is_delete)
69 goto delete;
70 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
71 mutex_lock(&ccs_policy_lock);
72 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
73 struct ccs_argv0_acl_record *acl;
74 if (ccs_acl_type1(ptr) != TYPE_ARGV0_ACL)
75 continue;
76 if (ptr->cond != condition)
77 continue;
78 acl = container_of(ptr, struct ccs_argv0_acl_record, head);
79 if (acl->filename != saved_filename ||
80 acl->argv0 != saved_argv0)
81 continue;
82 error = ccs_add_domain_acl(NULL, ptr);
83 break;
84 }
85 if (error && ccs_memory_ok(entry, sizeof(*entry))) {
86 entry->head.type = TYPE_ARGV0_ACL;
87 entry->head.cond = condition;
88 entry->filename = saved_filename;
89 saved_filename = NULL;
90 entry->argv0 = saved_argv0;
91 saved_argv0 = NULL;
92 error = ccs_add_domain_acl(domain, &entry->head);
93 entry = NULL;
94 }
95 mutex_unlock(&ccs_policy_lock);
96 goto out;
97 delete:
98 mutex_lock(&ccs_policy_lock);
99 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
100 struct ccs_argv0_acl_record *acl;
101 if (ccs_acl_type2(ptr) != TYPE_ARGV0_ACL)
102 continue;
103 if (ptr->cond != condition)
104 continue;
105 acl = container_of(ptr, struct ccs_argv0_acl_record, head);
106 if (acl->filename != saved_filename ||
107 acl->argv0 != saved_argv0)
108 continue;
109 error = ccs_del_domain_acl(ptr);
110 break;
111 }
112 mutex_unlock(&ccs_policy_lock);
113 out:
114 ccs_put_name(saved_filename);
115 ccs_put_name(saved_argv0);
116 kfree(entry);
117 return error;
118 }
119
120 /**
121 * ccs_check_argv0_acl - Check permission for argv[0].
122 *
123 * @r: Pointer to "struct ccs_request_info".
124 * @filename: The fullpath of the program.
125 * @argv0: The basename of argv[0].
126 *
127 * Returns 0 on success, -EPERM otherwise.
128 *
129 * Caller holds ccs_read_lock().
130 */
131 static int ccs_check_argv0_acl(struct ccs_request_info *r,
132 const struct ccs_path_info *filename,
133 const char *argv0)
134 {
135 int error = -EPERM;
136 struct ccs_domain_info *domain = r->domain;
137 struct ccs_acl_info *ptr;
138 struct ccs_path_info argv_0;
139 ccs_check_read_lock();
140 argv_0.name = argv0;
141 ccs_fill_path_info(&argv_0);
142 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
143 struct ccs_argv0_acl_record *acl;
144 if (ccs_acl_type2(ptr) != TYPE_ARGV0_ACL)
145 continue;
146 acl = container_of(ptr, struct ccs_argv0_acl_record, head);
147 if (!ccs_check_condition(r, ptr) ||
148 !ccs_path_matches_pattern(filename, acl->filename) ||
149 !ccs_path_matches_pattern(&argv_0, acl->argv0))
150 continue;
151 r->cond = ptr->cond;
152 error = 0;
153 break;
154 }
155 return error;
156 }
157
158 /**
159 * ccs_check_argv0_perm - Check permission for argv[0].
160 *
161 * @r: Pointer to "struct ccs_request_info".
162 * @filename: The fullpath of the program.
163 * @argv0: The basename of argv[0].
164 *
165 * Returns 0 on success, 1 on retry, negative value otherwise.
166 *
167 * Caller holds ccs_read_lock().
168 */
169 int ccs_check_argv0_perm(struct ccs_request_info *r,
170 const struct ccs_path_info *filename,
171 const char *argv0)
172 {
173 int error = 0;
174 const bool is_enforce = (r->mode == 3);
175 ccs_check_read_lock();
176 if (!ccs_can_sleep())
177 return 0;
178 if (!filename || !argv0 || !*argv0)
179 return 0;
180 error = ccs_check_argv0_acl(r, filename, argv0);
181 ccs_audit_argv0_log(r, filename->name, argv0, !error);
182 if (!error)
183 return 0;
184 if (is_enforce)
185 return ccs_check_supervisor(r, KEYWORD_ALLOW_ARGV0 "%s %s\n",
186 filename->name, argv0);
187 else if (ccs_domain_quota_ok(r)) {
188 struct ccs_condition *cond = ccs_handler_cond();
189 ccs_update_argv0_entry(filename->name, argv0,
190 r->domain, cond, false);
191 ccs_put_condition(cond);
192 }
193 return 0;
194 }
195
196 /**
197 * ccs_write_argv0_policy - Write "struct ccs_argv0_acl_record" list.
198 *
199 * @data: String to parse.
200 * @domain: Pointer to "struct ccs_domain_info".
201 * @condition: Pointer to "struct ccs_condition". May be NULL.
202 * @is_delete: True if it is a delete request.
203 *
204 * Returns 0 on success, negative value otherwise.
205 */
206 int ccs_write_argv0_policy(char *data, struct ccs_domain_info *domain,
207 struct ccs_condition *condition,
208 const bool is_delete)
209 {
210 char *w[2];
211 if (!ccs_tokenize(data, w, sizeof(w)) || !w[1][0])
212 return -EINVAL;
213 return ccs_update_argv0_entry(w[0], w[1], domain, condition,
214 is_delete);
215 }

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