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
);
82 * tomoyo_memory_free - Free memory for elements.
84 * @ptr: Pointer to allocated memory.
86 void tomoyo_memory_free(void *ptr
)
88 atomic_sub(ksize(ptr
), &tomoyo_policy_memory_size
);
93 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
95 * @group_name: The name of address group.
98 * Returns pointer to "struct tomoyo_group" on success, NULL otherwise.
100 struct tomoyo_group
*tomoyo_get_group(const char *group_name
, const u8 idx
)
102 struct tomoyo_group e
= { };
103 struct tomoyo_group
*group
= NULL
;
105 if (!tomoyo_correct_word(group_name
) || idx
>= TOMOYO_MAX_GROUP
)
107 e
.group_name
= tomoyo_get_name(group_name
);
110 if (mutex_lock_interruptible(&tomoyo_policy_lock
))
112 list_for_each_entry(group
, &tomoyo_group_list
[idx
], list
) {
113 if (e
.group_name
!= group
->group_name
)
115 atomic_inc(&group
->users
);
120 struct tomoyo_group
*entry
= tomoyo_commit_ok(&e
, sizeof(e
));
122 INIT_LIST_HEAD(&entry
->member_list
);
123 atomic_set(&entry
->users
, 1);
124 list_add_tail_rcu(&entry
->list
,
125 &tomoyo_group_list
[idx
]);
130 mutex_unlock(&tomoyo_policy_lock
);
132 tomoyo_put_name(e
.group_name
);
133 return found
? group
: NULL
;
137 * tomoyo_name_list is used for holding string data used by TOMOYO.
138 * Since same string data is likely used for multiple times (e.g.
139 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
140 * "const struct tomoyo_path_info *".
142 struct list_head tomoyo_name_list
[TOMOYO_MAX_HASH
];
145 * tomoyo_get_name - Allocate permanent memory for string data.
147 * @name: The string to store into the permernent memory.
149 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
151 const struct tomoyo_path_info
*tomoyo_get_name(const char *name
)
153 struct tomoyo_name_entry
*ptr
;
157 struct list_head
*head
;
161 len
= strlen(name
) + 1;
162 hash
= full_name_hash((const unsigned char *) name
, len
- 1);
163 head
= &tomoyo_name_list
[hash_long(hash
, TOMOYO_HASH_BITS
)];
164 if (mutex_lock_interruptible(&tomoyo_policy_lock
))
166 list_for_each_entry(ptr
, head
, list
) {
167 if (hash
!= ptr
->entry
.hash
|| strcmp(name
, ptr
->entry
.name
))
169 atomic_inc(&ptr
->users
);
172 ptr
= kzalloc(sizeof(*ptr
) + len
, GFP_NOFS
);
173 allocated_len
= ptr
? ksize(ptr
) : 0;
174 if (!ptr
|| (tomoyo_quota_for_policy
&&
175 atomic_read(&tomoyo_policy_memory_size
) + allocated_len
176 > tomoyo_quota_for_policy
)) {
179 tomoyo_warn_oom(__func__
);
182 atomic_add(allocated_len
, &tomoyo_policy_memory_size
);
183 ptr
->entry
.name
= ((char *) ptr
) + sizeof(*ptr
);
184 memmove((char *) ptr
->entry
.name
, name
, len
);
185 atomic_set(&ptr
->users
, 1);
186 tomoyo_fill_path_info(&ptr
->entry
);
187 list_add_tail(&ptr
->list
, head
);
189 mutex_unlock(&tomoyo_policy_lock
);
190 return ptr
? &ptr
->entry
: NULL
;
194 * tomoyo_mm_init - Initialize mm related code.
196 void __init
tomoyo_mm_init(void)
200 for (idx
= 0; idx
< TOMOYO_MAX_POLICY
; idx
++)
201 INIT_LIST_HEAD(&tomoyo_policy_list
[idx
]);
202 for (idx
= 0; idx
< TOMOYO_MAX_GROUP
; idx
++)
203 INIT_LIST_HEAD(&tomoyo_group_list
[idx
]);
204 for (idx
= 0; idx
< TOMOYO_MAX_HASH
; idx
++)
205 INIT_LIST_HEAD(&tomoyo_name_list
[idx
]);
206 INIT_LIST_HEAD(&tomoyo_kernel_domain
.acl_info_list
);
207 tomoyo_kernel_domain
.domainname
= tomoyo_get_name(TOMOYO_ROOT_NAME
);
208 list_add_tail_rcu(&tomoyo_kernel_domain
.list
, &tomoyo_domain_list
);
209 idx
= tomoyo_read_lock();
210 if (tomoyo_find_domain(TOMOYO_ROOT_NAME
) != &tomoyo_kernel_domain
)
211 panic("Can't register tomoyo_kernel_domain");
213 /* Load built-in policy. */
214 tomoyo_write_transition_control("/sbin/hotplug", false,
215 TOMOYO_TRANSITION_CONTROL_INITIALIZE
);
216 tomoyo_write_transition_control("/sbin/modprobe", false,
217 TOMOYO_TRANSITION_CONTROL_INITIALIZE
);
219 tomoyo_read_unlock(idx
);
223 /* Memory allocated for query lists. */
224 unsigned int tomoyo_query_memory_size
;
225 /* Quota for holding query lists. */
226 unsigned int tomoyo_quota_for_query
;
229 * tomoyo_read_memory_counter - Check for memory usage in bytes.
231 * @head: Pointer to "struct tomoyo_io_buffer".
233 * Returns memory usage.
235 void tomoyo_read_memory_counter(struct tomoyo_io_buffer
*head
)
237 if (!head
->read_eof
) {
238 const unsigned int policy
239 = atomic_read(&tomoyo_policy_memory_size
);
240 const unsigned int query
= tomoyo_query_memory_size
;
243 memset(buffer
, 0, sizeof(buffer
));
244 if (tomoyo_quota_for_policy
)
245 snprintf(buffer
, sizeof(buffer
) - 1,
247 tomoyo_quota_for_policy
);
250 tomoyo_io_printf(head
, "Policy: %10u%s\n", policy
,
252 if (tomoyo_quota_for_query
)
253 snprintf(buffer
, sizeof(buffer
) - 1,
255 tomoyo_quota_for_query
);
258 tomoyo_io_printf(head
, "Query lists: %10u%s\n", query
,
260 tomoyo_io_printf(head
, "Total: %10u\n", policy
+ query
);
261 head
->read_eof
= true;
266 * tomoyo_write_memory_quota - Set memory quota.
268 * @head: Pointer to "struct tomoyo_io_buffer".
272 int tomoyo_write_memory_quota(struct tomoyo_io_buffer
*head
)
274 char *data
= head
->write_buf
;
277 if (sscanf(data
, "Policy: %u", &size
) == 1)
278 tomoyo_quota_for_policy
= size
;
279 else if (sscanf(data
, "Query lists: %u", &size
) == 1)
280 tomoyo_quota_for_query
= size
;