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 111 - (hide annotations) (download) (as text)
Wed Feb 28 11:45:08 2007 UTC (17 years, 3 months ago) by kumaneko
Original Path: trunk/ccs-patch/fs/tomoyo_capability.c
File MIME type: text/x-csrc
File size: 9499 byte(s)


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     * Version: 1.3.2 2007/02/14
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     /***** 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     extern struct semaphore domain_acl_lock;
23     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     };
60    
61     typedef struct {
62     unsigned char value[TOMOYO_MAX_CAPABILITY_INDEX];
63     } PROFILE;
64    
65     static PROFILE *profile_ptr[MAX_PROFILES];
66    
67     /************************* UTILITY FUNCTIONS *************************/
68    
69     const char *capability2keyword(const unsigned int capability)
70     {
71     return capability < TOMOYO_MAX_CAPABILITY_INDEX ? capability_control_array[capability].keyword : NULL;
72     }
73    
74     static const char *capability2name(const unsigned int capability)
75     {
76     return capability < TOMOYO_MAX_CAPABILITY_INDEX ? capability_control_array[capability].capability_name : NULL;
77     }
78    
79     /* Check whether the given capability control is enabled. */
80     static unsigned int CheckCapabilityFlags(const unsigned int index)
81     {
82     const u8 profile = current->domain_info->profile;
83     return sbin_init_started && index < TOMOYO_MAX_CAPABILITY_INDEX && profile < MAX_PROFILES && profile_ptr[profile] ? profile_ptr[profile]->value[index] : 0;
84     }
85    
86     /* Check whether the given capability control is enforce mode. */
87     static unsigned int CheckCapabilityEnforce(const unsigned int index)
88     {
89     return CheckCapabilityFlags(index) == 3;
90     }
91    
92     /* Check whether the given capability control is accept mode. */
93     static unsigned int CheckCapabilityAccept(const unsigned int index)
94     {
95     return CheckCapabilityFlags(index) == 1;
96     }
97    
98     static PROFILE *FindOrAssignNewProfile(const unsigned int profile)
99     {
100     static DECLARE_MUTEX(profile_lock);
101     PROFILE *ptr = NULL;
102     down(&profile_lock);
103     if (profile < MAX_PROFILES && (ptr = profile_ptr[profile]) == NULL) {
104     if ((ptr = (PROFILE *) alloc_element(sizeof(PROFILE))) != NULL) {
105     int i;
106     for (i = 0; i < TOMOYO_MAX_CAPABILITY_INDEX; i++) ptr->value[i] = capability_control_array[i].current_value;
107     mb(); /* Instead of using spinlock. */
108     profile_ptr[profile] = ptr;
109     }
110     }
111     up(&profile_lock);
112     return ptr;
113     }
114    
115     int SetCapabilityStatus(const char *data, unsigned int value, const unsigned int profile)
116     {
117     int i;
118     PROFILE *ptr = FindOrAssignNewProfile(profile);
119     if (!ptr) return -EINVAL;
120     for (i = 0; i < TOMOYO_MAX_CAPABILITY_INDEX; i++) {
121     if (strcmp(data, capability_control_array[i].keyword)) continue;
122     if (value > 3) value = 3;
123     ptr->value[i] = value;
124     return 0;
125     }
126     return -EINVAL;
127     }
128    
129     int ReadCapabilityStatus(IO_BUFFER *head)
130     {
131     int step;
132     for (step = head->read_step; step < MAX_PROFILES * TOMOYO_MAX_CAPABILITY_INDEX; step++) {
133     const int i = step / TOMOYO_MAX_CAPABILITY_INDEX, j = step % TOMOYO_MAX_CAPABILITY_INDEX;
134     const PROFILE *profile = profile_ptr[i];
135     head->read_step = step;
136     if (!profile) continue;
137     if (io_printf(head, "%u-" KEYWORD_MAC_FOR_CAPABILITY "%s=%u\n", i, capability_control_array[j].keyword, profile->value[j])) break;
138     }
139     return step < MAX_PROFILES * TOMOYO_MAX_CAPABILITY_INDEX ? -ENOMEM : 0;
140     }
141    
142     /************************* AUDIT FUNCTIONS *************************/
143    
144     #ifdef CONFIG_TOMOYO_AUDIT
145     static int AuditCapabilityLog(const unsigned int capability, const int is_granted)
146     {
147     char *buf;
148     int len = 64;
149     if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;
150     if ((buf = InitAuditLog(&len)) == NULL) return -ENOMEM;
151     snprintf(buf + strlen(buf), len - strlen(buf) - 1, KEYWORD_ALLOW_CAPABILITY "%s\n", capability2keyword(capability));
152     return WriteAuditLog(buf, is_granted);
153     }
154     #else
155     static inline void AuditCapabilityLog(const unsigned int capability, const int is_granted) {}
156     #endif
157    
158     /************************* CAPABILITY ACL HANDLER *************************/
159    
160     static int AddCapabilityACL(const unsigned int capability, struct domain_info *domain, const int is_delete, const struct condition_list *condition)
161     {
162     struct acl_info *ptr;
163     int error = -ENOMEM;
164     const u16 hash = capability;
165     if (!domain) return -EINVAL;
166     down(&domain_acl_lock);
167     if (!is_delete) {
168     if ((ptr = domain->first_acl_ptr) == NULL) goto first_entry;
169     while (1) {
170     CAPABILITY_ACL_RECORD *new_ptr;
171     if (ptr->type == TYPE_CAPABILITY_ACL && ptr->u.w == hash && ptr->cond == condition) {
172     ptr->is_deleted = 0;
173     /* Found. Nothing to do. */
174     error = 0;
175     break;
176     }
177     if (ptr->next) {
178     ptr = ptr->next;
179     continue;
180     }
181     first_entry: ;
182     /* Not found. Append it to the tail. */
183     if ((new_ptr = (CAPABILITY_ACL_RECORD *) alloc_element(sizeof(CAPABILITY_ACL_RECORD))) == NULL) break;
184     new_ptr->head.type = TYPE_CAPABILITY_ACL;
185     new_ptr->head.u.w = hash;
186     new_ptr->head.cond = condition;
187     error = AddDomainACL(ptr, domain, (struct acl_info *) new_ptr);
188     break;
189     }
190     } else {
191     error = -ENOENT;
192     for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
193     if (ptr->type != TYPE_CAPABILITY_ACL || ptr->is_deleted || ptr->u.w != hash || ptr->cond != condition) continue;
194     error = DelDomainACL(ptr);
195     break;
196     }
197     }
198     up(&domain_acl_lock);
199     return error;
200     }
201    
202     int CheckCapabilityACL(const unsigned int capability)
203     {
204     struct domain_info * const domain = current->domain_info;
205     struct acl_info *ptr;
206     const int is_enforce = CheckCapabilityEnforce(capability);
207     const u16 hash = capability;
208     if (!CheckCapabilityFlags(capability)) return 0;
209     for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
210     if (ptr->type != TYPE_CAPABILITY_ACL || ptr->is_deleted || ptr->u.w != hash || CheckCondition(ptr->cond, NULL)) continue;
211     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     if (CheckCapabilityAccept(capability)) AddCapabilityACL(capability, domain, 0, NULL);
220     return 0;
221     }
222    
223     int AddCapabilityPolicy(char *data, struct domain_info *domain, const int is_delete)
224     {
225     unsigned int capability;
226     const struct condition_list *condition = NULL;
227     char *cp = FindConditionPart(data);
228     if (cp && (condition = FindOrAssignNewCondition(cp)) == NULL) return -EINVAL;
229     for (capability = 0; capability < TOMOYO_MAX_CAPABILITY_INDEX; capability++) {
230     if (strcmp(data, capability_control_array[capability].keyword) == 0) {
231     return AddCapabilityACL(capability, domain, is_delete, condition);
232     }
233     }
234     return -EINVAL;
235     }
236    
237     EXPORT_SYMBOL(CheckCapabilityACL);
238    
239     /***** TOMOYO Linux end. *****/

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