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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3533 - (hide annotations) (download) (as text)
Thu Mar 25 05:48:40 2010 UTC (14 years, 2 months ago) by kumaneko
Original Path: trunk/1.7.x/ccs-patch/security/ccsecurity/memory.c
File MIME type: text/x-csrc
File size: 6972 byte(s)
Fix ccs_get_ipv6_address() bug.
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 3519 * Version: 1.7.2-pre 2010/03/21
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     struct ccs_ipv6addr_entry *ptr;
107     int error = -ENOMEM;
108     if (!addr)
109     return NULL;
110 kumaneko 3512 entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
111 kumaneko 2864 mutex_lock(&ccs_policy_lock);
112     list_for_each_entry(ptr, &ccs_address_list, list) {
113     if (memcmp(&ptr->addr, addr, sizeof(*addr)))
114     continue;
115     atomic_inc(&ptr->users);
116     error = 0;
117     break;
118     }
119     if (error && ccs_memory_ok(entry, sizeof(*entry))) {
120     ptr = entry;
121     ptr->addr = *addr;
122     atomic_set(&ptr->users, 1);
123     list_add_tail(&ptr->list, &ccs_address_list);
124     entry = NULL;
125 kumaneko 3533 error = 0;
126 kumaneko 2864 }
127     mutex_unlock(&ccs_policy_lock);
128     kfree(entry);
129 kumaneko 3533 return !error ? &ptr->addr : NULL;
130 kumaneko 2864 }
131    
132     /* The list for "struct ccs_name_entry". */
133 kumaneko 3131 struct list_head ccs_name_list[CCS_MAX_HASH];
134 kumaneko 2864
135     /**
136     * ccs_get_name - Allocate memory for string data.
137     *
138     * @name: The string to store into the permernent memory.
139     *
140     * Returns pointer to "struct ccs_path_info" on success, NULL otherwise.
141     */
142     const struct ccs_path_info *ccs_get_name(const char *name)
143     {
144     struct ccs_name_entry *ptr;
145     unsigned int hash;
146     int len;
147     int allocated_len;
148 kumaneko 3146 struct list_head *head;
149 kumaneko 2864
150     if (!name)
151     return NULL;
152     len = strlen(name) + 1;
153     hash = full_name_hash((const unsigned char *) name, len - 1);
154 kumaneko 3146 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
155     head = &ccs_name_list[hash_long(hash, CCS_HASH_BITS)];
156     #else
157     head = &ccs_name_list[hash % CCS_MAX_HASH];
158     #endif
159 kumaneko 3519 mutex_lock(&ccs_policy_lock);
160 kumaneko 3146 list_for_each_entry(ptr, head, list) {
161 kumaneko 2864 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
162     continue;
163     atomic_inc(&ptr->users);
164     goto out;
165     }
166 kumaneko 2900 allocated_len = ccs_round2(sizeof(*ptr) + len);
167 kumaneko 3512 ptr = kzalloc(allocated_len, CCS_GFP_FLAGS);
168 kumaneko 2903 if (!ptr || (ccs_quota_for_policy &&
169     atomic_read(&ccs_policy_memory_size) + allocated_len
170     > ccs_quota_for_policy)) {
171 kumaneko 2864 kfree(ptr);
172     ptr = NULL;
173 kumaneko 2908 ccs_warn_oom(__func__);
174 kumaneko 2864 goto out;
175     }
176 kumaneko 2903 atomic_add(allocated_len, &ccs_policy_memory_size);
177 kumaneko 2864 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
178     memmove((char *) ptr->entry.name, name, len);
179     atomic_set(&ptr->users, 1);
180     ccs_fill_path_info(&ptr->entry);
181     ptr->size = allocated_len;
182 kumaneko 3146 list_add_tail(&ptr->list, head);
183 kumaneko 2864 out:
184 kumaneko 3519 mutex_unlock(&ccs_policy_lock);
185 kumaneko 2864 return ptr ? &ptr->entry : NULL;
186     }
187    
188     /**
189 kumaneko 3078 * ccs_mm_init - Initialize mm related code.
190 kumaneko 2864 */
191 kumaneko 3502 void __init ccs_mm_init(void)
192 kumaneko 2864 {
193     int i;
194 kumaneko 2892 for (i = 0; i < CCS_MAX_HASH; i++)
195 kumaneko 2864 INIT_LIST_HEAD(&ccs_name_list[i]);
196     INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);
197     ccs_kernel_domain.domainname = ccs_get_name(ROOT_NAME);
198     list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);
199     if (ccs_find_domain(ROOT_NAME) != &ccs_kernel_domain)
200     panic("Can't register ccs_kernel_domain");
201     {
202     /* Load built-in policy. */
203     static char ccs_builtin_initializers[] __initdata
204     = CONFIG_CCSECURITY_BUILTIN_INITIALIZERS;
205     char *cp = ccs_builtin_initializers;
206     ccs_normalize_line(cp);
207     while (cp && *cp) {
208     char *cp2 = strchr(cp, ' ');
209     if (cp2)
210     *cp2++ = '\0';
211     ccs_write_domain_initializer_policy(cp, false, false);
212     cp = cp2;
213     }
214     }
215     }
216    
217     unsigned int ccs_audit_log_memory_size;
218     unsigned int ccs_quota_for_audit_log;
219    
220     unsigned int ccs_query_memory_size;
221     unsigned int ccs_quota_for_query;
222    
223     /**
224     * ccs_read_memory_counter - Check for memory usage.
225     *
226     * @head: Pointer to "struct ccs_io_buffer".
227     */
228 kumaneko 2943 void ccs_read_memory_counter(struct ccs_io_buffer *head)
229 kumaneko 2864 {
230 kumaneko 2943 const unsigned int usage[3] = {
231     atomic_read(&ccs_policy_memory_size),
232     ccs_audit_log_memory_size,
233     ccs_query_memory_size
234     };
235     const unsigned int quota[3] = {
236     ccs_quota_for_policy,
237     ccs_quota_for_audit_log,
238     ccs_quota_for_query
239     };
240     static const char *header[4] = {
241     "Policy: ",
242     "Audit logs: ",
243     "Query lists:",
244     "Total: "
245     };
246     unsigned int total = 0;
247     int i;
248     if (head->read_eof)
249     return;
250     for (i = 0; i < 3; i++) {
251     total += usage[i];
252     ccs_io_printf(head, "%s %10u", header[i], usage[i]);
253     if (quota[i])
254     ccs_io_printf(head, " (Quota: %10u)", quota[i]);
255     ccs_io_printf(head, "\n");
256 kumaneko 2864 }
257 kumaneko 2943 ccs_io_printf(head, "%s %10u\n", header[3], total);
258     head->read_eof = true;
259 kumaneko 2864 }
260    
261     /**
262     * ccs_write_memory_quota - Set memory quota.
263     *
264     * @head: Pointer to "struct ccs_io_buffer".
265     *
266     * Returns 0.
267     */
268     int ccs_write_memory_quota(struct ccs_io_buffer *head)
269     {
270     char *data = head->write_buf;
271     unsigned int size;
272 kumaneko 2903 if (sscanf(data, "Policy: %u", &size) == 1)
273     ccs_quota_for_policy = size;
274 kumaneko 2864 else if (sscanf(data, "Audit logs: %u", &size) == 1)
275     ccs_quota_for_audit_log = size;
276 kumaneko 2903 else if (sscanf(data, "Query lists: %u", &size) == 1)
277 kumaneko 2864 ccs_quota_for_query = size;
278     return 0;
279     }

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