Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1507 - (show annotations) (download) (as text)
Tue Sep 2 06:45:13 2008 UTC (15 years, 9 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 7153 byte(s)


1 /*
2 * fs/tomoyo_capability.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.4 2008/09/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 #include <linux/realpath.h>
18
19 /**
20 * cap_operation2name - Convert capability operation to capability message.
21 *
22 * @operation: Type of operation.
23 *
24 * Returns the name of capability.
25 */
26 static const char *cap_operation2name(const u8 operation)
27 {
28 static const char *capability_name[TOMOYO_MAX_CAPABILITY_INDEX] = {
29 [TOMOYO_INET_STREAM_SOCKET_CREATE] =
30 "socket(PF_INET, SOCK_STREAM)",
31 [TOMOYO_INET_STREAM_SOCKET_LISTEN] =
32 "listen(PF_INET, SOCK_STREAM)",
33 [TOMOYO_INET_STREAM_SOCKET_CONNECT] =
34 "connect(PF_INET, SOCK_STREAM)",
35 [TOMOYO_USE_INET_DGRAM_SOCKET] =
36 "socket(PF_INET, SOCK_DGRAM)",
37 [TOMOYO_USE_INET_RAW_SOCKET] =
38 "socket(PF_INET, SOCK_RAW)",
39 [TOMOYO_USE_ROUTE_SOCKET] = "socket(PF_ROUTE)",
40 [TOMOYO_USE_PACKET_SOCKET] = "socket(PF_PACKET)",
41 [TOMOYO_SYS_MOUNT] = "sys_mount()",
42 [TOMOYO_SYS_UMOUNT] = "sys_umount()",
43 [TOMOYO_SYS_REBOOT] = "sys_reboot()",
44 [TOMOYO_SYS_CHROOT] = "sys_chroot()",
45 [TOMOYO_SYS_KILL] = "sys_kill()",
46 [TOMOYO_SYS_VHANGUP] = "sys_vhangup()",
47 [TOMOYO_SYS_SETTIME] = "sys_settimeofday()",
48 [TOMOYO_SYS_NICE] = "sys_nice()",
49 [TOMOYO_SYS_SETHOSTNAME] = "sys_sethostname()",
50 [TOMOYO_USE_KERNEL_MODULE] = "kernel_module",
51 [TOMOYO_CREATE_FIFO] = "mknod(FIFO)",
52 [TOMOYO_CREATE_BLOCK_DEV] = "mknod(BDEV)",
53 [TOMOYO_CREATE_CHAR_DEV] = "mknod(CDEV)",
54 [TOMOYO_CREATE_UNIX_SOCKET] = "mknod(SOCKET)",
55 [TOMOYO_SYS_LINK] = "sys_link()",
56 [TOMOYO_SYS_SYMLINK] = "sys_symlink()",
57 [TOMOYO_SYS_RENAME] = "sys_rename()",
58 [TOMOYO_SYS_UNLINK] = "sys_unlink()",
59 [TOMOYO_SYS_CHMOD] = "sys_chmod()",
60 [TOMOYO_SYS_CHOWN] = "sys_chown()",
61 [TOMOYO_SYS_IOCTL] = "sys_ioctl()",
62 [TOMOYO_SYS_KEXEC_LOAD] = "sys_kexec_load()",
63 [TOMOYO_SYS_PIVOT_ROOT] = "sys_pivot_root()",
64 [TOMOYO_SYS_PTRACE] = "sys_ptrace()",
65 };
66 if (operation < TOMOYO_MAX_CAPABILITY_INDEX)
67 return capability_name[operation];
68 return NULL;
69 }
70
71 /**
72 * audit_capability_log - Audit capability log.
73 *
74 * @operation: Type of operation.
75 * @is_granted: True if this is a granted log.
76 * @profile: Profile number used.
77 * @mode: Access control mode used.
78 *
79 * Returns 0 on success, negative value otherwise.
80 */
81 static int audit_capability_log(const u8 operation, const bool is_granted,
82 const u8 profile, const u8 mode)
83 {
84 char *buf;
85 int len = 64;
86 int len2;
87 if (ccs_can_save_audit_log(is_granted) < 0)
88 return -ENOMEM;
89 buf = ccs_init_audit_log(&len, profile, mode, NULL);
90 if (!buf)
91 return -ENOMEM;
92 len2 = strlen(buf);
93 snprintf(buf + len2, len - len2 - 1, KEYWORD_ALLOW_CAPABILITY "%s\n",
94 ccs_cap2keyword(operation));
95 return ccs_write_audit_log(buf, is_granted);
96 }
97
98 /**
99 * update_capability_acl - Update "struct capability_acl_record" list.
100 *
101 * @operation: Type of operation.
102 * @domain: Pointer to "struct domain_info".
103 * @condition: Pointer to "struct condition_list". May be NULL.
104 * @is_delete: True if it is a delete request.
105 *
106 * Returns 0 on success, negative value otherwise.
107 */
108 static int update_capability_acl(const u8 operation, struct domain_info *domain,
109 const struct condition_list *condition,
110 const bool is_delete)
111 {
112 struct acl_info *ptr;
113 struct capability_acl_record *acl;
114 int error = -ENOMEM;
115 if (!domain)
116 return -EINVAL;
117 mutex_lock(&domain_acl_lock);
118 if (is_delete)
119 goto delete;
120 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
121 if (ccs_acl_type1(ptr) != TYPE_CAPABILITY_ACL)
122 continue;
123 if (ccs_get_condition_part(ptr) != condition)
124 continue;
125 acl = container_of(ptr, struct capability_acl_record, head);
126 if (acl->operation != operation)
127 continue;
128 error = ccs_add_domain_acl(NULL, ptr);
129 goto out;
130 }
131 /* Not found. Append it to the tail. */
132 acl = ccs_alloc_acl_element(TYPE_CAPABILITY_ACL, condition);
133 if (!acl)
134 goto out;
135 acl->operation = operation;
136 error = ccs_add_domain_acl(domain, &acl->head);
137 goto out;
138 delete:
139 error = -ENOENT;
140 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
141 if (ccs_acl_type2(ptr) != TYPE_CAPABILITY_ACL)
142 continue;
143 if (ccs_get_condition_part(ptr) != condition)
144 continue;
145 acl = container_of(ptr, struct capability_acl_record, head);
146 if (acl->operation != operation)
147 continue;
148 error = ccs_del_domain_acl(ptr);
149 break;
150 }
151 out:
152 mutex_unlock(&domain_acl_lock);
153 return error;
154 }
155
156 /**
157 * ccs_capable - Check permission for capability.
158 *
159 * @operation: Type of operation.
160 *
161 * Returns true on success, false otherwise.
162 */
163 bool ccs_capable(const u8 operation)
164 {
165 struct domain_info * const domain = current->domain_info;
166 struct acl_info *ptr;
167 const u8 profile = current->domain_info->profile;
168 const u8 mode = ccs_check_capability_flags(operation);
169 const bool is_enforce = (mode == 3);
170 bool found = false;
171 if (!mode)
172 return true;
173 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
174 struct capability_acl_record *acl;
175 if (ccs_acl_type2(ptr) != TYPE_CAPABILITY_ACL)
176 continue;
177 acl = container_of(ptr, struct capability_acl_record, head);
178 if (acl->operation != operation ||
179 !ccs_check_condition(ptr, NULL))
180 continue;
181 ccs_update_condition(ptr);
182 found = true;
183 break;
184 }
185 audit_capability_log(operation, found, profile, mode);
186 if (found)
187 return true;
188 if (ccs_verbose_mode())
189 printk(KERN_WARNING "TOMOYO-%s: %s denied for %s\n",
190 ccs_get_msg(is_enforce), cap_operation2name(operation),
191 ccs_get_last_name(domain));
192 if (is_enforce)
193 return !ccs_check_supervisor(NULL,
194 KEYWORD_ALLOW_CAPABILITY "%s\n",
195 ccs_cap2keyword(operation));
196 if (mode == 1 && ccs_check_domain_quota(domain))
197 update_capability_acl(operation, domain, NULL, false);
198 return true;
199 }
200 EXPORT_SYMBOL(ccs_capable); /* for net/unix/af_unix.c */
201
202 /**
203 * ccs_write_capability_policy - Write "struct capability_acl_record" list.
204 *
205 * @data: String to parse.
206 * @domain: Pointer to "struct domain_info".
207 * @condition: Pointer to "struct condition_list". May be NULL.
208 * @is_delete: True if it is a delete request.
209 *
210 * Returns 0 on success, negative value otherwise.
211 */
212 int ccs_write_capability_policy(char *data, struct domain_info *domain,
213 const struct condition_list *condition,
214 const bool is_delete)
215 {
216 u8 capability;
217 for (capability = 0; capability < TOMOYO_MAX_CAPABILITY_INDEX;
218 capability++) {
219 if (strcmp(data, ccs_cap2keyword(capability)))
220 continue;
221 return update_capability_acl(capability, domain, condition,
222 is_delete);
223 }
224 return -EINVAL;
225 }

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