Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Contents of /trunk/1.6.x/ccs-patch/fs/tomoyo_exec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1785 - (show annotations) (download) (as text)
Wed Nov 5 00:00:42 2008 UTC (15 years, 7 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 5736 byte(s)


1 /*
2 * fs/tomoyo_exec.c
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 *
8 * Version: 1.6.5-rc 2008/11/05
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 #include <linux/realpath.h>
18
19 /**
20 * audit_argv0_log - Audit argv[0] log.
21 *
22 * @r: Pointer to "struct ccs_request_info".
23 * @filename: The fullpath of program.
24 * @argv0: The basename of argv[0].
25 * @is_granted: True if this is a granted log.
26 *
27 * Returns 0 on success, negative value otherwise.
28 */
29 static int audit_argv0_log(struct ccs_request_info *r, const char *filename,
30 const char *argv0, const bool is_granted)
31 {
32 return ccs_write_audit_log(is_granted, r, KEYWORD_ALLOW_ARGV0
33 "%s %s\n", filename, argv0);
34 }
35
36 /**
37 * update_argv0_entry - Update "struct argv0_acl_record" list.
38 *
39 * @filename: The fullpath of the program.
40 * @argv0: The basename of argv[0].
41 * @domain: Pointer to "struct domain_info".
42 * @condition: Pointer to "struct condition_list". May be NULL.
43 * @is_delete: True if it is a delete request.
44 *
45 * Returns 0 on success, negative value otherwise.
46 */
47 static int update_argv0_entry(const char *filename, const char *argv0,
48 struct domain_info *domain,
49 const struct condition_list *condition,
50 const bool is_delete)
51 {
52 static DEFINE_MUTEX(lock);
53 struct acl_info *ptr;
54 struct argv0_acl_record *acl;
55 const struct path_info *saved_filename;
56 const struct path_info *saved_argv0;
57 int error = -ENOMEM;
58 if (!ccs_is_correct_path(filename, 1, 0, -1, __func__) ||
59 !ccs_is_correct_path(argv0, -1, 0, -1, __func__) ||
60 strchr(argv0, '/'))
61 return -EINVAL;
62 saved_filename = ccs_save_name(filename);
63 saved_argv0 = ccs_save_name(argv0);
64 if (!saved_filename || !saved_argv0)
65 return -ENOMEM;
66 mutex_lock(&lock);
67 if (is_delete)
68 goto delete;
69 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
70 if (ccs_acl_type1(ptr) != TYPE_ARGV0_ACL)
71 continue;
72 if (ccs_get_condition_part(ptr) != condition)
73 continue;
74 acl = container_of(ptr, struct argv0_acl_record, head);
75 if (acl->filename != saved_filename ||
76 acl->argv0 != saved_argv0)
77 continue;
78 error = ccs_add_domain_acl(NULL, ptr);
79 goto out;
80 }
81 /* Not found. Append it to the tail. */
82 acl = ccs_alloc_acl_element(TYPE_ARGV0_ACL, condition);
83 if (!acl)
84 goto out;
85 acl->filename = saved_filename;
86 acl->argv0 = saved_argv0;
87 error = ccs_add_domain_acl(domain, &acl->head);
88 goto out;
89 delete:
90 error = -ENOENT;
91 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
92 if (ccs_acl_type2(ptr) != TYPE_ARGV0_ACL)
93 continue;
94 if (ccs_get_condition_part(ptr) != condition)
95 continue;
96 acl = container_of(ptr, struct argv0_acl_record, head);
97 if (acl->filename != saved_filename ||
98 acl->argv0 != saved_argv0)
99 continue;
100 error = ccs_del_domain_acl(ptr);
101 break;
102 }
103 out:
104 mutex_unlock(&lock);
105 return error;
106 }
107
108 /**
109 * check_argv0_acl - Check permission for argv[0].
110 *
111 * @r: Pointer to "struct ccs_request_info".
112 * @filename: The fullpath of the program.
113 * @argv0: The basename of argv[0].
114 *
115 * Returns 0 on success, -EPERM otherwise.
116 */
117 static int check_argv0_acl(struct ccs_request_info *r,
118 const struct path_info *filename, const char *argv0)
119 {
120 int error = -EPERM;
121 struct domain_info *domain = r->domain;
122 struct acl_info *ptr;
123 struct path_info argv_0;
124 argv_0.name = argv0;
125 ccs_fill_path_info(&argv_0);
126 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
127 struct argv0_acl_record *acl;
128 if (ccs_acl_type2(ptr) != TYPE_ARGV0_ACL)
129 continue;
130 acl = container_of(ptr, struct argv0_acl_record, head);
131 if (!ccs_check_condition(r, ptr) ||
132 !ccs_path_matches_pattern(filename, acl->filename) ||
133 !ccs_path_matches_pattern(&argv_0, acl->argv0))
134 continue;
135 r->cond = ccs_get_condition_part(ptr);
136 error = 0;
137 break;
138 }
139 return error;
140 }
141
142 /**
143 * ccs_check_argv0_perm - Check permission for argv[0].
144 *
145 * @r: Pointer to "struct ccs_request_info".
146 * @filename: The fullpath of the program.
147 * @argv0: The basename of argv[0].
148 *
149 * Returns 0 on success, 1 on retry, negative value otherwise.
150 */
151 int ccs_check_argv0_perm(struct ccs_request_info *r,
152 const struct path_info *filename, const char *argv0)
153 {
154 int error = 0;
155 const bool is_enforce = (r->mode == 3);
156 if (!ccs_can_sleep())
157 return 0;
158 if (!filename || !argv0 || !*argv0)
159 return 0;
160 error = check_argv0_acl(r, filename, argv0);
161 audit_argv0_log(r, filename->name, argv0, !error);
162 if (!error)
163 return 0;
164 if (ccs_verbose_mode(r->domain))
165 printk(KERN_WARNING "TOMOYO-%s: Run %s as %s denied for %s\n",
166 ccs_get_msg(is_enforce), filename->name, argv0,
167 ccs_get_last_name(r->domain));
168 if (is_enforce)
169 return ccs_check_supervisor(r, KEYWORD_ALLOW_ARGV0 "%s %s\n",
170 filename->name, argv0);
171 if (r->mode == 1 && ccs_check_domain_quota(r->domain))
172 update_argv0_entry(filename->name, argv0, r->domain, NULL,
173 false);
174 return 0;
175 }
176
177 /**
178 * ccs_write_argv0_policy - Write "struct argv0_acl_record" list.
179 *
180 * @data: String to parse.
181 * @domain: Pointer to "struct domain_info".
182 * @condition: Pointer to "struct condition_list". May be NULL.
183 * @is_delete: True if it is a delete request.
184 *
185 * Returns 0 on success, negative value otherwise.
186 */
187 int ccs_write_argv0_policy(char *data, struct domain_info *domain,
188 const struct condition_list *condition,
189 const bool is_delete)
190 {
191 char *argv0 = strchr(data, ' ');
192 if (!argv0)
193 return -EINVAL;
194 *argv0++ = '\0';
195 return update_argv0_entry(data, argv0, domain, condition, is_delete);
196 }

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