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_name_list is used for holding string data used by TOMOYO.
94 * Since same string data is likely used for multiple times (e.g.
95 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
96 * "const struct tomoyo_path_info *".
98 struct list_head tomoyo_name_list
[TOMOYO_MAX_HASH
];
101 * tomoyo_get_name - Allocate permanent memory for string data.
103 * @name: The string to store into the permernent memory.
105 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
107 const struct tomoyo_path_info
*tomoyo_get_name(const char *name
)
109 struct tomoyo_name_entry
*ptr
;
113 struct list_head
*head
;
117 len
= strlen(name
) + 1;
118 hash
= full_name_hash((const unsigned char *) name
, len
- 1);
119 head
= &tomoyo_name_list
[hash_long(hash
, TOMOYO_HASH_BITS
)];
120 if (mutex_lock_interruptible(&tomoyo_policy_lock
))
122 list_for_each_entry(ptr
, head
, list
) {
123 if (hash
!= ptr
->entry
.hash
|| strcmp(name
, ptr
->entry
.name
))
125 atomic_inc(&ptr
->users
);
128 ptr
= kzalloc(sizeof(*ptr
) + len
, GFP_NOFS
);
129 allocated_len
= ptr
? ksize(ptr
) : 0;
130 if (!ptr
|| (tomoyo_quota_for_policy
&&
131 atomic_read(&tomoyo_policy_memory_size
) + allocated_len
132 > tomoyo_quota_for_policy
)) {
135 tomoyo_warn_oom(__func__
);
138 atomic_add(allocated_len
, &tomoyo_policy_memory_size
);
139 ptr
->entry
.name
= ((char *) ptr
) + sizeof(*ptr
);
140 memmove((char *) ptr
->entry
.name
, name
, len
);
141 atomic_set(&ptr
->users
, 1);
142 tomoyo_fill_path_info(&ptr
->entry
);
143 list_add_tail(&ptr
->list
, head
);
145 mutex_unlock(&tomoyo_policy_lock
);
146 return ptr
? &ptr
->entry
: NULL
;
150 * tomoyo_mm_init - Initialize mm related code.
152 void __init
tomoyo_mm_init(void)
156 for (idx
= 0; idx
< TOMOYO_MAX_HASH
; idx
++)
157 INIT_LIST_HEAD(&tomoyo_name_list
[idx
]);
158 INIT_LIST_HEAD(&tomoyo_kernel_domain
.acl_info_list
);
159 tomoyo_kernel_domain
.domainname
= tomoyo_get_name(TOMOYO_ROOT_NAME
);
160 list_add_tail_rcu(&tomoyo_kernel_domain
.list
, &tomoyo_domain_list
);
161 idx
= tomoyo_read_lock();
162 if (tomoyo_find_domain(TOMOYO_ROOT_NAME
) != &tomoyo_kernel_domain
)
163 panic("Can't register tomoyo_kernel_domain");
165 /* Load built-in policy. */
166 tomoyo_write_domain_initializer_policy("/sbin/hotplug",
168 tomoyo_write_domain_initializer_policy("/sbin/modprobe",
171 tomoyo_read_unlock(idx
);
175 /* Memory allocated for query lists. */
176 unsigned int tomoyo_query_memory_size
;
177 /* Quota for holding query lists. */
178 unsigned int tomoyo_quota_for_query
;
181 * tomoyo_read_memory_counter - Check for memory usage in bytes.
183 * @head: Pointer to "struct tomoyo_io_buffer".
185 * Returns memory usage.
187 int tomoyo_read_memory_counter(struct tomoyo_io_buffer
*head
)
189 if (!head
->read_eof
) {
190 const unsigned int policy
191 = atomic_read(&tomoyo_policy_memory_size
);
192 const unsigned int query
= tomoyo_query_memory_size
;
195 memset(buffer
, 0, sizeof(buffer
));
196 if (tomoyo_quota_for_policy
)
197 snprintf(buffer
, sizeof(buffer
) - 1,
199 tomoyo_quota_for_policy
);
202 tomoyo_io_printf(head
, "Policy: %10u%s\n", policy
,
204 if (tomoyo_quota_for_query
)
205 snprintf(buffer
, sizeof(buffer
) - 1,
207 tomoyo_quota_for_query
);
210 tomoyo_io_printf(head
, "Query lists: %10u%s\n", query
,
212 tomoyo_io_printf(head
, "Total: %10u\n", policy
+ query
);
213 head
->read_eof
= true;
219 * tomoyo_write_memory_quota - Set memory quota.
221 * @head: Pointer to "struct tomoyo_io_buffer".
225 int tomoyo_write_memory_quota(struct tomoyo_io_buffer
*head
)
227 char *data
= head
->write_buf
;
230 if (sscanf(data
, "Policy: %u", &size
) == 1)
231 tomoyo_quota_for_policy
= size
;
232 else if (sscanf(data
, "Query lists: %u", &size
) == 1)
233 tomoyo_quota_for_query
= size
;