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 /* Memory allocated for policy. */
33 static atomic_t tomoyo_policy_memory_size
;
34 /* Quota for holding policy. */
35 static unsigned int tomoyo_quota_for_policy
;
38 * tomoyo_memory_ok - Check memory quota.
40 * @ptr: Pointer to allocated memory.
42 * Returns true on success, false otherwise.
44 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
46 bool tomoyo_memory_ok(void *ptr
)
48 size_t s
= ptr
? ksize(ptr
) : 0;
49 atomic_add(s
, &tomoyo_policy_memory_size
);
50 if (ptr
&& (!tomoyo_quota_for_policy
||
51 atomic_read(&tomoyo_policy_memory_size
)
52 <= tomoyo_quota_for_policy
)) {
56 atomic_sub(s
, &tomoyo_policy_memory_size
);
57 tomoyo_warn_oom(__func__
);
62 * tomoyo_commit_ok - Check memory quota.
64 * @data: Data to copy from.
65 * @size: Size in byte.
67 * Returns pointer to allocated memory on success, NULL otherwise.
68 * @data is zero-cleared on success.
70 void *tomoyo_commit_ok(void *data
, const unsigned int size
)
72 void *ptr
= kzalloc(size
, GFP_NOFS
);
73 if (tomoyo_memory_ok(ptr
)) {
74 memmove(ptr
, data
, size
);
75 memset(data
, 0, size
);
83 * tomoyo_memory_free - Free memory for elements.
85 * @ptr: Pointer to allocated memory.
87 void tomoyo_memory_free(void *ptr
)
89 atomic_sub(ksize(ptr
), &tomoyo_policy_memory_size
);
94 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
96 * @group_name: The name of address group.
99 * Returns pointer to "struct tomoyo_group" on success, NULL otherwise.
101 struct tomoyo_group
*tomoyo_get_group(const char *group_name
, const u8 idx
)
103 struct tomoyo_group e
= { };
104 struct tomoyo_group
*group
= NULL
;
106 if (!tomoyo_correct_word(group_name
) || idx
>= TOMOYO_MAX_GROUP
)
108 e
.group_name
= tomoyo_get_name(group_name
);
111 if (mutex_lock_interruptible(&tomoyo_policy_lock
))
113 list_for_each_entry(group
, &tomoyo_group_list
[idx
], list
) {
114 if (e
.group_name
!= group
->group_name
)
116 atomic_inc(&group
->users
);
121 struct tomoyo_group
*entry
= tomoyo_commit_ok(&e
, sizeof(e
));
123 INIT_LIST_HEAD(&entry
->member_list
);
124 atomic_set(&entry
->users
, 1);
125 list_add_tail_rcu(&entry
->list
,
126 &tomoyo_group_list
[idx
]);
131 mutex_unlock(&tomoyo_policy_lock
);
133 tomoyo_put_name(e
.group_name
);
134 return found
? group
: NULL
;
138 * tomoyo_name_list is used for holding string data used by TOMOYO.
139 * Since same string data is likely used for multiple times (e.g.
140 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
141 * "const struct tomoyo_path_info *".
143 struct list_head tomoyo_name_list
[TOMOYO_MAX_HASH
];
146 * tomoyo_get_name - Allocate permanent memory for string data.
148 * @name: The string to store into the permernent memory.
150 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
152 const struct tomoyo_path_info
*tomoyo_get_name(const char *name
)
154 struct tomoyo_name
*ptr
;
158 struct list_head
*head
;
162 len
= strlen(name
) + 1;
163 hash
= full_name_hash((const unsigned char *) name
, len
- 1);
164 head
= &tomoyo_name_list
[hash_long(hash
, TOMOYO_HASH_BITS
)];
165 if (mutex_lock_interruptible(&tomoyo_policy_lock
))
167 list_for_each_entry(ptr
, head
, list
) {
168 if (hash
!= ptr
->entry
.hash
|| strcmp(name
, ptr
->entry
.name
))
170 atomic_inc(&ptr
->users
);
173 ptr
= kzalloc(sizeof(*ptr
) + len
, GFP_NOFS
);
174 allocated_len
= ptr
? ksize(ptr
) : 0;
175 if (!ptr
|| (tomoyo_quota_for_policy
&&
176 atomic_read(&tomoyo_policy_memory_size
) + allocated_len
177 > tomoyo_quota_for_policy
)) {
180 tomoyo_warn_oom(__func__
);
183 atomic_add(allocated_len
, &tomoyo_policy_memory_size
);
184 ptr
->entry
.name
= ((char *) ptr
) + sizeof(*ptr
);
185 memmove((char *) ptr
->entry
.name
, name
, len
);
186 atomic_set(&ptr
->users
, 1);
187 tomoyo_fill_path_info(&ptr
->entry
);
188 list_add_tail(&ptr
->list
, head
);
190 mutex_unlock(&tomoyo_policy_lock
);
191 return ptr
? &ptr
->entry
: NULL
;
195 * tomoyo_mm_init - Initialize mm related code.
197 void __init
tomoyo_mm_init(void)
201 for (idx
= 0; idx
< TOMOYO_MAX_POLICY
; idx
++)
202 INIT_LIST_HEAD(&tomoyo_policy_list
[idx
]);
203 for (idx
= 0; idx
< TOMOYO_MAX_GROUP
; idx
++)
204 INIT_LIST_HEAD(&tomoyo_group_list
[idx
]);
205 for (idx
= 0; idx
< TOMOYO_MAX_HASH
; idx
++)
206 INIT_LIST_HEAD(&tomoyo_name_list
[idx
]);
207 INIT_LIST_HEAD(&tomoyo_kernel_domain
.acl_info_list
);
208 tomoyo_kernel_domain
.domainname
= tomoyo_get_name(TOMOYO_ROOT_NAME
);
209 list_add_tail_rcu(&tomoyo_kernel_domain
.list
, &tomoyo_domain_list
);
210 idx
= tomoyo_read_lock();
211 if (tomoyo_find_domain(TOMOYO_ROOT_NAME
) != &tomoyo_kernel_domain
)
212 panic("Can't register tomoyo_kernel_domain");
214 /* Load built-in policy. */
215 tomoyo_write_transition_control("/sbin/hotplug", false,
216 TOMOYO_TRANSITION_CONTROL_INITIALIZE
);
217 tomoyo_write_transition_control("/sbin/modprobe", false,
218 TOMOYO_TRANSITION_CONTROL_INITIALIZE
);
220 tomoyo_read_unlock(idx
);
224 /* Memory allocated for query lists. */
225 unsigned int tomoyo_query_memory_size
;
226 /* Quota for holding query lists. */
227 unsigned int tomoyo_quota_for_query
;
230 * tomoyo_read_memory_counter - Check for memory usage in bytes.
232 * @head: Pointer to "struct tomoyo_io_buffer".
234 * Returns memory usage.
236 void tomoyo_read_memory_counter(struct tomoyo_io_buffer
*head
)
239 const unsigned int policy
240 = atomic_read(&tomoyo_policy_memory_size
);
241 const unsigned int query
= tomoyo_query_memory_size
;
244 memset(buffer
, 0, sizeof(buffer
));
245 if (tomoyo_quota_for_policy
)
246 snprintf(buffer
, sizeof(buffer
) - 1,
248 tomoyo_quota_for_policy
);
251 tomoyo_io_printf(head
, "Policy: %10u%s\n", policy
,
253 if (tomoyo_quota_for_query
)
254 snprintf(buffer
, sizeof(buffer
) - 1,
256 tomoyo_quota_for_query
);
259 tomoyo_io_printf(head
, "Query lists: %10u%s\n", query
,
261 tomoyo_io_printf(head
, "Total: %10u\n", policy
+ query
);
267 * tomoyo_write_memory_quota - Set memory quota.
269 * @head: Pointer to "struct tomoyo_io_buffer".
273 int tomoyo_write_memory_quota(struct tomoyo_io_buffer
*head
)
275 char *data
= head
->write_buf
;
278 if (sscanf(data
, "Policy: %u", &size
) == 1)
279 tomoyo_quota_for_policy
= size
;
280 else if (sscanf(data
, "Query lists: %u", &size
) == 1)
281 tomoyo_quota_for_query
= size
;