Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 722 - (hide annotations) (download) (as text)
Thu Nov 22 04:09:54 2007 UTC (16 years, 6 months ago) by kumaneko
Original Path: trunk/1.5.x/ccs-patch/fs/tomoyo_capability.c
File MIME type: text/x-csrc
File size: 9566 byte(s)
Use struct list1_head
1 kumaneko 111 /*
2     * fs/tomoyo_capability.c
3     *
4     * Implementation of the Domain-Based Mandatory Access Control.
5     *
6     * Copyright (C) 2005-2007 NTT DATA CORPORATION
7     *
8 kumaneko 708 * Version: 1.5.2-pre 2007/11/19
9 kumaneko 111 *
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 kumaneko 652 extern struct mutex domain_acl_lock;
23 kumaneko 111 extern int sbin_init_started;
24    
25     static struct {
26     const char *keyword;
27     unsigned int current_value;
28     const char *capability_name;
29     } capability_control_array[TOMOYO_MAX_CAPABILITY_INDEX] = { /* domain_policy.txt */
30     [TOMOYO_INET_STREAM_SOCKET_CREATE] = { "inet_tcp_create", 0, "socket(PF_INET, SOCK_STREAM)" },
31     [TOMOYO_INET_STREAM_SOCKET_LISTEN] = { "inet_tcp_listen", 0, "listen(PF_INET, SOCK_STREAM)" },
32     [TOMOYO_INET_STREAM_SOCKET_CONNECT] = { "inet_tcp_connect", 0, "connect(PF_INET, SOCK_STREAM)" },
33     [TOMOYO_USE_INET_DGRAM_SOCKET] = { "use_inet_udp", 0, "socket(PF_INET, SOCK_DGRAM)" },
34     [TOMOYO_USE_INET_RAW_SOCKET] = { "use_inet_ip", 0, "socket(PF_INET, SOCK_RAW)" },
35     [TOMOYO_USE_ROUTE_SOCKET] = { "use_route", 0, "socket(PF_ROUTE)" },
36     [TOMOYO_USE_PACKET_SOCKET] = { "use_packet", 0, "socket(PF_PACKET)" },
37     [TOMOYO_SYS_MOUNT] = { "SYS_MOUNT", 0, "sys_mount()" },
38     [TOMOYO_SYS_UMOUNT] = { "SYS_UMOUNT", 0, "sys_umount()" },
39     [TOMOYO_SYS_REBOOT] = { "SYS_REBOOT", 0, "sys_reboot()" },
40     [TOMOYO_SYS_CHROOT] = { "SYS_CHROOT", 0, "sys_chroot()" },
41     [TOMOYO_SYS_KILL] = { "SYS_KILL", 0, "sys_kill()" },
42     [TOMOYO_SYS_VHANGUP] = { "SYS_VHANGUP", 0, "sys_vhangup()" },
43     [TOMOYO_SYS_SETTIME] = { "SYS_TIME", 0, "sys_settimeofday()" },
44     [TOMOYO_SYS_NICE] = { "SYS_NICE", 0, "sys_nice()" },
45     [TOMOYO_SYS_SETHOSTNAME] = { "SYS_SETHOSTNAME", 0, "sys_sethostname()" },
46     [TOMOYO_USE_KERNEL_MODULE] = { "use_kernel_module", 0, "kernel_module" },
47     [TOMOYO_CREATE_FIFO] = { "create_fifo", 0, "mknod(FIFO)" },
48     [TOMOYO_CREATE_BLOCK_DEV] = { "create_block_dev", 0, "mknod(BDEV)" },
49     [TOMOYO_CREATE_CHAR_DEV] = { "create_char_dev", 0, "mknod(CDEV)" },
50     [TOMOYO_CREATE_UNIX_SOCKET] = { "create_unix_socket", 0, "mknod(SOCKET)" },
51     [TOMOYO_SYS_LINK] = { "SYS_LINK", 0, "sys_link()" },
52     [TOMOYO_SYS_SYMLINK] = { "SYS_SYMLINK", 0, "sys_symlink()" },
53     [TOMOYO_SYS_RENAME] = { "SYS_RENAME", 0, "sys_rename()" },
54     [TOMOYO_SYS_UNLINK] = { "SYS_UNLINK", 0, "sys_unlink()" },
55     [TOMOYO_SYS_CHMOD] = { "SYS_CHMOD", 0, "sys_chmod()" },
56     [TOMOYO_SYS_CHOWN] = { "SYS_CHOWN", 0, "sys_chown()" },
57     [TOMOYO_SYS_IOCTL] = { "SYS_IOCTL", 0, "sys_ioctl()" },
58     [TOMOYO_SYS_KEXEC_LOAD] = { "SYS_KEXEC_LOAD", 0, "sys_kexec_load()" },
59 kumaneko 141 [TOMOYO_SYS_PIVOT_ROOT] = { "SYS_PIVOT_ROOT", 0, "sys_pivot_root()" },
60 kumaneko 111 };
61    
62 kumaneko 214 struct profile {
63 kumaneko 111 unsigned char value[TOMOYO_MAX_CAPABILITY_INDEX];
64 kumaneko 214 };
65 kumaneko 111
66 kumaneko 214 static struct profile *profile_ptr[MAX_PROFILES];
67 kumaneko 111
68     /************************* UTILITY FUNCTIONS *************************/
69    
70     const char *capability2keyword(const unsigned int capability)
71     {
72     return capability < TOMOYO_MAX_CAPABILITY_INDEX ? capability_control_array[capability].keyword : NULL;
73     }
74    
75     static const char *capability2name(const unsigned int capability)
76     {
77     return capability < TOMOYO_MAX_CAPABILITY_INDEX ? capability_control_array[capability].capability_name : NULL;
78     }
79    
80     /* Check whether the given capability control is enabled. */
81     static unsigned int CheckCapabilityFlags(const unsigned int index)
82     {
83     const u8 profile = current->domain_info->profile;
84 kumaneko 121 return sbin_init_started && index < TOMOYO_MAX_CAPABILITY_INDEX
85     #if MAX_PROFILES != 256
86     && profile < MAX_PROFILES
87     #endif
88     && profile_ptr[profile] ? profile_ptr[profile]->value[index] : 0;
89 kumaneko 111 }
90    
91     /* Check whether the given capability control is enforce mode. */
92 kumaneko 621 static bool CheckCapabilityEnforce(const unsigned int index)
93 kumaneko 111 {
94     return CheckCapabilityFlags(index) == 3;
95     }
96    
97 kumaneko 461 /* Check whether the given capability control is learning mode. */
98 kumaneko 621 static bool CheckCapabilityAccept(const unsigned int index, struct domain_info * const domain)
99 kumaneko 111 {
100 kumaneko 512 if (CheckCapabilityFlags(index) != 1) return 0;
101     return CheckDomainQuota(domain);
102 kumaneko 111 }
103    
104 kumaneko 214 static struct profile *FindOrAssignNewProfile(const unsigned int profile)
105 kumaneko 111 {
106 kumaneko 652 static DEFINE_MUTEX(profile_lock);
107 kumaneko 214 struct profile *ptr = NULL;
108 kumaneko 652 mutex_lock(&profile_lock);
109 kumaneko 111 if (profile < MAX_PROFILES && (ptr = profile_ptr[profile]) == NULL) {
110 kumaneko 214 if ((ptr = alloc_element(sizeof(*ptr))) != NULL) {
111 kumaneko 111 int i;
112     for (i = 0; i < TOMOYO_MAX_CAPABILITY_INDEX; i++) ptr->value[i] = capability_control_array[i].current_value;
113 kumaneko 708 mb(); /* Avoid out-of-order execution. */
114 kumaneko 111 profile_ptr[profile] = ptr;
115     }
116     }
117 kumaneko 652 mutex_unlock(&profile_lock);
118 kumaneko 111 return ptr;
119     }
120    
121     int SetCapabilityStatus(const char *data, unsigned int value, const unsigned int profile)
122     {
123     int i;
124 kumaneko 214 struct profile *ptr = FindOrAssignNewProfile(profile);
125 kumaneko 111 if (!ptr) return -EINVAL;
126     for (i = 0; i < TOMOYO_MAX_CAPABILITY_INDEX; i++) {
127     if (strcmp(data, capability_control_array[i].keyword)) continue;
128     if (value > 3) value = 3;
129     ptr->value[i] = value;
130     return 0;
131     }
132     return -EINVAL;
133     }
134    
135 kumaneko 214 int ReadCapabilityStatus(struct io_buffer *head)
136 kumaneko 111 {
137     int step;
138     for (step = head->read_step; step < MAX_PROFILES * TOMOYO_MAX_CAPABILITY_INDEX; step++) {
139     const int i = step / TOMOYO_MAX_CAPABILITY_INDEX, j = step % TOMOYO_MAX_CAPABILITY_INDEX;
140 kumaneko 214 const struct profile *profile = profile_ptr[i];
141 kumaneko 111 head->read_step = step;
142     if (!profile) continue;
143     if (io_printf(head, "%u-" KEYWORD_MAC_FOR_CAPABILITY "%s=%u\n", i, capability_control_array[j].keyword, profile->value[j])) break;
144     }
145     return step < MAX_PROFILES * TOMOYO_MAX_CAPABILITY_INDEX ? -ENOMEM : 0;
146     }
147    
148     /************************* AUDIT FUNCTIONS *************************/
149    
150 kumaneko 621 static int AuditCapabilityLog(const unsigned int capability, const bool is_granted)
151 kumaneko 111 {
152     char *buf;
153     int len = 64;
154     if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;
155     if ((buf = InitAuditLog(&len)) == NULL) return -ENOMEM;
156     snprintf(buf + strlen(buf), len - strlen(buf) - 1, KEYWORD_ALLOW_CAPABILITY "%s\n", capability2keyword(capability));
157     return WriteAuditLog(buf, is_granted);
158     }
159    
160     /************************* CAPABILITY ACL HANDLER *************************/
161    
162 kumaneko 621 static int AddCapabilityACL(const unsigned int capability, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
163 kumaneko 111 {
164     struct acl_info *ptr;
165 kumaneko 708 struct capability_acl_record *acl;
166 kumaneko 111 int error = -ENOMEM;
167     const u16 hash = capability;
168     if (!domain) return -EINVAL;
169 kumaneko 652 mutex_lock(&domain_acl_lock);
170 kumaneko 514 if (!is_delete) {
171 kumaneko 722 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
172 kumaneko 712 acl = container_of(ptr, struct capability_acl_record, head);
173 kumaneko 708 if (ptr->type == TYPE_CAPABILITY_ACL && acl->capability == hash && ptr->cond == condition) {
174 kumaneko 111 ptr->is_deleted = 0;
175     /* Found. Nothing to do. */
176     error = 0;
177 kumaneko 708 goto out;
178 kumaneko 111 }
179     }
180 kumaneko 708 /* Not found. Append it to the tail. */
181     if ((acl = alloc_element(sizeof(*acl))) == NULL) goto out;
182     acl->head.type = TYPE_CAPABILITY_ACL;
183     acl->capability = hash;
184     acl->head.cond = condition;
185     error = AddDomainACL(domain, &acl->head);
186 kumaneko 111 } else {
187     error = -ENOENT;
188 kumaneko 722 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
189 kumaneko 712 acl = container_of(ptr, struct capability_acl_record, head);
190 kumaneko 708 if (ptr->type != TYPE_CAPABILITY_ACL || ptr->is_deleted || acl->capability != hash || ptr->cond != condition) continue;
191 kumaneko 111 error = DelDomainACL(ptr);
192     break;
193     }
194     }
195 kumaneko 708 out: ;
196 kumaneko 652 mutex_unlock(&domain_acl_lock);
197 kumaneko 111 return error;
198     }
199    
200     int CheckCapabilityACL(const unsigned int capability)
201     {
202     struct domain_info * const domain = current->domain_info;
203     struct acl_info *ptr;
204 kumaneko 621 const bool is_enforce = CheckCapabilityEnforce(capability);
205 kumaneko 111 const u16 hash = capability;
206     if (!CheckCapabilityFlags(capability)) return 0;
207 kumaneko 722 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
208 kumaneko 708 struct capability_acl_record *acl;
209 kumaneko 712 acl = container_of(ptr, struct capability_acl_record, head);
210 kumaneko 708 if (ptr->type != TYPE_CAPABILITY_ACL || ptr->is_deleted || acl->capability != hash || CheckCondition(ptr->cond, NULL)) continue;
211 kumaneko 111 AuditCapabilityLog(capability, 1);
212     return 0;
213     }
214     if (TomoyoVerboseMode()) {
215     printk("TOMOYO-%s: %s denied for %s\n", GetMSG(is_enforce), capability2name(capability), GetLastName(domain));
216     }
217     AuditCapabilityLog(capability, 0);
218     if (is_enforce) return CheckSupervisor("%s\n" KEYWORD_ALLOW_CAPABILITY "%s\n", domain->domainname->name, capability2keyword(capability));
219 kumaneko 514 if (CheckCapabilityAccept(capability, domain)) AddCapabilityACL(capability, domain, NULL, 0);
220 kumaneko 111 return 0;
221     }
222 kumaneko 223 EXPORT_SYMBOL(CheckCapabilityACL);
223 kumaneko 111
224 kumaneko 621 int AddCapabilityPolicy(char *data, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
225 kumaneko 111 {
226     unsigned int capability;
227     for (capability = 0; capability < TOMOYO_MAX_CAPABILITY_INDEX; capability++) {
228     if (strcmp(data, capability_control_array[capability].keyword) == 0) {
229 kumaneko 514 return AddCapabilityACL(capability, domain, condition, is_delete);
230 kumaneko 111 }
231     }
232     return -EINVAL;
233     }
234    
235     /***** TOMOYO Linux end. *****/

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