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

Subversion リポジトリの参照

Annotation of /trunk/1.8.x/ccs-patch/security/ccsecurity/memory.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3924 - (hide annotations) (download) (as text)
Thu Aug 26 11:01:19 2010 UTC (13 years, 8 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 8682 byte(s)
Replace task.state[] with auto_domain_transition .
1 kumaneko 2864 /*
2 kumaneko 3033 * security/ccsecurity/memory.c
3 kumaneko 2864 *
4 kumaneko 3502 * Copyright (C) 2005-2010 NTT DATA CORPORATION
5 kumaneko 2864 *
6 kumaneko 3871 * Version: 1.8.0-pre 2010/08/01
7 kumaneko 2864 *
8     * This file is applicable to both 2.4.30 and 2.6.11 and later.
9     * See README.ccs for ChangeLog.
10     *
11     */
12    
13     #include "internal.h"
14 kumaneko 3146 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
15     #include <linux/hash.h>
16     #endif
17 kumaneko 2864
18 kumaneko 3643 /**
19     * ccs_warn_oom - Print out of memory warning message.
20     *
21     * @function: Function's name.
22     */
23 kumaneko 2932 void ccs_warn_oom(const char *function)
24 kumaneko 2908 {
25     /* Reduce error messages. */
26     static pid_t ccs_last_pid;
27     const pid_t pid = current->pid;
28     if (ccs_last_pid != pid) {
29     printk(KERN_WARNING "ERROR: Out of memory at %s.\n",
30     function);
31     ccs_last_pid = pid;
32     }
33     if (!ccs_policy_loaded)
34     panic("MAC Initialization failed.\n");
35     }
36    
37 kumaneko 3643 /* Memory allocated for policy. */
38 kumaneko 2903 static atomic_t ccs_policy_memory_size;
39 kumaneko 3643 /* Quota for holding policy. */
40 kumaneko 2903 static unsigned int ccs_quota_for_policy;
41 kumaneko 2864
42     /**
43     * ccs_memory_ok - Check memory quota.
44     *
45     * @ptr: Pointer to allocated memory.
46     * @size: Size in byte.
47     *
48 kumaneko 3104 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
49 kumaneko 2864 */
50     bool ccs_memory_ok(const void *ptr, const unsigned int size)
51     {
52 kumaneko 2900 size_t s = ccs_round2(size);
53 kumaneko 2903 atomic_add(s, &ccs_policy_memory_size);
54     if (ptr && (!ccs_quota_for_policy ||
55     atomic_read(&ccs_policy_memory_size)
56     <= ccs_quota_for_policy))
57 kumaneko 2864 return true;
58 kumaneko 2903 atomic_sub(s, &ccs_policy_memory_size);
59 kumaneko 2908 ccs_warn_oom(__func__);
60 kumaneko 2864 return false;
61     }
62    
63     /**
64 kumaneko 3512 * ccs_commit_ok - Allocate memory and check memory quota.
65 kumaneko 2864 *
66 kumaneko 2900 * @data: Data to copy from.
67     * @size: Size in byte.
68 kumaneko 2864 *
69 kumaneko 3512 * Returns pointer to allocated memory on success, NULL otherwise.
70     * @data is zero-cleared on success.
71 kumaneko 2864 */
72 kumaneko 3512 void *ccs_commit_ok(void *data, const unsigned int size)
73 kumaneko 2864 {
74 kumaneko 3512 void *ptr = kmalloc(size, CCS_GFP_FLAGS);
75 kumaneko 2900 if (ccs_memory_ok(ptr, size)) {
76     memmove(ptr, data, size);
77     memset(data, 0, size);
78 kumaneko 3512 return ptr;
79 kumaneko 2864 }
80 kumaneko 3512 kfree(ptr);
81     return NULL;
82 kumaneko 2864 }
83    
84     /**
85 kumaneko 2900 * ccs_memory_free - Free memory for elements.
86 kumaneko 2864 *
87 kumaneko 2900 * @ptr: Pointer to allocated memory.
88     * @size: Size in byte.
89 kumaneko 2864 */
90 kumaneko 2900 void ccs_memory_free(const void *ptr, size_t size)
91 kumaneko 2864 {
92 kumaneko 2903 atomic_sub(ccs_round2(size), &ccs_policy_memory_size);
93 kumaneko 2900 kfree(ptr);
94 kumaneko 2864 }
95    
96 kumaneko 3689 /**
97     * ccs_get_group - Allocate memory for "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group".
98     *
99     * @group_name: The name of address group.
100     * @idx: Index number.
101     *
102     * Returns pointer to "struct ccs_group" on success, NULL otherwise.
103     */
104     struct ccs_group *ccs_get_group(const char *group_name, const u8 idx)
105     {
106 kumaneko 3697 struct ccs_group e = { };
107 kumaneko 3689 struct ccs_group *group = NULL;
108 kumaneko 3697 bool found = false;
109 kumaneko 3707 if (!ccs_correct_word(group_name) || idx >= CCS_MAX_GROUP)
110 kumaneko 3689 return NULL;
111 kumaneko 3697 e.group_name = ccs_get_name(group_name);
112     if (!e.group_name)
113 kumaneko 3689 return NULL;
114     if (mutex_lock_interruptible(&ccs_policy_lock))
115     goto out;
116 kumaneko 3697 list_for_each_entry(group, &ccs_group_list[idx], head.list) {
117     if (e.group_name != group->group_name)
118 kumaneko 3689 continue;
119     atomic_inc(&group->head.users);
120 kumaneko 3697 found = true;
121 kumaneko 3689 break;
122     }
123 kumaneko 3697 if (!found) {
124     struct ccs_group *entry = ccs_commit_ok(&e, sizeof(e));
125     if (entry) {
126     INIT_LIST_HEAD(&entry->member_list);
127     atomic_set(&entry->head.users, 1);
128     list_add_tail_rcu(&entry->head.list,
129     &ccs_group_list[idx]);
130     group = entry;
131     found = true;
132     }
133 kumaneko 3689 }
134     mutex_unlock(&ccs_policy_lock);
135     out:
136 kumaneko 3697 ccs_put_name(e.group_name);
137     return found ? group : NULL;
138 kumaneko 3689 }
139 kumaneko 2864
140     /**
141     * ccs_get_ipv6_address - Keep the given IPv6 address on the RAM.
142     *
143     * @addr: Pointer to "struct in6_addr".
144     *
145     * Returns pointer to "struct in6_addr" on success, NULL otherwise.
146     *
147     * The RAM is shared, so NEVER try to modify or kfree() the returned address.
148     */
149     const struct in6_addr *ccs_get_ipv6_address(const struct in6_addr *addr)
150     {
151 kumaneko 3693 struct ccs_ipv6addr *entry;
152     struct ccs_ipv6addr *ptr = NULL;
153 kumaneko 2864 int error = -ENOMEM;
154     if (!addr)
155     return NULL;
156 kumaneko 3512 entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
157 kumaneko 3534 if (mutex_lock_interruptible(&ccs_policy_lock))
158     goto out;
159 kumaneko 3689 list_for_each_entry(ptr, &ccs_shared_list[CCS_IPV6ADDRESS_LIST],
160     head.list) {
161 kumaneko 2864 if (memcmp(&ptr->addr, addr, sizeof(*addr)))
162     continue;
163 kumaneko 3689 atomic_inc(&ptr->head.users);
164 kumaneko 2864 error = 0;
165     break;
166     }
167     if (error && ccs_memory_ok(entry, sizeof(*entry))) {
168     ptr = entry;
169     ptr->addr = *addr;
170 kumaneko 3689 atomic_set(&ptr->head.users, 1);
171     list_add_tail(&ptr->head.list,
172     &ccs_shared_list[CCS_IPV6ADDRESS_LIST]);
173 kumaneko 2864 entry = NULL;
174 kumaneko 3533 error = 0;
175 kumaneko 2864 }
176     mutex_unlock(&ccs_policy_lock);
177 kumaneko 3534 out:
178 kumaneko 2864 kfree(entry);
179 kumaneko 3533 return !error ? &ptr->addr : NULL;
180 kumaneko 2864 }
181    
182 kumaneko 3693 /* The list for "struct ccs_name". */
183 kumaneko 3131 struct list_head ccs_name_list[CCS_MAX_HASH];
184 kumaneko 2864
185     /**
186     * ccs_get_name - Allocate memory for string data.
187     *
188     * @name: The string to store into the permernent memory.
189     *
190     * Returns pointer to "struct ccs_path_info" on success, NULL otherwise.
191     */
192     const struct ccs_path_info *ccs_get_name(const char *name)
193     {
194 kumaneko 3693 struct ccs_name *ptr;
195 kumaneko 2864 unsigned int hash;
196     int len;
197     int allocated_len;
198 kumaneko 3146 struct list_head *head;
199 kumaneko 2864
200     if (!name)
201     return NULL;
202     len = strlen(name) + 1;
203     hash = full_name_hash((const unsigned char *) name, len - 1);
204 kumaneko 3146 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
205     head = &ccs_name_list[hash_long(hash, CCS_HASH_BITS)];
206     #else
207     head = &ccs_name_list[hash % CCS_MAX_HASH];
208     #endif
209 kumaneko 3534 if (mutex_lock_interruptible(&ccs_policy_lock))
210     return NULL;
211 kumaneko 3689 list_for_each_entry(ptr, head, head.list) {
212 kumaneko 2864 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
213     continue;
214 kumaneko 3689 atomic_inc(&ptr->head.users);
215 kumaneko 2864 goto out;
216     }
217 kumaneko 3697 allocated_len = sizeof(*ptr) + len;
218 kumaneko 3512 ptr = kzalloc(allocated_len, CCS_GFP_FLAGS);
219 kumaneko 3697 if (ccs_memory_ok(ptr, allocated_len)) {
220     ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
221     memmove((char *) ptr->entry.name, name, len);
222     atomic_set(&ptr->head.users, 1);
223     ccs_fill_path_info(&ptr->entry);
224     ptr->size = allocated_len;
225     list_add_tail(&ptr->head.list, head);
226     } else {
227 kumaneko 2864 kfree(ptr);
228     ptr = NULL;
229     }
230     out:
231 kumaneko 3519 mutex_unlock(&ccs_policy_lock);
232 kumaneko 2864 return ptr ? &ptr->entry : NULL;
233     }
234    
235     /**
236 kumaneko 3078 * ccs_mm_init - Initialize mm related code.
237 kumaneko 2864 */
238 kumaneko 3502 void __init ccs_mm_init(void)
239 kumaneko 2864 {
240 kumaneko 3535 int idx;
241     for (idx = 0; idx < CCS_MAX_HASH; idx++)
242     INIT_LIST_HEAD(&ccs_name_list[idx]);
243 kumaneko 3924 for (idx = 0; idx < CCS_MAX_ACL_GROUPS; idx++) {
244     INIT_LIST_HEAD(&ccs_acl_group[idx].acl_info_list[0]);
245     INIT_LIST_HEAD(&ccs_acl_group[idx].acl_info_list[1]);
246     }
247     INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list[0]);
248     INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list[1]);
249 kumaneko 3707 ccs_kernel_domain.domainname = ccs_get_name(CCS_ROOT_NAME);
250 kumaneko 2864 list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);
251 kumaneko 3535 idx = ccs_read_lock();
252 kumaneko 3707 if (ccs_find_domain(CCS_ROOT_NAME) != &ccs_kernel_domain)
253 kumaneko 2864 panic("Can't register ccs_kernel_domain");
254     {
255     /* Load built-in policy. */
256     static char ccs_builtin_initializers[] __initdata
257     = CONFIG_CCSECURITY_BUILTIN_INITIALIZERS;
258     char *cp = ccs_builtin_initializers;
259     ccs_normalize_line(cp);
260     while (cp && *cp) {
261     char *cp2 = strchr(cp, ' ');
262     if (cp2)
263     *cp2++ = '\0';
264 kumaneko 3752 ccs_write_transition_control(cp, false,
265     CCS_TRANSITION_CONTROL_INITIALIZE);
266 kumaneko 2864 cp = cp2;
267     }
268     }
269 kumaneko 3535 ccs_read_unlock(idx);
270 kumaneko 2864 }
271    
272 kumaneko 3643 /* Memory allocated for audit logs. */
273 kumaneko 3694 unsigned int ccs_log_memory_size;
274 kumaneko 3643 /* Quota for holding audit logs. */
275 kumaneko 3694 unsigned int ccs_quota_for_log;
276 kumaneko 2864
277 kumaneko 3643 /* Memory allocated for query lists. */
278 kumaneko 2864 unsigned int ccs_query_memory_size;
279 kumaneko 3643 /* Quota for holding query lists. */
280 kumaneko 2864 unsigned int ccs_quota_for_query;
281    
282     /**
283     * ccs_read_memory_counter - Check for memory usage.
284     *
285     * @head: Pointer to "struct ccs_io_buffer".
286     */
287 kumaneko 2943 void ccs_read_memory_counter(struct ccs_io_buffer *head)
288 kumaneko 2864 {
289 kumaneko 2943 const unsigned int usage[3] = {
290     atomic_read(&ccs_policy_memory_size),
291 kumaneko 3694 ccs_log_memory_size,
292 kumaneko 2943 ccs_query_memory_size
293     };
294     const unsigned int quota[3] = {
295     ccs_quota_for_policy,
296 kumaneko 3694 ccs_quota_for_log,
297 kumaneko 2943 ccs_quota_for_query
298     };
299     static const char *header[4] = {
300     "Policy: ",
301     "Audit logs: ",
302     "Query lists:",
303     "Total: "
304     };
305     unsigned int total = 0;
306     int i;
307 kumaneko 3780 if (head->r.eof)
308 kumaneko 2943 return;
309     for (i = 0; i < 3; i++) {
310     total += usage[i];
311     ccs_io_printf(head, "%s %10u", header[i], usage[i]);
312     if (quota[i])
313     ccs_io_printf(head, " (Quota: %10u)", quota[i]);
314     ccs_io_printf(head, "\n");
315 kumaneko 2864 }
316 kumaneko 2943 ccs_io_printf(head, "%s %10u\n", header[3], total);
317 kumaneko 3780 head->r.eof = true;
318 kumaneko 2864 }
319    
320     /**
321     * ccs_write_memory_quota - Set memory quota.
322     *
323     * @head: Pointer to "struct ccs_io_buffer".
324     *
325     * Returns 0.
326     */
327     int ccs_write_memory_quota(struct ccs_io_buffer *head)
328     {
329     char *data = head->write_buf;
330     unsigned int size;
331 kumaneko 2903 if (sscanf(data, "Policy: %u", &size) == 1)
332     ccs_quota_for_policy = size;
333 kumaneko 2864 else if (sscanf(data, "Audit logs: %u", &size) == 1)
334 kumaneko 3694 ccs_quota_for_log = size;
335 kumaneko 2903 else if (sscanf(data, "Query lists: %u", &size) == 1)
336 kumaneko 2864 ccs_quota_for_query = size;
337     return 0;
338     }

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