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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3560 - (show annotations) (download) (as text)
Wed Mar 31 13:13:57 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: 7104 byte(s)
1.7.2-rc
1 /*
2 * security/ccsecurity/memory.c
3 *
4 * Copyright (C) 2005-2010 NTT DATA CORPORATION
5 *
6 * Version: 1.7.2-rc 2010/03/31
7 *
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 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
15 #include <linux/hash.h>
16 #endif
17
18 void ccs_warn_oom(const char *function)
19 {
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 static atomic_t ccs_policy_memory_size;
33 static unsigned int ccs_quota_for_policy;
34
35 /**
36 * ccs_memory_ok - Check memory quota.
37 *
38 * @ptr: Pointer to allocated memory.
39 * @size: Size in byte.
40 *
41 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
42 */
43 bool ccs_memory_ok(const void *ptr, const unsigned int size)
44 {
45 size_t s = ccs_round2(size);
46 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 return true;
51 atomic_sub(s, &ccs_policy_memory_size);
52 ccs_warn_oom(__func__);
53 return false;
54 }
55
56 /**
57 * ccs_commit_ok - Allocate memory and check memory quota.
58 *
59 * @data: Data to copy from.
60 * @size: Size in byte.
61 *
62 * Returns pointer to allocated memory on success, NULL otherwise.
63 * @data is zero-cleared on success.
64 */
65 void *ccs_commit_ok(void *data, const unsigned int size)
66 {
67 void *ptr = kmalloc(size, CCS_GFP_FLAGS);
68 if (!ptr)
69 return NULL;
70 if (ccs_memory_ok(ptr, size)) {
71 memmove(ptr, data, size);
72 memset(data, 0, size);
73 return ptr;
74 }
75 kfree(ptr);
76 return NULL;
77 }
78
79
80 /**
81 * ccs_memory_free - Free memory for elements.
82 *
83 * @ptr: Pointer to allocated memory.
84 * @size: Size in byte.
85 */
86 void ccs_memory_free(const void *ptr, size_t size)
87 {
88 atomic_sub(ccs_round2(size), &ccs_policy_memory_size);
89 kfree(ptr);
90 }
91
92 LIST_HEAD(ccs_address_list);
93
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 = NULL;
107 int error = -ENOMEM;
108 if (!addr)
109 return NULL;
110 entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
111 if (mutex_lock_interruptible(&ccs_policy_lock))
112 goto out;
113 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 error = 0;
127 }
128 mutex_unlock(&ccs_policy_lock);
129 out:
130 kfree(entry);
131 return !error ? &ptr->addr : NULL;
132 }
133
134 /* The list for "struct ccs_name_entry". */
135 struct list_head ccs_name_list[CCS_MAX_HASH];
136
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 struct list_head *head;
151
152 if (!name)
153 return NULL;
154 len = strlen(name) + 1;
155 hash = full_name_hash((const unsigned char *) name, len - 1);
156 #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 if (mutex_lock_interruptible(&ccs_policy_lock))
162 return NULL;
163 list_for_each_entry(ptr, head, list) {
164 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
165 continue;
166 atomic_inc(&ptr->users);
167 goto out;
168 }
169 allocated_len = ccs_round2(sizeof(*ptr) + len);
170 ptr = kzalloc(allocated_len, CCS_GFP_FLAGS);
171 if (!ptr || (ccs_quota_for_policy &&
172 atomic_read(&ccs_policy_memory_size) + allocated_len
173 > ccs_quota_for_policy)) {
174 kfree(ptr);
175 ptr = NULL;
176 ccs_warn_oom(__func__);
177 goto out;
178 }
179 atomic_add(allocated_len, &ccs_policy_memory_size);
180 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 list_add_tail(&ptr->list, head);
186 out:
187 mutex_unlock(&ccs_policy_lock);
188 return ptr ? &ptr->entry : NULL;
189 }
190
191 /**
192 * ccs_mm_init - Initialize mm related code.
193 */
194 void __init ccs_mm_init(void)
195 {
196 int idx;
197 for (idx = 0; idx < CCS_MAX_HASH; idx++)
198 INIT_LIST_HEAD(&ccs_name_list[idx]);
199 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 idx = ccs_read_lock();
203 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 ccs_read_unlock(idx);
220 }
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 void ccs_read_memory_counter(struct ccs_io_buffer *head)
234 {
235 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 }
262 ccs_io_printf(head, "%s %10u\n", header[3], total);
263 head->read_eof = true;
264 }
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 if (sscanf(data, "Policy: %u", &size) == 1)
278 ccs_quota_for_policy = size;
279 else if (sscanf(data, "Audit logs: %u", &size) == 1)
280 ccs_quota_for_audit_log = size;
281 else if (sscanf(data, "Query lists: %u", &size) == 1)
282 ccs_quota_for_query = size;
283 return 0;
284 }

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