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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3561 - (hide annotations) (download) (as text)
Thu Apr 1 05:04:44 2010 UTC (14 years, 1 month ago) by kumaneko
Original Path: trunk/1.7.x/ccs-patch/security/ccsecurity/memory.c
File MIME type: text/x-csrc
File size: 7101 byte(s)


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 3561 * Version: 1.7.2 2010/04/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 2932 void ccs_warn_oom(const char *function)
19 kumaneko 2908 {
20     /* Reduce error messages. */
21     static pid_t ccs_last_pid;
22     const pid_t pid = current->pid;
23     if (ccs_last_pid != pid) {
24     printk(KERN_WARNING "ERROR: Out of memory at %s.\n",
25     function);
26     ccs_last_pid = pid;
27     }
28     if (!ccs_policy_loaded)
29     panic("MAC Initialization failed.\n");
30     }
31    
32 kumaneko 2903 static atomic_t ccs_policy_memory_size;
33     static unsigned int ccs_quota_for_policy;
34 kumaneko 2864
35     /**
36     * ccs_memory_ok - Check memory quota.
37     *
38     * @ptr: Pointer to allocated memory.
39     * @size: Size in byte.
40     *
41 kumaneko 3104 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
42 kumaneko 2864 */
43     bool ccs_memory_ok(const void *ptr, const unsigned int size)
44     {
45 kumaneko 2900 size_t s = ccs_round2(size);
46 kumaneko 2903 atomic_add(s, &ccs_policy_memory_size);
47     if (ptr && (!ccs_quota_for_policy ||
48     atomic_read(&ccs_policy_memory_size)
49     <= ccs_quota_for_policy))
50 kumaneko 2864 return true;
51 kumaneko 2903 atomic_sub(s, &ccs_policy_memory_size);
52 kumaneko 2908 ccs_warn_oom(__func__);
53 kumaneko 2864 return false;
54     }
55    
56     /**
57 kumaneko 3512 * ccs_commit_ok - Allocate memory and check memory quota.
58 kumaneko 2864 *
59 kumaneko 2900 * @data: Data to copy from.
60     * @size: Size in byte.
61 kumaneko 2864 *
62 kumaneko 3512 * Returns pointer to allocated memory on success, NULL otherwise.
63     * @data is zero-cleared on success.
64 kumaneko 2864 */
65 kumaneko 3512 void *ccs_commit_ok(void *data, const unsigned int size)
66 kumaneko 2864 {
67 kumaneko 3512 void *ptr = kmalloc(size, CCS_GFP_FLAGS);
68     if (!ptr)
69     return NULL;
70 kumaneko 2900 if (ccs_memory_ok(ptr, size)) {
71     memmove(ptr, data, size);
72     memset(data, 0, size);
73 kumaneko 3512 return ptr;
74 kumaneko 2864 }
75 kumaneko 3512 kfree(ptr);
76     return NULL;
77 kumaneko 2864 }
78    
79    
80     /**
81 kumaneko 2900 * ccs_memory_free - Free memory for elements.
82 kumaneko 2864 *
83 kumaneko 2900 * @ptr: Pointer to allocated memory.
84     * @size: Size in byte.
85 kumaneko 2864 */
86 kumaneko 2900 void ccs_memory_free(const void *ptr, size_t size)
87 kumaneko 2864 {
88 kumaneko 2903 atomic_sub(ccs_round2(size), &ccs_policy_memory_size);
89 kumaneko 2900 kfree(ptr);
90 kumaneko 2864 }
91    
92 kumaneko 3131 LIST_HEAD(ccs_address_list);
93 kumaneko 2864
94     /**
95     * ccs_get_ipv6_address - Keep the given IPv6 address on the RAM.
96     *
97     * @addr: Pointer to "struct in6_addr".
98     *
99     * Returns pointer to "struct in6_addr" on success, NULL otherwise.
100     *
101     * The RAM is shared, so NEVER try to modify or kfree() the returned address.
102     */
103     const struct in6_addr *ccs_get_ipv6_address(const struct in6_addr *addr)
104     {
105     struct ccs_ipv6addr_entry *entry;
106 kumaneko 3534 struct ccs_ipv6addr_entry *ptr = NULL;
107 kumaneko 2864 int error = -ENOMEM;
108     if (!addr)
109     return NULL;
110 kumaneko 3512 entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
111 kumaneko 3534 if (mutex_lock_interruptible(&ccs_policy_lock))
112     goto out;
113 kumaneko 2864 list_for_each_entry(ptr, &ccs_address_list, list) {
114     if (memcmp(&ptr->addr, addr, sizeof(*addr)))
115     continue;
116     atomic_inc(&ptr->users);
117     error = 0;
118     break;
119     }
120     if (error && ccs_memory_ok(entry, sizeof(*entry))) {
121     ptr = entry;
122     ptr->addr = *addr;
123     atomic_set(&ptr->users, 1);
124     list_add_tail(&ptr->list, &ccs_address_list);
125     entry = NULL;
126 kumaneko 3533 error = 0;
127 kumaneko 2864 }
128     mutex_unlock(&ccs_policy_lock);
129 kumaneko 3534 out:
130 kumaneko 2864 kfree(entry);
131 kumaneko 3533 return !error ? &ptr->addr : NULL;
132 kumaneko 2864 }
133    
134     /* The list for "struct ccs_name_entry". */
135 kumaneko 3131 struct list_head ccs_name_list[CCS_MAX_HASH];
136 kumaneko 2864
137     /**
138     * ccs_get_name - Allocate memory for string data.
139     *
140     * @name: The string to store into the permernent memory.
141     *
142     * Returns pointer to "struct ccs_path_info" on success, NULL otherwise.
143     */
144     const struct ccs_path_info *ccs_get_name(const char *name)
145     {
146     struct ccs_name_entry *ptr;
147     unsigned int hash;
148     int len;
149     int allocated_len;
150 kumaneko 3146 struct list_head *head;
151 kumaneko 2864
152     if (!name)
153     return NULL;
154     len = strlen(name) + 1;
155     hash = full_name_hash((const unsigned char *) name, len - 1);
156 kumaneko 3146 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
157     head = &ccs_name_list[hash_long(hash, CCS_HASH_BITS)];
158     #else
159     head = &ccs_name_list[hash % CCS_MAX_HASH];
160     #endif
161 kumaneko 3534 if (mutex_lock_interruptible(&ccs_policy_lock))
162     return NULL;
163 kumaneko 3146 list_for_each_entry(ptr, head, list) {
164 kumaneko 2864 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
165     continue;
166     atomic_inc(&ptr->users);
167     goto out;
168     }
169 kumaneko 2900 allocated_len = ccs_round2(sizeof(*ptr) + len);
170 kumaneko 3512 ptr = kzalloc(allocated_len, CCS_GFP_FLAGS);
171 kumaneko 2903 if (!ptr || (ccs_quota_for_policy &&
172     atomic_read(&ccs_policy_memory_size) + allocated_len
173     > ccs_quota_for_policy)) {
174 kumaneko 2864 kfree(ptr);
175     ptr = NULL;
176 kumaneko 2908 ccs_warn_oom(__func__);
177 kumaneko 2864 goto out;
178     }
179 kumaneko 2903 atomic_add(allocated_len, &ccs_policy_memory_size);
180 kumaneko 2864 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
181     memmove((char *) ptr->entry.name, name, len);
182     atomic_set(&ptr->users, 1);
183     ccs_fill_path_info(&ptr->entry);
184     ptr->size = allocated_len;
185 kumaneko 3146 list_add_tail(&ptr->list, head);
186 kumaneko 2864 out:
187 kumaneko 3519 mutex_unlock(&ccs_policy_lock);
188 kumaneko 2864 return ptr ? &ptr->entry : NULL;
189     }
190    
191     /**
192 kumaneko 3078 * ccs_mm_init - Initialize mm related code.
193 kumaneko 2864 */
194 kumaneko 3502 void __init ccs_mm_init(void)
195 kumaneko 2864 {
196 kumaneko 3535 int idx;
197     for (idx = 0; idx < CCS_MAX_HASH; idx++)
198     INIT_LIST_HEAD(&ccs_name_list[idx]);
199 kumaneko 2864 INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);
200     ccs_kernel_domain.domainname = ccs_get_name(ROOT_NAME);
201     list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);
202 kumaneko 3535 idx = ccs_read_lock();
203 kumaneko 2864 if (ccs_find_domain(ROOT_NAME) != &ccs_kernel_domain)
204     panic("Can't register ccs_kernel_domain");
205     {
206     /* Load built-in policy. */
207     static char ccs_builtin_initializers[] __initdata
208     = CONFIG_CCSECURITY_BUILTIN_INITIALIZERS;
209     char *cp = ccs_builtin_initializers;
210     ccs_normalize_line(cp);
211     while (cp && *cp) {
212     char *cp2 = strchr(cp, ' ');
213     if (cp2)
214     *cp2++ = '\0';
215     ccs_write_domain_initializer_policy(cp, false, false);
216     cp = cp2;
217     }
218     }
219 kumaneko 3535 ccs_read_unlock(idx);
220 kumaneko 2864 }
221    
222     unsigned int ccs_audit_log_memory_size;
223     unsigned int ccs_quota_for_audit_log;
224    
225     unsigned int ccs_query_memory_size;
226     unsigned int ccs_quota_for_query;
227    
228     /**
229     * ccs_read_memory_counter - Check for memory usage.
230     *
231     * @head: Pointer to "struct ccs_io_buffer".
232     */
233 kumaneko 2943 void ccs_read_memory_counter(struct ccs_io_buffer *head)
234 kumaneko 2864 {
235 kumaneko 2943 const unsigned int usage[3] = {
236     atomic_read(&ccs_policy_memory_size),
237     ccs_audit_log_memory_size,
238     ccs_query_memory_size
239     };
240     const unsigned int quota[3] = {
241     ccs_quota_for_policy,
242     ccs_quota_for_audit_log,
243     ccs_quota_for_query
244     };
245     static const char *header[4] = {
246     "Policy: ",
247     "Audit logs: ",
248     "Query lists:",
249     "Total: "
250     };
251     unsigned int total = 0;
252     int i;
253     if (head->read_eof)
254     return;
255     for (i = 0; i < 3; i++) {
256     total += usage[i];
257     ccs_io_printf(head, "%s %10u", header[i], usage[i]);
258     if (quota[i])
259     ccs_io_printf(head, " (Quota: %10u)", quota[i]);
260     ccs_io_printf(head, "\n");
261 kumaneko 2864 }
262 kumaneko 2943 ccs_io_printf(head, "%s %10u\n", header[3], total);
263     head->read_eof = true;
264 kumaneko 2864 }
265    
266     /**
267     * ccs_write_memory_quota - Set memory quota.
268     *
269     * @head: Pointer to "struct ccs_io_buffer".
270     *
271     * Returns 0.
272     */
273     int ccs_write_memory_quota(struct ccs_io_buffer *head)
274     {
275     char *data = head->write_buf;
276     unsigned int size;
277 kumaneko 2903 if (sscanf(data, "Policy: %u", &size) == 1)
278     ccs_quota_for_policy = size;
279 kumaneko 2864 else if (sscanf(data, "Audit logs: %u", &size) == 1)
280     ccs_quota_for_audit_log = size;
281 kumaneko 2903 else if (sscanf(data, "Query lists: %u", &size) == 1)
282 kumaneko 2864 ccs_quota_for_query = size;
283     return 0;
284     }

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