diff options
Diffstat (limited to 'security/tomoyo/realpath.c')
-rw-r--r-- | security/tomoyo/realpath.c | 292 |
1 files changed, 75 insertions, 217 deletions
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 18369d497eb8..cf7d61f781b9 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c | |||
@@ -14,9 +14,8 @@ | |||
14 | #include <linux/mnt_namespace.h> | 14 | #include <linux/mnt_namespace.h> |
15 | #include <linux/fs_struct.h> | 15 | #include <linux/fs_struct.h> |
16 | #include <linux/hash.h> | 16 | #include <linux/hash.h> |
17 | 17 | #include <linux/magic.h> | |
18 | #include "common.h" | 18 | #include "common.h" |
19 | #include "realpath.h" | ||
20 | 19 | ||
21 | /** | 20 | /** |
22 | * tomoyo_encode: Convert binary string to ascii string. | 21 | * tomoyo_encode: Convert binary string to ascii string. |
@@ -89,30 +88,15 @@ int tomoyo_realpath_from_path2(struct path *path, char *newname, | |||
89 | sp = dentry->d_op->d_dname(dentry, newname + offset, | 88 | sp = dentry->d_op->d_dname(dentry, newname + offset, |
90 | newname_len - offset); | 89 | newname_len - offset); |
91 | } else { | 90 | } else { |
92 | /* Taken from d_namespace_path(). */ | 91 | struct path ns_root = {.mnt = NULL, .dentry = NULL}; |
93 | struct path root; | ||
94 | struct path ns_root = { }; | ||
95 | struct path tmp; | ||
96 | 92 | ||
97 | read_lock(¤t->fs->lock); | ||
98 | root = current->fs->root; | ||
99 | path_get(&root); | ||
100 | read_unlock(¤t->fs->lock); | ||
101 | spin_lock(&vfsmount_lock); | ||
102 | if (root.mnt && root.mnt->mnt_ns) | ||
103 | ns_root.mnt = mntget(root.mnt->mnt_ns->root); | ||
104 | if (ns_root.mnt) | ||
105 | ns_root.dentry = dget(ns_root.mnt->mnt_root); | ||
106 | spin_unlock(&vfsmount_lock); | ||
107 | spin_lock(&dcache_lock); | 93 | spin_lock(&dcache_lock); |
108 | tmp = ns_root; | 94 | /* go to whatever namespace root we are under */ |
109 | sp = __d_path(path, &tmp, newname, newname_len); | 95 | sp = __d_path(path, &ns_root, newname, newname_len); |
110 | spin_unlock(&dcache_lock); | 96 | spin_unlock(&dcache_lock); |
111 | path_put(&root); | ||
112 | path_put(&ns_root); | ||
113 | /* Prepend "/proc" prefix if using internal proc vfs mount. */ | 97 | /* Prepend "/proc" prefix if using internal proc vfs mount. */ |
114 | if (!IS_ERR(sp) && (path->mnt->mnt_parent == path->mnt) && | 98 | if (!IS_ERR(sp) && (path->mnt->mnt_flags & MNT_INTERNAL) && |
115 | (strcmp(path->mnt->mnt_sb->s_type->name, "proc") == 0)) { | 99 | (path->mnt->mnt_sb->s_magic == PROC_SUPER_MAGIC)) { |
116 | sp -= 5; | 100 | sp -= 5; |
117 | if (sp >= newname) | 101 | if (sp >= newname) |
118 | memcpy(sp, "/proc", 5); | 102 | memcpy(sp, "/proc", 5); |
@@ -149,12 +133,12 @@ int tomoyo_realpath_from_path2(struct path *path, char *newname, | |||
149 | * | 133 | * |
150 | * Returns the realpath of the given @path on success, NULL otherwise. | 134 | * Returns the realpath of the given @path on success, NULL otherwise. |
151 | * | 135 | * |
152 | * These functions use tomoyo_alloc(), so the caller must call tomoyo_free() | 136 | * These functions use kzalloc(), so the caller must call kfree() |
153 | * if these functions didn't return NULL. | 137 | * if these functions didn't return NULL. |
154 | */ | 138 | */ |
155 | char *tomoyo_realpath_from_path(struct path *path) | 139 | char *tomoyo_realpath_from_path(struct path *path) |
156 | { | 140 | { |
157 | char *buf = tomoyo_alloc(sizeof(struct tomoyo_page_buffer)); | 141 | char *buf = kzalloc(sizeof(struct tomoyo_page_buffer), GFP_KERNEL); |
158 | 142 | ||
159 | BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer) | 143 | BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer) |
160 | <= TOMOYO_MAX_PATHNAME_LEN - 1); | 144 | <= TOMOYO_MAX_PATHNAME_LEN - 1); |
@@ -163,7 +147,7 @@ char *tomoyo_realpath_from_path(struct path *path) | |||
163 | if (tomoyo_realpath_from_path2(path, buf, | 147 | if (tomoyo_realpath_from_path2(path, buf, |
164 | TOMOYO_MAX_PATHNAME_LEN - 1) == 0) | 148 | TOMOYO_MAX_PATHNAME_LEN - 1) == 0) |
165 | return buf; | 149 | return buf; |
166 | tomoyo_free(buf); | 150 | kfree(buf); |
167 | return NULL; | 151 | return NULL; |
168 | } | 152 | } |
169 | 153 | ||
@@ -206,98 +190,47 @@ char *tomoyo_realpath_nofollow(const char *pathname) | |||
206 | } | 190 | } |
207 | 191 | ||
208 | /* Memory allocated for non-string data. */ | 192 | /* Memory allocated for non-string data. */ |
209 | static unsigned int tomoyo_allocated_memory_for_elements; | 193 | static atomic_t tomoyo_policy_memory_size; |
210 | /* Quota for holding non-string data. */ | 194 | /* Quota for holding policy. */ |
211 | static unsigned int tomoyo_quota_for_elements; | 195 | static unsigned int tomoyo_quota_for_policy; |
212 | 196 | ||
213 | /** | 197 | /** |
214 | * tomoyo_alloc_element - Allocate permanent memory for structures. | 198 | * tomoyo_memory_ok - Check memory quota. |
215 | * | 199 | * |
216 | * @size: Size in bytes. | 200 | * @ptr: Pointer to allocated memory. |
217 | * | 201 | * |
218 | * Returns pointer to allocated memory on success, NULL otherwise. | 202 | * Returns true on success, false otherwise. |
219 | * | 203 | * |
220 | * Memory has to be zeroed. | 204 | * Caller holds tomoyo_policy_lock. |
221 | * The RAM is chunked, so NEVER try to kfree() the returned pointer. | 205 | * Memory pointed by @ptr will be zeroed on success. |
222 | */ | 206 | */ |
223 | void *tomoyo_alloc_element(const unsigned int size) | 207 | bool tomoyo_memory_ok(void *ptr) |
224 | { | 208 | { |
225 | static char *buf; | 209 | int allocated_len = ptr ? ksize(ptr) : 0; |
226 | static DEFINE_MUTEX(lock); | 210 | atomic_add(allocated_len, &tomoyo_policy_memory_size); |
227 | static unsigned int buf_used_len = PATH_MAX; | 211 | if (ptr && (!tomoyo_quota_for_policy || |
228 | char *ptr = NULL; | 212 | atomic_read(&tomoyo_policy_memory_size) |
229 | /*Assumes sizeof(void *) >= sizeof(long) is true. */ | 213 | <= tomoyo_quota_for_policy)) { |
230 | const unsigned int word_aligned_size | 214 | memset(ptr, 0, allocated_len); |
231 | = roundup(size, max(sizeof(void *), sizeof(long))); | 215 | return true; |
232 | if (word_aligned_size > PATH_MAX) | ||
233 | return NULL; | ||
234 | mutex_lock(&lock); | ||
235 | if (buf_used_len + word_aligned_size > PATH_MAX) { | ||
236 | if (!tomoyo_quota_for_elements || | ||
237 | tomoyo_allocated_memory_for_elements | ||
238 | + PATH_MAX <= tomoyo_quota_for_elements) | ||
239 | ptr = kzalloc(PATH_MAX, GFP_KERNEL); | ||
240 | if (!ptr) { | ||
241 | printk(KERN_WARNING "ERROR: Out of memory " | ||
242 | "for tomoyo_alloc_element().\n"); | ||
243 | if (!tomoyo_policy_loaded) | ||
244 | panic("MAC Initialization failed.\n"); | ||
245 | } else { | ||
246 | buf = ptr; | ||
247 | tomoyo_allocated_memory_for_elements += PATH_MAX; | ||
248 | buf_used_len = word_aligned_size; | ||
249 | ptr = buf; | ||
250 | } | ||
251 | } else if (word_aligned_size) { | ||
252 | int i; | ||
253 | ptr = buf + buf_used_len; | ||
254 | buf_used_len += word_aligned_size; | ||
255 | for (i = 0; i < word_aligned_size; i++) { | ||
256 | if (!ptr[i]) | ||
257 | continue; | ||
258 | printk(KERN_ERR "WARNING: Reserved memory was tainted! " | ||
259 | "The system might go wrong.\n"); | ||
260 | ptr[i] = '\0'; | ||
261 | } | ||
262 | } | 216 | } |
263 | mutex_unlock(&lock); | 217 | printk(KERN_WARNING "ERROR: Out of memory " |
264 | return ptr; | 218 | "for tomoyo_alloc_element().\n"); |
219 | if (!tomoyo_policy_loaded) | ||
220 | panic("MAC Initialization failed.\n"); | ||
221 | return false; | ||
265 | } | 222 | } |
266 | 223 | ||
267 | /* Memory allocated for string data in bytes. */ | 224 | /** |
268 | static unsigned int tomoyo_allocated_memory_for_savename; | 225 | * tomoyo_memory_free - Free memory for elements. |
269 | /* Quota for holding string data in bytes. */ | ||
270 | static unsigned int tomoyo_quota_for_savename; | ||
271 | |||
272 | /* | ||
273 | * TOMOYO uses this hash only when appending a string into the string | ||
274 | * table. Frequency of appending strings is very low. So we don't need | ||
275 | * large (e.g. 64k) hash size. 256 will be sufficient. | ||
276 | */ | ||
277 | #define TOMOYO_HASH_BITS 8 | ||
278 | #define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS) | ||
279 | |||
280 | /* | ||
281 | * tomoyo_name_entry is a structure which is used for linking | ||
282 | * "struct tomoyo_path_info" into tomoyo_name_list . | ||
283 | * | 226 | * |
284 | * Since tomoyo_name_list manages a list of strings which are shared by | 227 | * @ptr: Pointer to allocated memory. |
285 | * multiple processes (whereas "struct tomoyo_path_info" inside | ||
286 | * "struct tomoyo_path_info_with_data" is not shared), a reference counter will | ||
287 | * be added to "struct tomoyo_name_entry" rather than "struct tomoyo_path_info" | ||
288 | * when TOMOYO starts supporting garbage collector. | ||
289 | */ | 228 | */ |
290 | struct tomoyo_name_entry { | 229 | void tomoyo_memory_free(void *ptr) |
291 | struct list_head list; | 230 | { |
292 | struct tomoyo_path_info entry; | 231 | atomic_sub(ksize(ptr), &tomoyo_policy_memory_size); |
293 | }; | 232 | kfree(ptr); |
294 | 233 | } | |
295 | /* Structure for available memory region. */ | ||
296 | struct tomoyo_free_memory_block_list { | ||
297 | struct list_head list; | ||
298 | char *ptr; /* Pointer to a free area. */ | ||
299 | int len; /* Length of the area. */ | ||
300 | }; | ||
301 | 234 | ||
302 | /* | 235 | /* |
303 | * tomoyo_name_list is used for holding string data used by TOMOYO. | 236 | * tomoyo_name_list is used for holding string data used by TOMOYO. |
@@ -305,87 +238,58 @@ struct tomoyo_free_memory_block_list { | |||
305 | * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of | 238 | * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of |
306 | * "const struct tomoyo_path_info *". | 239 | * "const struct tomoyo_path_info *". |
307 | */ | 240 | */ |
308 | static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; | 241 | struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; |
242 | /* Lock for protecting tomoyo_name_list . */ | ||
243 | DEFINE_MUTEX(tomoyo_name_list_lock); | ||
309 | 244 | ||
310 | /** | 245 | /** |
311 | * tomoyo_save_name - Allocate permanent memory for string data. | 246 | * tomoyo_get_name - Allocate permanent memory for string data. |
312 | * | 247 | * |
313 | * @name: The string to store into the permernent memory. | 248 | * @name: The string to store into the permernent memory. |
314 | * | 249 | * |
315 | * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. | 250 | * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. |
316 | * | ||
317 | * The RAM is shared, so NEVER try to modify or kfree() the returned name. | ||
318 | */ | 251 | */ |
319 | const struct tomoyo_path_info *tomoyo_save_name(const char *name) | 252 | const struct tomoyo_path_info *tomoyo_get_name(const char *name) |
320 | { | 253 | { |
321 | static LIST_HEAD(fmb_list); | ||
322 | static DEFINE_MUTEX(lock); | ||
323 | struct tomoyo_name_entry *ptr; | 254 | struct tomoyo_name_entry *ptr; |
324 | unsigned int hash; | 255 | unsigned int hash; |
325 | /* fmb contains available size in bytes. | ||
326 | fmb is removed from the fmb_list when fmb->len becomes 0. */ | ||
327 | struct tomoyo_free_memory_block_list *fmb; | ||
328 | int len; | 256 | int len; |
329 | char *cp; | 257 | int allocated_len; |
330 | struct list_head *head; | 258 | struct list_head *head; |
331 | 259 | ||
332 | if (!name) | 260 | if (!name) |
333 | return NULL; | 261 | return NULL; |
334 | len = strlen(name) + 1; | 262 | len = strlen(name) + 1; |
335 | if (len > TOMOYO_MAX_PATHNAME_LEN) { | ||
336 | printk(KERN_WARNING "ERROR: Name too long " | ||
337 | "for tomoyo_save_name().\n"); | ||
338 | return NULL; | ||
339 | } | ||
340 | hash = full_name_hash((const unsigned char *) name, len - 1); | 263 | hash = full_name_hash((const unsigned char *) name, len - 1); |
341 | head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; | 264 | head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; |
342 | 265 | mutex_lock(&tomoyo_name_list_lock); | |
343 | mutex_lock(&lock); | ||
344 | list_for_each_entry(ptr, head, list) { | 266 | list_for_each_entry(ptr, head, list) { |
345 | if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) | 267 | if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) |
346 | goto out; | 268 | continue; |
347 | } | 269 | atomic_inc(&ptr->users); |
348 | list_for_each_entry(fmb, &fmb_list, list) { | 270 | goto out; |
349 | if (len <= fmb->len) | ||
350 | goto ready; | ||
351 | } | 271 | } |
352 | if (!tomoyo_quota_for_savename || | 272 | ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL); |
353 | tomoyo_allocated_memory_for_savename + PATH_MAX | 273 | allocated_len = ptr ? ksize(ptr) : 0; |
354 | <= tomoyo_quota_for_savename) | 274 | if (!ptr || (tomoyo_quota_for_policy && |
355 | cp = kzalloc(PATH_MAX, GFP_KERNEL); | 275 | atomic_read(&tomoyo_policy_memory_size) + allocated_len |
356 | else | 276 | > tomoyo_quota_for_policy)) { |
357 | cp = NULL; | 277 | kfree(ptr); |
358 | fmb = kzalloc(sizeof(*fmb), GFP_KERNEL); | ||
359 | if (!cp || !fmb) { | ||
360 | kfree(cp); | ||
361 | kfree(fmb); | ||
362 | printk(KERN_WARNING "ERROR: Out of memory " | 278 | printk(KERN_WARNING "ERROR: Out of memory " |
363 | "for tomoyo_save_name().\n"); | 279 | "for tomoyo_get_name().\n"); |
364 | if (!tomoyo_policy_loaded) | 280 | if (!tomoyo_policy_loaded) |
365 | panic("MAC Initialization failed.\n"); | 281 | panic("MAC Initialization failed.\n"); |
366 | ptr = NULL; | 282 | ptr = NULL; |
367 | goto out; | 283 | goto out; |
368 | } | 284 | } |
369 | tomoyo_allocated_memory_for_savename += PATH_MAX; | 285 | atomic_add(allocated_len, &tomoyo_policy_memory_size); |
370 | list_add(&fmb->list, &fmb_list); | 286 | ptr->entry.name = ((char *) ptr) + sizeof(*ptr); |
371 | fmb->ptr = cp; | 287 | memmove((char *) ptr->entry.name, name, len); |
372 | fmb->len = PATH_MAX; | 288 | atomic_set(&ptr->users, 1); |
373 | ready: | ||
374 | ptr = tomoyo_alloc_element(sizeof(*ptr)); | ||
375 | if (!ptr) | ||
376 | goto out; | ||
377 | ptr->entry.name = fmb->ptr; | ||
378 | memmove(fmb->ptr, name, len); | ||
379 | tomoyo_fill_path_info(&ptr->entry); | 289 | tomoyo_fill_path_info(&ptr->entry); |
380 | fmb->ptr += len; | ||
381 | fmb->len -= len; | ||
382 | list_add_tail(&ptr->list, head); | 290 | list_add_tail(&ptr->list, head); |
383 | if (fmb->len == 0) { | ||
384 | list_del(&fmb->list); | ||
385 | kfree(fmb); | ||
386 | } | ||
387 | out: | 291 | out: |
388 | mutex_unlock(&lock); | 292 | mutex_unlock(&tomoyo_name_list_lock); |
389 | return ptr ? &ptr->entry : NULL; | 293 | return ptr ? &ptr->entry : NULL; |
390 | } | 294 | } |
391 | 295 | ||
@@ -400,45 +304,14 @@ void __init tomoyo_realpath_init(void) | |||
400 | for (i = 0; i < TOMOYO_MAX_HASH; i++) | 304 | for (i = 0; i < TOMOYO_MAX_HASH; i++) |
401 | INIT_LIST_HEAD(&tomoyo_name_list[i]); | 305 | INIT_LIST_HEAD(&tomoyo_name_list[i]); |
402 | INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); | 306 | INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); |
403 | tomoyo_kernel_domain.domainname = tomoyo_save_name(TOMOYO_ROOT_NAME); | 307 | tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME); |
404 | list_add_tail(&tomoyo_kernel_domain.list, &tomoyo_domain_list); | 308 | /* |
405 | down_read(&tomoyo_domain_list_lock); | 309 | * tomoyo_read_lock() is not needed because this function is |
310 | * called before the first "delete" request. | ||
311 | */ | ||
312 | list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list); | ||
406 | if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain) | 313 | if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain) |
407 | panic("Can't register tomoyo_kernel_domain"); | 314 | panic("Can't register tomoyo_kernel_domain"); |
408 | up_read(&tomoyo_domain_list_lock); | ||
409 | } | ||
410 | |||
411 | /* Memory allocated for temporary purpose. */ | ||
412 | static atomic_t tomoyo_dynamic_memory_size; | ||
413 | |||
414 | /** | ||
415 | * tomoyo_alloc - Allocate memory for temporary purpose. | ||
416 | * | ||
417 | * @size: Size in bytes. | ||
418 | * | ||
419 | * Returns pointer to allocated memory on success, NULL otherwise. | ||
420 | */ | ||
421 | void *tomoyo_alloc(const size_t size) | ||
422 | { | ||
423 | void *p = kzalloc(size, GFP_KERNEL); | ||
424 | if (p) | ||
425 | atomic_add(ksize(p), &tomoyo_dynamic_memory_size); | ||
426 | return p; | ||
427 | } | ||
428 | |||
429 | /** | ||
430 | * tomoyo_free - Release memory allocated by tomoyo_alloc(). | ||
431 | * | ||
432 | * @p: Pointer returned by tomoyo_alloc(). May be NULL. | ||
433 | * | ||
434 | * Returns nothing. | ||
435 | */ | ||
436 | void tomoyo_free(const void *p) | ||
437 | { | ||
438 | if (p) { | ||
439 | atomic_sub(ksize(p), &tomoyo_dynamic_memory_size); | ||
440 | kfree(p); | ||
441 | } | ||
442 | } | 315 | } |
443 | 316 | ||
444 | /** | 317 | /** |
@@ -451,32 +324,19 @@ void tomoyo_free(const void *p) | |||
451 | int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) | 324 | int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) |
452 | { | 325 | { |
453 | if (!head->read_eof) { | 326 | if (!head->read_eof) { |
454 | const unsigned int shared | 327 | const unsigned int policy |
455 | = tomoyo_allocated_memory_for_savename; | 328 | = atomic_read(&tomoyo_policy_memory_size); |
456 | const unsigned int private | ||
457 | = tomoyo_allocated_memory_for_elements; | ||
458 | const unsigned int dynamic | ||
459 | = atomic_read(&tomoyo_dynamic_memory_size); | ||
460 | char buffer[64]; | 329 | char buffer[64]; |
461 | 330 | ||
462 | memset(buffer, 0, sizeof(buffer)); | 331 | memset(buffer, 0, sizeof(buffer)); |
463 | if (tomoyo_quota_for_savename) | 332 | if (tomoyo_quota_for_policy) |
464 | snprintf(buffer, sizeof(buffer) - 1, | ||
465 | " (Quota: %10u)", | ||
466 | tomoyo_quota_for_savename); | ||
467 | else | ||
468 | buffer[0] = '\0'; | ||
469 | tomoyo_io_printf(head, "Shared: %10u%s\n", shared, buffer); | ||
470 | if (tomoyo_quota_for_elements) | ||
471 | snprintf(buffer, sizeof(buffer) - 1, | 333 | snprintf(buffer, sizeof(buffer) - 1, |
472 | " (Quota: %10u)", | 334 | " (Quota: %10u)", |
473 | tomoyo_quota_for_elements); | 335 | tomoyo_quota_for_policy); |
474 | else | 336 | else |
475 | buffer[0] = '\0'; | 337 | buffer[0] = '\0'; |
476 | tomoyo_io_printf(head, "Private: %10u%s\n", private, buffer); | 338 | tomoyo_io_printf(head, "Policy: %10u%s\n", policy, buffer); |
477 | tomoyo_io_printf(head, "Dynamic: %10u\n", dynamic); | 339 | tomoyo_io_printf(head, "Total: %10u\n", policy); |
478 | tomoyo_io_printf(head, "Total: %10u\n", | ||
479 | shared + private + dynamic); | ||
480 | head->read_eof = true; | 340 | head->read_eof = true; |
481 | } | 341 | } |
482 | return 0; | 342 | return 0; |
@@ -494,9 +354,7 @@ int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head) | |||
494 | char *data = head->write_buf; | 354 | char *data = head->write_buf; |
495 | unsigned int size; | 355 | unsigned int size; |
496 | 356 | ||
497 | if (sscanf(data, "Shared: %u", &size) == 1) | 357 | if (sscanf(data, "Policy: %u", &size) == 1) |
498 | tomoyo_quota_for_savename = size; | 358 | tomoyo_quota_for_policy = size; |
499 | else if (sscanf(data, "Private: %u", &size) == 1) | ||
500 | tomoyo_quota_for_elements = size; | ||
501 | return 0; | 359 | return 0; |
502 | } | 360 | } |