2 * security/tomoyo/memory.c
4 * Memory management functions for TOMOYO.
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
9 #include <linux/hash.h>
10 #include <linux/slab.h>
14 * tomoyo_warn_oom - Print out of memory warning message.
16 * @function: Function's name.
18 void tomoyo_warn_oom(const char *function
)
20 /* Reduce error messages. */
21 static pid_t tomoyo_last_pid
;
22 const pid_t pid
= current
->pid
;
23 if (tomoyo_last_pid
!= pid
) {
24 printk(KERN_WARNING
"ERROR: Out of memory at %s.\n",
26 tomoyo_last_pid
= pid
;
28 if (!tomoyo_policy_loaded
)
29 panic("MAC Initialization failed.\n");
32 /* Memoy currently used by policy/audit log/query. */
33 unsigned int tomoyo_memory_used
[TOMOYO_MAX_MEMORY_STAT
];
34 /* Memory quota for "policy"/"audit log"/"query". */
35 unsigned int tomoyo_memory_quota
[TOMOYO_MAX_MEMORY_STAT
];
37 /* Memory allocated for policy. */
38 static atomic_t tomoyo_policy_memory_size
;
39 /* Quota for holding policy. */
40 static unsigned int tomoyo_quota_for_policy
;
43 * tomoyo_memory_ok - Check memory quota.
45 * @ptr: Pointer to allocated memory.
47 * Returns true on success, false otherwise.
49 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
51 bool tomoyo_memory_ok(void *ptr
)
53 size_t s
= ptr
? ksize(ptr
) : 0;
54 atomic_add(s
, &tomoyo_policy_memory_size
);
55 if (ptr
&& (!tomoyo_quota_for_policy
||
56 atomic_read(&tomoyo_policy_memory_size
)
57 <= tomoyo_quota_for_policy
)) {
61 atomic_sub(s
, &tomoyo_policy_memory_size
);
62 tomoyo_warn_oom(__func__
);
67 * tomoyo_commit_ok - Check memory quota.
69 * @data: Data to copy from.
70 * @size: Size in byte.
72 * Returns pointer to allocated memory on success, NULL otherwise.
73 * @data is zero-cleared on success.
75 void *tomoyo_commit_ok(void *data
, const unsigned int size
)
77 void *ptr
= kzalloc(size
, GFP_NOFS
);
78 if (tomoyo_memory_ok(ptr
)) {
79 memmove(ptr
, data
, size
);
80 memset(data
, 0, size
);
88 * tomoyo_memory_free - Free memory for elements.
90 * @ptr: Pointer to allocated memory.
92 void tomoyo_memory_free(void *ptr
)
94 atomic_sub(ksize(ptr
), &tomoyo_policy_memory_size
);
99 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
101 * @param: Pointer to "struct tomoyo_acl_param".
102 * @idx: Index number.
104 * Returns pointer to "struct tomoyo_group" on success, NULL otherwise.
106 struct tomoyo_group
*tomoyo_get_group(struct tomoyo_acl_param
*param
,
109 struct tomoyo_group e
= { };
110 struct tomoyo_group
*group
= NULL
;
111 struct list_head
*list
;
112 const char *group_name
= tomoyo_read_token(param
);
114 if (!tomoyo_correct_word(group_name
) || idx
>= TOMOYO_MAX_GROUP
)
116 e
.group_name
= tomoyo_get_name(group_name
);
119 if (mutex_lock_interruptible(&tomoyo_policy_lock
))
121 list
= &tomoyo_group_list
[idx
];
122 list_for_each_entry(group
, list
, head
.list
) {
123 if (e
.group_name
!= group
->group_name
)
125 atomic_inc(&group
->head
.users
);
130 struct tomoyo_group
*entry
= tomoyo_commit_ok(&e
, sizeof(e
));
132 INIT_LIST_HEAD(&entry
->member_list
);
133 atomic_set(&entry
->head
.users
, 1);
134 list_add_tail_rcu(&entry
->head
.list
, list
);
139 mutex_unlock(&tomoyo_policy_lock
);
141 tomoyo_put_name(e
.group_name
);
142 return found
? group
: NULL
;
146 * tomoyo_name_list is used for holding string data used by TOMOYO.
147 * Since same string data is likely used for multiple times (e.g.
148 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
149 * "const struct tomoyo_path_info *".
151 struct list_head tomoyo_name_list
[TOMOYO_MAX_HASH
];
154 * tomoyo_get_name - Allocate permanent memory for string data.
156 * @name: The string to store into the permernent memory.
158 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
160 const struct tomoyo_path_info
*tomoyo_get_name(const char *name
)
162 struct tomoyo_name
*ptr
;
166 struct list_head
*head
;
170 len
= strlen(name
) + 1;
171 hash
= full_name_hash((const unsigned char *) name
, len
- 1);
172 head
= &tomoyo_name_list
[hash_long(hash
, TOMOYO_HASH_BITS
)];
173 if (mutex_lock_interruptible(&tomoyo_policy_lock
))
175 list_for_each_entry(ptr
, head
, head
.list
) {
176 if (hash
!= ptr
->entry
.hash
|| strcmp(name
, ptr
->entry
.name
))
178 atomic_inc(&ptr
->head
.users
);
181 ptr
= kzalloc(sizeof(*ptr
) + len
, GFP_NOFS
);
182 allocated_len
= ptr
? ksize(ptr
) : 0;
183 if (!ptr
|| (tomoyo_quota_for_policy
&&
184 atomic_read(&tomoyo_policy_memory_size
) + allocated_len
185 > tomoyo_quota_for_policy
)) {
188 tomoyo_warn_oom(__func__
);
191 atomic_add(allocated_len
, &tomoyo_policy_memory_size
);
192 ptr
->entry
.name
= ((char *) ptr
) + sizeof(*ptr
);
193 memmove((char *) ptr
->entry
.name
, name
, len
);
194 atomic_set(&ptr
->head
.users
, 1);
195 tomoyo_fill_path_info(&ptr
->entry
);
196 list_add_tail(&ptr
->head
.list
, head
);
198 mutex_unlock(&tomoyo_policy_lock
);
199 return ptr
? &ptr
->entry
: NULL
;
203 * tomoyo_mm_init - Initialize mm related code.
205 void __init
tomoyo_mm_init(void)
209 for (idx
= 0; idx
< TOMOYO_MAX_POLICY
; idx
++)
210 INIT_LIST_HEAD(&tomoyo_policy_list
[idx
]);
211 for (idx
= 0; idx
< TOMOYO_MAX_GROUP
; idx
++)
212 INIT_LIST_HEAD(&tomoyo_group_list
[idx
]);
213 for (idx
= 0; idx
< TOMOYO_MAX_HASH
; idx
++)
214 INIT_LIST_HEAD(&tomoyo_name_list
[idx
]);
215 INIT_LIST_HEAD(&tomoyo_kernel_domain
.acl_info_list
);
216 for (idx
= 0; idx
< TOMOYO_MAX_ACL_GROUPS
; idx
++)
217 INIT_LIST_HEAD(&tomoyo_acl_group
[idx
]);
218 tomoyo_kernel_domain
.domainname
= tomoyo_get_name(TOMOYO_ROOT_NAME
);
219 list_add_tail_rcu(&tomoyo_kernel_domain
.list
, &tomoyo_domain_list
);
220 idx
= tomoyo_read_lock();
221 if (tomoyo_find_domain(TOMOYO_ROOT_NAME
) != &tomoyo_kernel_domain
)
222 panic("Can't register tomoyo_kernel_domain");
224 /* Will be replaced with tomoyo_load_builtin_policy(). */
226 /* Load built-in policy. */
227 tomoyo_write_transition_control("/sbin/hotplug", false,
228 TOMOYO_TRANSITION_CONTROL_INITIALIZE
);
229 tomoyo_write_transition_control("/sbin/modprobe", false,
230 TOMOYO_TRANSITION_CONTROL_INITIALIZE
);
233 tomoyo_read_unlock(idx
);
237 /* Memory allocated for query lists. */
238 unsigned int tomoyo_query_memory_size
;
239 /* Quota for holding query lists. */
240 unsigned int tomoyo_quota_for_query
;
243 * tomoyo_read_memory_counter - Check for memory usage in bytes.
245 * @head: Pointer to "struct tomoyo_io_buffer".
247 * Returns memory usage.
249 void tomoyo_read_memory_counter(struct tomoyo_io_buffer
*head
)
252 const unsigned int policy
253 = atomic_read(&tomoyo_policy_memory_size
);
254 const unsigned int query
= tomoyo_query_memory_size
;
257 memset(buffer
, 0, sizeof(buffer
));
258 if (tomoyo_quota_for_policy
)
259 snprintf(buffer
, sizeof(buffer
) - 1,
261 tomoyo_quota_for_policy
);
264 tomoyo_io_printf(head
, "Policy: %10u%s\n", policy
,
266 if (tomoyo_quota_for_query
)
267 snprintf(buffer
, sizeof(buffer
) - 1,
269 tomoyo_quota_for_query
);
272 tomoyo_io_printf(head
, "Query lists: %10u%s\n", query
,
274 tomoyo_io_printf(head
, "Total: %10u\n", policy
+ query
);
280 * tomoyo_write_memory_quota - Set memory quota.
282 * @head: Pointer to "struct tomoyo_io_buffer".
286 int tomoyo_write_memory_quota(struct tomoyo_io_buffer
*head
)
288 char *data
= head
->write_buf
;
291 if (sscanf(data
, "Policy: %u", &size
) == 1)
292 tomoyo_quota_for_policy
= size
;
293 else if (sscanf(data
, "Query lists: %u", &size
) == 1)
294 tomoyo_quota_for_query
= size
;