オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Annotation of /trunk/1.7.x/ccs-patch/security/ccsecurity/realpath.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2716 - (hide annotations) (download) (as text)
Wed Jul 1 12:20:54 2009 UTC (14 years, 10 months ago) by kumaneko
Original Path: branches/ccs-patch/fs/realpath.c
File MIME type: text/x-csrc
File size: 38565 byte(s)


1 kumaneko 111 /*
2     * fs/realpath.c
3     *
4     * Get the canonicalized absolute pathnames. The basis for SAKURA and TOMOYO.
5     *
6 kumaneko 2030 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 kumaneko 111 *
8 kumaneko 2704 * Version: 1.7.0-pre 2009/05/28
9 kumaneko 111 *
10     * This file is applicable to both 2.4.30 and 2.6.11 and later.
11     * See README.ccs for ChangeLog.
12     *
13     */
14     #include <linux/string.h>
15     #include <linux/mm.h>
16     #include <linux/utime.h>
17     #include <linux/file.h>
18     #include <linux/smp_lock.h>
19     #include <linux/module.h>
20     #include <linux/slab.h>
21     #include <asm/uaccess.h>
22     #include <asm/atomic.h>
23     #include <linux/version.h>
24 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
25 kumaneko 111 #include <linux/namei.h>
26     #include <linux/mount.h>
27 kumaneko 2002 static const int ccs_lookup_flags = LOOKUP_FOLLOW;
28 kumaneko 111 #else
29 kumaneko 2002 static const int ccs_lookup_flags = LOOKUP_FOLLOW | LOOKUP_POSITIVE;
30 kumaneko 111 #endif
31     #include <linux/proc_fs.h>
32     #include <linux/ccs_common.h>
33 kumaneko 2540 #include <linux/realpath.h>
34 kumaneko 2271 #include <net/sock.h>
35 kumaneko 111
36 kumaneko 1052 /**
37 kumaneko 2002 * ccs_get_absolute_path - Get the path of a dentry but ignores chroot'ed root.
38 kumaneko 111 *
39 kumaneko 1052 * @dentry: Pointer to "struct dentry".
40     * @vfsmnt: Pointer to "struct vfsmount".
41     * @buffer: Pointer to buffer to return value in.
42     * @buflen: Sizeof @buffer.
43     *
44     * Returns 0 on success, -ENOMEM otherwise.
45     *
46 kumaneko 1064 * Caller holds the dcache_lock and vfsmount_lock.
47 kumaneko 111 * Based on __d_path() in fs/dcache.c
48     *
49     * If dentry is a directory, trailing '/' is appended.
50 kumaneko 1052 * Characters out of 0x20 < c < 0x7F range are converted to
51     * \ooo style octal string.
52 kumaneko 111 * Character \ is converted to \\ string.
53     */
54 kumaneko 2002 static int ccs_get_absolute_path(struct dentry *dentry, struct vfsmount *vfsmnt,
55     char *buffer, int buflen)
56 kumaneko 111 {
57 kumaneko 1052 /***** CRITICAL SECTION START *****/
58 kumaneko 111 char *start = buffer;
59     char *end = buffer + buflen;
60 kumaneko 621 bool is_dir = (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode));
61 kumaneko 111
62 kumaneko 1052 if (buflen < 256)
63     goto out;
64 kumaneko 111
65     *--end = '\0';
66     buflen--;
67    
68     for (;;) {
69     struct dentry *parent;
70    
71     if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
72     /* Global root? */
73 kumaneko 1052 if (vfsmnt->mnt_parent == vfsmnt)
74 kumaneko 111 break;
75     dentry = vfsmnt->mnt_mountpoint;
76     vfsmnt = vfsmnt->mnt_parent;
77     continue;
78     }
79     if (is_dir) {
80 kumaneko 1052 is_dir = false;
81     *--end = '/';
82     buflen--;
83 kumaneko 111 }
84     parent = dentry->d_parent;
85     {
86     const char *sp = dentry->d_name.name;
87     const char *cp = sp + dentry->d_name.len - 1;
88     unsigned char c;
89    
90 kumaneko 1052 /*
91     * Exception: Use /proc/self/ rather than
92     * /proc/\$/ for current process.
93     */
94     if (IS_ROOT(parent) && *sp > '0' && *sp <= '9' &&
95     parent->d_sb &&
96     parent->d_sb->s_magic == PROC_SUPER_MAGIC) {
97 kumaneko 111 char *ep;
98 kumaneko 1052 const pid_t pid
99     = (pid_t) simple_strtoul(sp, &ep, 10);
100 kumaneko 1778 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
101     const pid_t tgid
102     = task_tgid_nr_ns(current,
103     dentry->d_sb->
104     s_fs_info);
105     if (!*ep && pid == tgid && tgid) {
106 kumaneko 1052 sp = "self";
107     cp = sp + 3;
108     }
109 kumaneko 111 #else
110 kumaneko 1778 if (!*ep && pid == sys_getpid()) {
111 kumaneko 1052 sp = "self";
112     cp = sp + 3;
113     }
114 kumaneko 111 #endif
115     }
116    
117     while (sp <= cp) {
118 kumaneko 1052 c = *(unsigned char *) cp;
119 kumaneko 111 if (c == '\\') {
120     buflen -= 2;
121 kumaneko 1052 if (buflen < 0)
122     goto out;
123 kumaneko 111 *--end = '\\';
124     *--end = '\\';
125     } else if (c > ' ' && c < 127) {
126 kumaneko 1052 if (--buflen < 0)
127     goto out;
128 kumaneko 111 *--end = (char) c;
129     } else {
130     buflen -= 4;
131 kumaneko 1052 if (buflen < 0)
132     goto out;
133 kumaneko 111 *--end = (c & 7) + '0';
134     *--end = ((c >> 3) & 7) + '0';
135     *--end = (c >> 6) + '0';
136     *--end = '\\';
137     }
138     cp--;
139     }
140 kumaneko 1052 if (--buflen < 0)
141     goto out;
142 kumaneko 111 *--end = '/';
143     }
144     dentry = parent;
145     }
146 kumaneko 1052 if (*end == '/') {
147     buflen++;
148     end++;
149     }
150 kumaneko 111 {
151     const char *sp = dentry->d_name.name;
152     const char *cp = sp + dentry->d_name.len - 1;
153     unsigned char c;
154     while (sp <= cp) {
155 kumaneko 1052 c = *(unsigned char *) cp;
156 kumaneko 111 if (c == '\\') {
157     buflen -= 2;
158 kumaneko 1052 if (buflen < 0)
159     goto out;
160 kumaneko 111 *--end = '\\';
161     *--end = '\\';
162     } else if (c > ' ' && c < 127) {
163 kumaneko 1052 if (--buflen < 0)
164     goto out;
165 kumaneko 111 *--end = (char) c;
166     } else {
167     buflen -= 4;
168 kumaneko 1052 if (buflen < 0)
169     goto out;
170 kumaneko 111 *--end = (c & 7) + '0';
171     *--end = ((c >> 3) & 7) + '0';
172     *--end = (c >> 6) + '0';
173     *--end = '\\';
174     }
175     cp--;
176     }
177     }
178     /* Move the pathname to the top of the buffer. */
179     memmove(start, end, strlen(end) + 1);
180     return 0;
181     out:
182     return -ENOMEM;
183 kumaneko 1052 /***** CRITICAL SECTION END *****/
184 kumaneko 111 }
185    
186 kumaneko 2271 #define SOCKFS_MAGIC 0x534F434B
187    
188 kumaneko 1052 /**
189 kumaneko 1054 * ccs_realpath_from_dentry2 - Returns realpath(3) of the given dentry but ignores chroot'ed root.
190 kumaneko 1052 *
191     * @dentry: Pointer to "struct dentry".
192     * @mnt: Pointer to "struct vfsmount".
193     * @newname: Pointer to buffer to return value in.
194 kumaneko 1064 * @newname_len: Size of @newname.
195 kumaneko 1052 *
196     * Returns 0 on success, negative value otherwise.
197     */
198 kumaneko 2711 static int ccs_realpath_from_dentry2(struct dentry *dentry,
199     struct vfsmount *mnt,
200     char *newname, int newname_len)
201 kumaneko 111 {
202 kumaneko 1379 int error = -EINVAL;
203 kumaneko 111 struct dentry *d_dentry;
204     struct vfsmount *d_mnt;
205 kumaneko 1379 if (!dentry || !newname || newname_len <= 2048)
206     goto out;
207 kumaneko 2271 /* Get better name for socket. */
208     if (dentry->d_sb && dentry->d_sb->s_magic == SOCKFS_MAGIC) {
209     struct inode *inode = dentry->d_inode;
210 kumaneko 2284 struct socket *sock = inode ? SOCKET_I(inode) : NULL;
211     struct sock *sk = sock ? sock->sk : NULL;
212     if (sk) {
213 kumaneko 2271 snprintf(newname, newname_len - 1,
214 kumaneko 2284 "socket:[family=%u:type=%u:protocol=%u]",
215     sk->sk_family, sk->sk_type, sk->sk_protocol);
216 kumaneko 2271 } else {
217     snprintf(newname, newname_len - 1, "socket:[unknown]");
218     }
219     return 0;
220     }
221 kumaneko 1259 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
222     if (dentry->d_op && dentry->d_op->d_dname) {
223     /* For "socket:[\$]" and "pipe:[\$]". */
224     static const int offset = 1536;
225     char *dp = newname;
226     char *sp = dentry->d_op->d_dname(dentry, newname + offset,
227     newname_len - offset);
228     if (IS_ERR(sp)) {
229     error = PTR_ERR(sp);
230     goto out;
231     }
232     error = -ENOMEM;
233     newname += offset;
234     while (1) {
235     const unsigned char c = *(unsigned char *) sp++;
236     if (c == '\\') {
237     if (dp + 2 >= newname)
238     break;
239     *dp++ = '\\';
240     *dp++ = '\\';
241     } else if (c > ' ' && c < 127) {
242     if (dp + 1 >= newname)
243     break;
244     *dp++ = (char) c;
245     } else if (c) {
246     if (dp + 4 >= newname)
247     break;
248     *dp++ = '\\';
249     *dp++ = (c >> 6) + '0';
250     *dp++ = ((c >> 3) & 7) + '0';
251     *dp++ = (c & 7) + '0';
252     } else {
253     *dp = '\0';
254     return 0;
255     }
256     }
257     goto out;
258     }
259     #endif
260 kumaneko 1379 if (!mnt)
261     goto out;
262 kumaneko 111 d_dentry = dget(dentry);
263     d_mnt = mntget(mnt);
264     /***** CRITICAL SECTION START *****/
265 kumaneko 1474 ccs_realpath_lock();
266 kumaneko 2002 error = ccs_get_absolute_path(d_dentry, d_mnt, newname, newname_len);
267 kumaneko 1474 ccs_realpath_unlock();
268 kumaneko 111 /***** CRITICAL SECTION END *****/
269     dput(d_dentry);
270     mntput(d_mnt);
271 kumaneko 1259 out:
272 kumaneko 1056 if (error)
273 kumaneko 1379 printk(KERN_WARNING "ccs_realpath: Pathname too long. (%d)\n",
274     error);
275 kumaneko 111 return error;
276     }
277    
278 kumaneko 1052 /**
279 kumaneko 1054 * ccs_realpath_from_dentry - Returns realpath(3) of the given pathname but ignores chroot'ed root.
280 kumaneko 1052 *
281     * @dentry: Pointer to "struct dentry".
282     * @mnt: Pointer to "struct vfsmount".
283     *
284     * Returns the realpath of the given @dentry and @mnt on success,
285     * NULL otherwise.
286     *
287 kumaneko 2711 * These functions use kzalloc(), so caller must kfree()
288 kumaneko 1052 * if these functions didn't return NULL.
289     */
290     char *ccs_realpath_from_dentry(struct dentry *dentry, struct vfsmount *mnt)
291 kumaneko 111 {
292 kumaneko 2711 char *buf = kzalloc(CCS_MAX_PATHNAME_LEN, GFP_KERNEL);
293 kumaneko 1052 if (buf && ccs_realpath_from_dentry2(dentry, mnt, buf,
294 kumaneko 2711 CCS_MAX_PATHNAME_LEN - 2) == 0)
295 kumaneko 1052 return buf;
296 kumaneko 2711 kfree(buf);
297 kumaneko 111 return NULL;
298     }
299    
300 kumaneko 1052 /**
301     * ccs_realpath - Get realpath of a pathname.
302     *
303     * @pathname: The pathname to solve.
304     *
305     * Returns the realpath of @pathname on success, NULL otherwise.
306     */
307     char *ccs_realpath(const char *pathname)
308 kumaneko 111 {
309     struct nameidata nd;
310 kumaneko 2002 if (pathname && path_lookup(pathname, ccs_lookup_flags, &nd) == 0) {
311 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
312     char *buf = ccs_realpath_from_dentry(nd.path.dentry,
313     nd.path.mnt);
314 kumaneko 990 path_put(&nd.path);
315     #else
316 kumaneko 1052 char *buf = ccs_realpath_from_dentry(nd.dentry, nd.mnt);
317 kumaneko 111 path_release(&nd);
318 kumaneko 990 #endif
319 kumaneko 111 return buf;
320     }
321     return NULL;
322     }
323    
324 kumaneko 1052 /**
325 kumaneko 2037 * ccs_realpath_both - Get realpath of a pathname and symlink.
326 kumaneko 1052 *
327     * @pathname: The pathname to solve.
328 kumaneko 2037 * @ee: Pointer to "struct ccs_execve_entry".
329 kumaneko 1052 *
330 kumaneko 2075 * Returns 0 on success, negative value otherwise.
331 kumaneko 1052 */
332 kumaneko 2075 int ccs_realpath_both(const char *pathname, struct ccs_execve_entry *ee)
333 kumaneko 111 {
334     struct nameidata nd;
335 kumaneko 2037 int ret;
336     bool is_symlink;
337     if (!pathname ||
338     path_lookup(pathname, ccs_lookup_flags ^ LOOKUP_FOLLOW, &nd))
339 kumaneko 2075 return -ENOENT;
340 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
341 kumaneko 2037 is_symlink = nd.path.dentry->d_inode &&
342     S_ISLNK(nd.path.dentry->d_inode->i_mode);
343     ret = ccs_realpath_from_dentry2(nd.path.dentry, nd.path.mnt,
344     ee->tmp, CCS_EXEC_TMPSIZE - 1);
345     path_put(&nd.path);
346 kumaneko 990 #else
347 kumaneko 2037 is_symlink = nd.dentry->d_inode && S_ISLNK(nd.dentry->d_inode->i_mode);
348     ret = ccs_realpath_from_dentry2(nd.dentry, nd.mnt, ee->tmp,
349     CCS_EXEC_TMPSIZE - 1);
350     path_release(&nd);
351 kumaneko 990 #endif
352 kumaneko 2037 if (ret)
353 kumaneko 2075 return -ENOMEM;
354 kumaneko 2044 if (strlen(ee->tmp) > CCS_MAX_PATHNAME_LEN - 1)
355 kumaneko 2075 return -ENOMEM;
356 kumaneko 2037 ee->program_path[CCS_MAX_PATHNAME_LEN - 1] = '\0';
357     if (!is_symlink) {
358     strncpy(ee->program_path, ee->tmp,
359     CCS_MAX_PATHNAME_LEN - 1);
360 kumaneko 2075 return 0;
361 kumaneko 111 }
362 kumaneko 2037 if (path_lookup(pathname, ccs_lookup_flags, &nd))
363 kumaneko 2075 return -ENOENT;
364 kumaneko 2037 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
365     ret = ccs_realpath_from_dentry2(nd.path.dentry, nd.path.mnt,
366     ee->program_path,
367     CCS_MAX_PATHNAME_LEN - 1);
368     path_put(&nd.path);
369     #else
370     ret = ccs_realpath_from_dentry2(nd.dentry, nd.mnt, ee->program_path,
371     CCS_MAX_PATHNAME_LEN - 1);
372     path_release(&nd);
373     #endif
374 kumaneko 2075 return ret ? -ENOMEM : 0;
375 kumaneko 111 }
376    
377 kumaneko 1052 /**
378 kumaneko 2519 * ccs_encode: Encode binary string to ascii string.
379     *
380     * @str: String in binary format.
381     *
382     * Returns pointer to @str in ascii format on success, NULL otherwise.
383     *
384 kumaneko 2711 * This function uses kzalloc(), so caller must kfree() if this function
385 kumaneko 2519 * didn't return NULL.
386     */
387     char *ccs_encode(const char *str)
388     {
389     int len = 0;
390     const char *p = str;
391     char *cp;
392     char *cp0;
393     if (!p)
394     return NULL;
395     while (*p) {
396     const unsigned char c = *p++;
397     if (c == '\\')
398     len += 2;
399     else if (c > ' ' && c < 127)
400     len++;
401     else
402     len += 4;
403     }
404     len++;
405 kumaneko 2711 cp = kzalloc(len, GFP_KERNEL);
406 kumaneko 2519 if (!cp)
407     return NULL;
408     cp0 = cp;
409     p = str;
410     while (*p) {
411     const unsigned char c = *p++;
412     if (c == '\\') {
413     *cp++ = '\\';
414     *cp++ = '\\';
415     } else if (c > ' ' && c < 127) {
416     *cp++ = c;
417     } else {
418     *cp++ = '\\';
419     *cp++ = (c >> 6) + '0';
420     *cp++ = ((c >> 3) & 7) + '0';
421     *cp++ = (c & 7) + '0';
422     }
423     }
424     return cp0;
425     }
426    
427     /**
428 kumaneko 2002 * ccs_round_up - Round up an integer so that the returned pointers are appropriately aligned.
429 kumaneko 1052 *
430     * @size: Size in bytes.
431     *
432     * Returns rounded value of @size.
433     *
434     * FIXME: Are there more requirements that is needed for assigning value
435     * atomically?
436 kumaneko 111 */
437 kumaneko 2002 static inline unsigned int ccs_round_up(const unsigned int size)
438 kumaneko 1052 {
439     if (sizeof(void *) >= sizeof(long))
440     return ((size + sizeof(void *) - 1)
441     / sizeof(void *)) * sizeof(void *);
442     else
443     return ((size + sizeof(long) - 1)
444     / sizeof(long)) * sizeof(long);
445 kumaneko 111 }
446    
447 kumaneko 2701 static atomic_t ccs_allocated_memory_for_elements;
448 kumaneko 2002 static unsigned int ccs_quota_for_elements;
449 kumaneko 111
450 kumaneko 1052 /**
451 kumaneko 2540 * ccs_memory_ok - Check memory quota.
452 kumaneko 1052 *
453 kumaneko 2540 * @ptr: Pointer to allocated memory.
454 kumaneko 1052 *
455 kumaneko 2540 * Returns true if @ptr is not NULL and quota not exceeded, false otehrwise.
456     */
457     bool ccs_memory_ok(const void *ptr)
458     {
459     const unsigned int len = ptr ? ksize(ptr) : 0;
460     if (len && (!ccs_quota_for_elements ||
461 kumaneko 2701 atomic_read(&ccs_allocated_memory_for_elements) + len
462 kumaneko 2540 <= ccs_quota_for_elements)) {
463 kumaneko 2701 atomic_add(len, &ccs_allocated_memory_for_elements);
464 kumaneko 2540 return true;
465     }
466     printk(KERN_WARNING "ERROR: Out of memory. (%s)\n", __func__);
467     if (!ccs_policy_loaded)
468     panic("MAC Initialization failed.\n");
469     return false;
470     }
471    
472     /**
473     * ccs_memory_free - Free memory for elements.
474 kumaneko 1052 *
475 kumaneko 2540 * @ptr: Pointer to allocated memory.
476 kumaneko 1052 */
477 kumaneko 2540 static void ccs_memory_free(const void *ptr)
478 kumaneko 111 {
479 kumaneko 2701 atomic_sub(ksize(ptr), &ccs_allocated_memory_for_elements);
480 kumaneko 2540 kfree(ptr);
481     }
482    
483     /**
484     * ccs_free_element - Delete memory for structures.
485     *
486     * @ptr: Memory to release.
487     */
488     static void ccs_free_element(void *ptr)
489     {
490     if (!ptr)
491     return;
492 kumaneko 2701 atomic_sub(ksize(ptr), &ccs_allocated_memory_for_elements);
493 kumaneko 2540 kfree(ptr);
494     }
495    
496     /**
497     * ccs_put_path_group - Delete memory for "struct ccs_path_group_entry".
498     *
499     * @group: Pointer to "struct ccs_path_group_entry".
500     */
501     void ccs_put_path_group(struct ccs_path_group_entry *group)
502     {
503     struct ccs_path_group_member *member;
504     struct ccs_path_group_member *next_member;
505     LIST_HEAD(q);
506     bool can_delete_group = false;
507 kumaneko 2545 if (!group)
508     return;
509 kumaneko 2690 mutex_lock(&ccs_policy_lock);
510 kumaneko 2540 if (atomic_dec_and_test(&group->users)) {
511     list_for_each_entry_safe(member, next_member,
512     &group->path_group_member_list,
513     list) {
514     if (!member->is_deleted)
515     break;
516     list_del(&member->list);
517     list_add(&member->list, &q);
518 kumaneko 111 }
519 kumaneko 2540 if (list_empty(&group->path_group_member_list)) {
520     list_del(&group->list);
521     can_delete_group = true;
522 kumaneko 111 }
523     }
524 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
525 kumaneko 2540 list_for_each_entry_safe(member, next_member, &q, list) {
526     list_del(&member->list);
527     ccs_put_name(member->member_name);
528     ccs_free_element(member);
529     }
530     if (can_delete_group) {
531     ccs_put_name(group->group_name);
532     ccs_free_element(group);
533     }
534 kumaneko 111 }
535    
536 kumaneko 2540 /**
537     * ccs_put_address_group - Delete memory for "struct ccs_address_group_entry".
538     *
539     * @group: Pointer to "struct ccs_address_group_entry".
540     */
541     void ccs_put_address_group(struct ccs_address_group_entry *group)
542     {
543     struct ccs_address_group_member *member;
544     struct ccs_address_group_member *next_member;
545     LIST_HEAD(q);
546     bool can_delete_group = false;
547 kumaneko 2545 if (!group)
548     return;
549 kumaneko 2690 mutex_lock(&ccs_policy_lock);
550 kumaneko 2540 if (atomic_dec_and_test(&group->users)) {
551     list_for_each_entry_safe(member, next_member,
552     &group->address_group_member_list,
553     list) {
554     if (!member->is_deleted)
555     break;
556     list_del(&member->list);
557     list_add(&member->list, &q);
558     }
559     if (list_empty(&group->address_group_member_list)) {
560     list_del(&group->list);
561     can_delete_group = true;
562     }
563     }
564 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
565 kumaneko 2540 list_for_each_entry_safe(member, next_member, &q, list) {
566     list_del(&member->list);
567     if (member->is_ipv6) {
568     ccs_put_ipv6_address(member->min.ipv6);
569     ccs_put_ipv6_address(member->max.ipv6);
570     }
571     ccs_free_element(member);
572     }
573     if (can_delete_group) {
574     ccs_put_name(group->group_name);
575     ccs_free_element(group);
576     }
577     }
578    
579     static LIST_HEAD(ccs_address_list);
580    
581     /**
582     * ccs_get_ipv6_address - Keep the given IPv6 address on the RAM.
583     *
584     * @addr: Pointer to "struct in6_addr".
585     *
586     * Returns pointer to "struct in6_addr" on success, NULL otherwise.
587     *
588     * The RAM is shared, so NEVER try to modify or kfree() the returned address.
589     */
590     const struct in6_addr *ccs_get_ipv6_address(const struct in6_addr *addr)
591     {
592 kumaneko 2575 struct ccs_ipv6addr_entry *entry;
593     struct ccs_ipv6addr_entry *ptr;
594 kumaneko 2540 int error = -ENOMEM;
595     if (!addr)
596     return NULL;
597     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
598 kumaneko 2690 mutex_lock(&ccs_policy_lock);
599 kumaneko 2540 list_for_each_entry(ptr, &ccs_address_list, list) {
600     if (memcmp(&ptr->addr, addr, sizeof(*addr)))
601     continue;
602     atomic_inc(&ptr->users);
603     error = 0;
604     break;
605     }
606     if (error && ccs_memory_ok(entry)) {
607     ptr = entry;
608     ptr->addr = *addr;
609     atomic_set(&ptr->users, 1);
610     list_add_tail(&ptr->list, &ccs_address_list);
611     entry = NULL;
612     }
613 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
614 kumaneko 2540 kfree(entry);
615     return ptr ? &ptr->addr : NULL;
616     }
617    
618     /**
619     * ccs_put_ipv6_address - Delete the given IPv6 address on the RAM.
620     *
621     * @addr: Pointer to "struct in6_addr".
622     */
623     void ccs_put_ipv6_address(const struct in6_addr *addr)
624     {
625 kumaneko 2575 struct ccs_ipv6addr_entry *ptr;
626 kumaneko 2540 bool can_delete = false;
627     if (!addr)
628     return;
629 kumaneko 2575 ptr = container_of(addr, struct ccs_ipv6addr_entry, addr);
630 kumaneko 2690 mutex_lock(&ccs_policy_lock);
631 kumaneko 2540 if (atomic_dec_and_test(&ptr->users)) {
632     list_del(&ptr->list);
633     can_delete = true;
634     }
635 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
636 kumaneko 2546 if (can_delete)
637     ccs_free_element(ptr);
638 kumaneko 2540 }
639    
640 kumaneko 2553 /**
641 kumaneko 2576 * ccs_put_condition - Delete memory for "struct ccs_condition".
642 kumaneko 2553 *
643 kumaneko 2576 * @cond: Pointer to "struct ccs_condition".
644 kumaneko 2553 */
645 kumaneko 2576 void ccs_put_condition(struct ccs_condition *cond)
646 kumaneko 2553 {
647     const unsigned long *ptr;
648     const struct ccs_argv_entry *argv;
649     const struct ccs_envp_entry *envp;
650     const struct ccs_symlinkp_entry *symlinkp;
651     u16 condc;
652     u16 argc;
653     u16 envc;
654     u16 symlinkc;
655     u16 i;
656     bool can_delete = false;
657     if (!cond)
658     return;
659 kumaneko 2690 mutex_lock(&ccs_policy_lock);
660 kumaneko 2553 if (atomic_dec_and_test(&cond->users)) {
661     list_del(&cond->list);
662     can_delete = true;
663     }
664 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
665 kumaneko 2553 if (!can_delete)
666     return;
667 kumaneko 2698 condc = cond->condc;
668     argc = cond->argc;
669     envc = cond->envc;
670     symlinkc = cond->symlinkc;
671 kumaneko 2553 ptr = (const unsigned long *) (cond + 1);
672     argv = (const struct ccs_argv_entry *) (ptr + condc);
673     envp = (const struct ccs_envp_entry *) (argv + argc);
674     symlinkp = (const struct ccs_symlinkp_entry *) (envp + envc);
675     for (i = 0; i < argc; argv++, i++)
676     ccs_put_name(argv->value);
677     for (i = 0; i < envc; envp++, i++) {
678     ccs_put_name(envp->name);
679     ccs_put_name(envp->value);
680     }
681     for (i = 0; i < symlinkc; symlinkp++, i++)
682     ccs_put_name(symlinkp->value);
683     ccs_free_element(cond);
684     }
685    
686 kumaneko 2701 static atomic_t ccs_allocated_memory_for_savename;
687 kumaneko 2002 static unsigned int ccs_quota_for_savename;
688 kumaneko 111
689     #define MAX_HASH 256
690    
691 kumaneko 1052 /* Structure for string data. */
692 kumaneko 2002 struct ccs_name_entry {
693 kumaneko 2540 struct list_head list;
694     atomic_t users;
695 kumaneko 2002 struct ccs_path_info entry;
696 kumaneko 214 };
697 kumaneko 111
698 kumaneko 2002 /* The list for "struct ccs_name_entry". */
699 kumaneko 2540 static struct list_head ccs_name_list[MAX_HASH];
700     static DEFINE_MUTEX(ccs_name_list_lock);
701 kumaneko 731
702 kumaneko 1052 /**
703 kumaneko 2540 * ccs_get_name - Allocate memory for string data.
704 kumaneko 1052 *
705     * @name: The string to store into the permernent memory.
706     *
707 kumaneko 2002 * Returns pointer to "struct ccs_path_info" on success, NULL otherwise.
708 kumaneko 1052 */
709 kumaneko 2540 const struct ccs_path_info *ccs_get_name(const char *name)
710 kumaneko 111 {
711 kumaneko 2002 struct ccs_name_entry *ptr;
712 kumaneko 111 unsigned int hash;
713     int len;
714 kumaneko 2540 int allocated_len;
715    
716 kumaneko 1052 if (!name)
717     return NULL;
718 kumaneko 111 len = strlen(name) + 1;
719     if (len > CCS_MAX_PATHNAME_LEN) {
720 kumaneko 2551 printk(KERN_WARNING "ERROR: Name too long. (%s)\n", __func__);
721 kumaneko 111 return NULL;
722     }
723     hash = full_name_hash((const unsigned char *) name, len - 1);
724 kumaneko 2540 /***** EXCLUSIVE SECTION START *****/
725     mutex_lock(&ccs_name_list_lock);
726     list_for_each_entry(ptr, &ccs_name_list[hash % MAX_HASH], list) {
727     if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
728     continue;
729     atomic_inc(&ptr->users);
730     goto out;
731 kumaneko 111 }
732 kumaneko 2711 ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL);
733 kumaneko 2540 allocated_len = ptr ? ksize(ptr) : 0;
734     if (!allocated_len ||
735     (ccs_quota_for_savename &&
736 kumaneko 2701 atomic_read(&ccs_allocated_memory_for_savename) + allocated_len
737 kumaneko 2540 > ccs_quota_for_savename)) {
738     kfree(ptr);
739     ptr = NULL;
740 kumaneko 2551 printk(KERN_WARNING "ERROR: Out of memory. (%s)\n", __func__);
741 kumaneko 2040 if (!ccs_policy_loaded)
742 kumaneko 1052 panic("MAC Initialization failed.\n");
743 kumaneko 731 goto out;
744     }
745 kumaneko 2701 atomic_add(allocated_len, &ccs_allocated_memory_for_savename);
746 kumaneko 2540 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
747     memmove((char *) ptr->entry.name, name, len);
748     atomic_set(&ptr->users, 1);
749 kumaneko 1052 ccs_fill_path_info(&ptr->entry);
750 kumaneko 2540 list_add_tail(&ptr->list, &ccs_name_list[hash % MAX_HASH]);
751 kumaneko 111 out:
752 kumaneko 2540 mutex_unlock(&ccs_name_list_lock);
753     /***** EXCLUSIVE SECTION END *****/
754 kumaneko 111 return ptr ? &ptr->entry : NULL;
755     }
756    
757 kumaneko 2540 /**
758     * ccs_put_name - Delete shared memory for string data.
759     *
760     * @name: Pointer to "struct ccs_path_info".
761     */
762     void ccs_put_name(const struct ccs_path_info *name)
763     {
764     struct ccs_name_entry *ptr;
765     bool can_delete = false;
766     if (!name)
767     return;
768     ptr = container_of(name, struct ccs_name_entry, entry);
769     /***** EXCLUSIVE SECTION START *****/
770     mutex_lock(&ccs_name_list_lock);
771     if (atomic_dec_and_test(&ptr->users)) {
772     list_del(&ptr->list);
773     can_delete = true;
774     }
775     mutex_unlock(&ccs_name_list_lock);
776     /***** EXCLUSIVE SECTION END *****/
777     if (can_delete) {
778 kumaneko 2701 atomic_sub(ksize(ptr), &ccs_allocated_memory_for_savename);
779 kumaneko 2540 kfree(ptr);
780     }
781     }
782    
783 kumaneko 1052 /* Structure for temporarily allocated memory. */
784 kumaneko 2002 struct ccs_cache_entry {
785 kumaneko 111 struct list_head list;
786     void *ptr;
787     int size;
788 kumaneko 214 };
789 kumaneko 111
790 kumaneko 2702 struct srcu_struct ccs_ss;
791    
792 kumaneko 1052 /**
793     * ccs_realpath_init - Initialize realpath related code.
794     *
795     * Returns 0.
796     */
797     static int __init ccs_realpath_init(void)
798 kumaneko 111 {
799 kumaneko 731 int i;
800 kumaneko 2540 /* Constraint for ccs_get_name(). */
801 kumaneko 1052 if (CCS_MAX_PATHNAME_LEN > PAGE_SIZE)
802     panic("Bad size.");
803 kumaneko 2037 /* Constraint for "struct ccs_execve_entry"->tmp users. */
804     if (CCS_MAX_PATHNAME_LEN > CCS_EXEC_TMPSIZE)
805     panic("Bad size.");
806 kumaneko 2702 if (init_srcu_struct(&ccs_ss))
807     panic("Out of memory.");
808 kumaneko 1052 for (i = 0; i < MAX_HASH; i++)
809 kumaneko 2540 INIT_LIST_HEAD(&ccs_name_list[i]);
810     INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);
811     ccs_kernel_domain.domainname = ccs_get_name(ROOT_NAME);
812 kumaneko 2692 list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);
813     if (ccs_find_domain(ROOT_NAME) != &ccs_kernel_domain)
814 kumaneko 2282 panic("Can't register ccs_kernel_domain");
815 kumaneko 2703 #ifdef CONFIG_CCSECURITY_BUILTIN_INITIALIZERS
816 kumaneko 2308 {
817     /* Load built-in policy. */
818 kumaneko 2392 static char ccs_builtin_initializers[] __initdata
819 kumaneko 2703 = CONFIG_CCSECURITY_BUILTIN_INITIALIZERS;
820 kumaneko 2392 char *cp = ccs_builtin_initializers;
821     ccs_normalize_line(cp);
822     while (cp && *cp) {
823     char *cp2 = strchr(cp, ' ');
824     if (cp2)
825     *cp2++ = '\0';
826     ccs_write_domain_initializer_policy(cp, false, false);
827     cp = cp2;
828 kumaneko 2308 }
829     }
830     #endif
831 kumaneko 1052 return 0;
832 kumaneko 111 }
833    
834 kumaneko 1084 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
835 kumaneko 1052 __initcall(ccs_realpath_init);
836 kumaneko 1084 #else
837 kumaneko 1106 core_initcall(ccs_realpath_init);
838 kumaneko 1084 #endif
839 kumaneko 1052
840 kumaneko 2713 unsigned int ccs_audit_log_memory_size;
841     unsigned int ccs_quota_for_audit_log;
842 kumaneko 1052
843 kumaneko 2713 unsigned int ccs_query_memory_size;
844     unsigned int ccs_quota_for_query;
845    
846 kumaneko 1052 /**
847 kumaneko 1180 * ccs_read_memory_counter - Check for memory usage.
848     *
849     * @head: Pointer to "struct ccs_io_buffer".
850     *
851     * Returns memory usage.
852     */
853     int ccs_read_memory_counter(struct ccs_io_buffer *head)
854     {
855     if (!head->read_eof) {
856 kumaneko 2701 const unsigned int shared
857     = atomic_read(&ccs_allocated_memory_for_savename);
858     const unsigned int private
859     = atomic_read(&ccs_allocated_memory_for_elements);
860 kumaneko 2713 const unsigned int audit_log = ccs_audit_log_memory_size;
861     const unsigned int query = ccs_query_memory_size;
862 kumaneko 1180 char buffer[64];
863     memset(buffer, 0, sizeof(buffer));
864 kumaneko 2002 if (ccs_quota_for_savename)
865 kumaneko 1180 snprintf(buffer, sizeof(buffer) - 1,
866 kumaneko 2002 " (Quota: %10u)", ccs_quota_for_savename);
867 kumaneko 1180 else
868     buffer[0] = '\0';
869 kumaneko 2713 ccs_io_printf(head, "Policy (string): %10u%s\n",
870     shared, buffer);
871 kumaneko 2002 if (ccs_quota_for_elements)
872 kumaneko 1180 snprintf(buffer, sizeof(buffer) - 1,
873 kumaneko 2002 " (Quota: %10u)", ccs_quota_for_elements);
874 kumaneko 1180 else
875     buffer[0] = '\0';
876 kumaneko 2713 ccs_io_printf(head, "Policy (non-string): %10u%s\n",
877     private, buffer);
878     if (ccs_quota_for_audit_log)
879 kumaneko 1903 snprintf(buffer, sizeof(buffer) - 1,
880 kumaneko 2713 " (Quota: %10u)", ccs_quota_for_audit_log);
881 kumaneko 1903 else
882     buffer[0] = '\0';
883 kumaneko 2713 ccs_io_printf(head, "Audit logs: %10u%s\n",
884     audit_log, buffer);
885     if (ccs_quota_for_query)
886     snprintf(buffer, sizeof(buffer) - 1,
887     " (Quota: %10u)", ccs_quota_for_query);
888     else
889     buffer[0] = '\0';
890     ccs_io_printf(head, "Interactive enforcement: %10u%s\n",
891     query, buffer);
892     ccs_io_printf(head, "Total: %10u\n",
893     shared + private + audit_log + query);
894 kumaneko 1180 head->read_eof = true;
895     }
896     return 0;
897     }
898    
899     /**
900     * ccs_write_memory_quota - Set memory quota.
901     *
902     * @head: Pointer to "struct ccs_io_buffer".
903     *
904     * Returns 0.
905     */
906     int ccs_write_memory_quota(struct ccs_io_buffer *head)
907     {
908     char *data = head->write_buf;
909     unsigned int size;
910 kumaneko 2713 if (sscanf(data, "Policy (string): %u", &size) == 1)
911 kumaneko 2002 ccs_quota_for_savename = size;
912 kumaneko 2713 else if (sscanf(data, "Policy (non-string): %u", &size) == 1)
913 kumaneko 2002 ccs_quota_for_elements = size;
914 kumaneko 2713 else if (sscanf(data, "Audit logs: %u", &size) == 1)
915     ccs_quota_for_audit_log = size;
916     else if (sscanf(data, "Interactive enforcement: %u", &size) == 1)
917     ccs_quota_for_query = size;
918 kumaneko 1180 return 0;
919     }
920 kumaneko 2540
921 kumaneko 2701 /* Garbage collector functions */
922    
923     enum ccs_gc_id {
924     CCS_ID_CONDITION,
925     CCS_ID_RESERVEDPORT,
926     CCS_ID_ADDRESS_GROUP,
927     CCS_ID_ADDRESS_GROUP_MEMBER,
928     CCS_ID_PATH_GROUP,
929     CCS_ID_PATH_GROUP_MEMBER,
930     CCS_ID_GLOBAL_ENV,
931     CCS_ID_AGGREGATOR,
932     CCS_ID_DOMAIN_INITIALIZER,
933     CCS_ID_DOMAIN_KEEPER,
934     CCS_ID_ALIAS,
935     CCS_ID_GLOBALLY_READABLE,
936     CCS_ID_PATTERN,
937     CCS_ID_NO_REWRITE,
938     CCS_ID_MANAGER,
939     CCS_ID_ACL,
940     CCS_ID_DOMAIN
941     };
942    
943     struct ccs_gc_entry {
944     struct list_head list;
945     int type;
946     void *element;
947     };
948    
949     /* Caller holds ccs_policy_lock mutex. */
950     static bool ccs_add_to_gc(const int type, void *element, struct list_head *head)
951 kumaneko 2540 {
952 kumaneko 2711 struct ccs_gc_entry *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
953 kumaneko 2701 if (!entry)
954     return false;
955     entry->type = type;
956     entry->element = element;
957     list_add(&entry->list, head);
958     return true;
959 kumaneko 2540 }
960    
961 kumaneko 2701 static inline void ccs_gc_del_domain_initializer
962     (struct ccs_domain_initializer_entry *ptr)
963 kumaneko 2540 {
964 kumaneko 2701 ccs_put_name(ptr->domainname);
965     ccs_put_name(ptr->program);
966 kumaneko 2540 }
967    
968 kumaneko 2701 static inline void ccs_gc_del_domain_keeper
969     (struct ccs_domain_keeper_entry *ptr)
970 kumaneko 2540 {
971 kumaneko 2701 ccs_put_name(ptr->domainname);
972     ccs_put_name(ptr->program);
973 kumaneko 2540 }
974    
975 kumaneko 2701 static void ccs_del_allow_read(struct ccs_globally_readable_file_entry *ptr)
976 kumaneko 2540 {
977 kumaneko 2701 ccs_put_name(ptr->filename);
978     ccs_memory_free(ptr);
979 kumaneko 2540 }
980    
981 kumaneko 2701 static void ccs_del_allow_env(struct ccs_globally_usable_env_entry *ptr)
982 kumaneko 2540 {
983 kumaneko 2701 ccs_put_name(ptr->env);
984     ccs_memory_free(ptr);
985 kumaneko 2540 }
986    
987 kumaneko 2701 static void ccs_del_file_pattern(struct ccs_pattern_entry *ptr)
988 kumaneko 2540 {
989 kumaneko 2701 ccs_put_name(ptr->pattern);
990     ccs_memory_free(ptr);
991 kumaneko 2540 }
992    
993 kumaneko 2701 static void ccs_del_no_rewrite(struct ccs_no_rewrite_entry *ptr)
994 kumaneko 2540 {
995 kumaneko 2701 ccs_put_name(ptr->pattern);
996     ccs_memory_free(ptr);
997 kumaneko 2540 }
998    
999 kumaneko 2701 static void ccs_del_domain_initializer(struct ccs_domain_initializer_entry *ptr)
1000 kumaneko 2540 {
1001 kumaneko 2701 ccs_put_name(ptr->domainname);
1002     ccs_put_name(ptr->program);
1003     ccs_memory_free(ptr);
1004 kumaneko 2540 }
1005    
1006 kumaneko 2701 static void ccs_del_domain_keeper(struct ccs_domain_keeper_entry *ptr)
1007 kumaneko 2540 {
1008 kumaneko 2701 ccs_put_name(ptr->domainname);
1009     ccs_put_name(ptr->program);
1010     ccs_memory_free(ptr);
1011 kumaneko 2540 }
1012    
1013 kumaneko 2701 static void ccs_del_alias(struct ccs_alias_entry *ptr)
1014     {
1015     ccs_put_name(ptr->original_name);
1016     ccs_put_name(ptr->aliased_name);
1017     ccs_memory_free(ptr);
1018     }
1019    
1020     static void ccs_del_aggregator(struct ccs_aggregator_entry *ptr)
1021     {
1022     ccs_put_name(ptr->original_name);
1023     ccs_put_name(ptr->aggregated_name);
1024     ccs_memory_free(ptr);
1025     }
1026    
1027     static void ccs_del_manager(struct ccs_policy_manager_entry *ptr)
1028     {
1029     ccs_put_name(ptr->manager);
1030     ccs_memory_free(ptr);
1031     }
1032    
1033 kumaneko 2540 /* For compatibility with older kernels. */
1034     #ifndef for_each_process
1035     #define for_each_process for_each_task
1036     #endif
1037    
1038     /**
1039     * ccs_used_by_task - Check whether the given pointer is referenced by a task.
1040     *
1041     * @domain: Pointer to "struct ccs_domain_info".
1042     *
1043     * Returns true if @ptr is in use, false otherwise.
1044     */
1045     static bool ccs_used_by_task(struct ccs_domain_info *domain)
1046     {
1047     bool in_use = false;
1048     struct task_struct *p;
1049     /***** CRITICAL SECTION START *****/
1050     read_lock(&tasklist_lock);
1051     for_each_process(p) {
1052     if (p->ccs_domain_info != domain)
1053     continue;
1054     in_use = true;
1055     break;
1056     }
1057     read_unlock(&tasklist_lock);
1058     /***** CRITICAL SECTION END *****/
1059     return in_use;
1060     }
1061    
1062 kumaneko 2701 static void ccs_del_acl(struct ccs_acl_info *acl)
1063 kumaneko 2540 {
1064 kumaneko 2701 struct ccs_single_path_acl_record *acl1;
1065     struct ccs_double_path_acl_record *acl2;
1066     struct ccs_ip_network_acl_record *acl3;
1067     struct ccs_ioctl_acl_record *acl4;
1068     struct ccs_argv0_acl_record *acl5;
1069     struct ccs_env_acl_record *acl6;
1070     struct ccs_capability_acl_record *acl7;
1071     struct ccs_signal_acl_record *acl8;
1072     struct ccs_execute_handler_record *acl9;
1073 kumaneko 2707 struct ccs_mount_acl_record *acl10;
1074     struct ccs_umount_acl_record *acl11;
1075     struct ccs_chroot_acl_record *acl12;
1076     struct ccs_pivot_root_acl_record *acl13;
1077 kumaneko 2701 ccs_put_condition(acl->cond);
1078     switch (ccs_acl_type1(acl)) {
1079     case TYPE_SINGLE_PATH_ACL:
1080     acl1 = container_of(acl, struct ccs_single_path_acl_record,
1081     head);
1082     if (acl1->u_is_group)
1083     ccs_put_path_group(acl1->u.group);
1084     else
1085     ccs_put_name(acl1->u.filename);
1086     break;
1087     case TYPE_DOUBLE_PATH_ACL:
1088     acl2 = container_of(acl, struct ccs_double_path_acl_record,
1089     head);
1090     if (acl2->u1_is_group)
1091     ccs_put_path_group(acl2->u1.group1);
1092     else
1093     ccs_put_name(acl2->u1.filename1);
1094     if (acl2->u2_is_group)
1095     ccs_put_path_group(acl2->u2.group2);
1096     else
1097     ccs_put_name(acl2->u2.filename2);
1098     break;
1099     case TYPE_IP_NETWORK_ACL:
1100     acl3 = container_of(acl, struct ccs_ip_network_acl_record,
1101     head);
1102     if (acl3->record_type == IP_RECORD_TYPE_ADDRESS_GROUP)
1103     ccs_put_address_group(acl3->u.group);
1104     else if (acl3->record_type == IP_RECORD_TYPE_IPv6) {
1105     ccs_put_ipv6_address(acl3->u.ipv6.min);
1106     ccs_put_ipv6_address(acl3->u.ipv6.max);
1107     }
1108     break;
1109     case TYPE_IOCTL_ACL:
1110     acl4 = container_of(acl, struct ccs_ioctl_acl_record, head);
1111     if (acl4->u_is_group)
1112     ccs_put_path_group(acl4->u.group);
1113     else
1114     ccs_put_name(acl4->u.filename);
1115     break;
1116     case TYPE_ARGV0_ACL:
1117     acl5 = container_of(acl, struct ccs_argv0_acl_record, head);
1118     ccs_put_name(acl5->argv0);
1119     break;
1120     case TYPE_ENV_ACL:
1121     acl6 = container_of(acl, struct ccs_env_acl_record, head);
1122     ccs_put_name(acl6->env);
1123     break;
1124     case TYPE_CAPABILITY_ACL:
1125     acl7 = container_of(acl, struct ccs_capability_acl_record,
1126     head);
1127     break;
1128     case TYPE_SIGNAL_ACL:
1129     acl8 = container_of(acl, struct ccs_signal_acl_record,
1130     head);
1131     ccs_put_name(acl8->domainname);
1132     break;
1133     case TYPE_EXECUTE_HANDLER:
1134     case TYPE_DENIED_EXECUTE_HANDLER:
1135     acl9 = container_of(acl, struct ccs_execute_handler_record,
1136     head);
1137     ccs_put_name(acl9->handler);
1138     break;
1139 kumaneko 2707 case TYPE_MOUNT_ACL:
1140     acl10 = container_of(acl, struct ccs_mount_acl_record, head);
1141     ccs_put_name(acl10->dev_name);
1142     ccs_put_name(acl10->dir_name);
1143     ccs_put_name(acl10->fs_type);
1144     break;
1145     case TYPE_UMOUNT_ACL:
1146     acl11 = container_of(acl, struct ccs_umount_acl_record, head);
1147     ccs_put_name(acl11->dir);
1148     break;
1149     case TYPE_CHROOT_ACL:
1150     acl12 = container_of(acl, struct ccs_chroot_acl_record, head);
1151     ccs_put_name(acl12->dir);
1152     break;
1153     case TYPE_PIVOT_ROOT_ACL:
1154     acl13 = container_of(acl, struct ccs_pivot_root_acl_record,
1155     head);
1156     ccs_put_name(acl13->old_root);
1157     ccs_put_name(acl13->new_root);
1158     break;
1159    
1160 kumaneko 2701 }
1161     ccs_memory_free(acl);
1162     }
1163    
1164     static bool ccs_del_domain(struct ccs_domain_info *domain)
1165     {
1166     if (ccs_used_by_task(domain))
1167     return false;
1168     ccs_put_name(domain->domainname);
1169     ccs_memory_free(domain);
1170     return true;
1171     }
1172    
1173     static void ccs_del_path_group_member(struct ccs_path_group_member *member)
1174     {
1175     ccs_put_name(member->member_name);
1176     ccs_free_element(member);
1177     }
1178    
1179     static void ccs_del_path_group(struct ccs_path_group_entry *group)
1180     {
1181     ccs_put_name(group->group_name);
1182     ccs_free_element(group);
1183     }
1184    
1185     static void ccs_del_address_group_member
1186     (struct ccs_address_group_member *member)
1187     {
1188     if (member->is_ipv6) {
1189     ccs_put_ipv6_address(member->min.ipv6);
1190     ccs_put_ipv6_address(member->max.ipv6);
1191     }
1192     ccs_free_element(member);
1193     }
1194    
1195     static void ccs_del_address_group(struct ccs_address_group_entry *group)
1196     {
1197     ccs_put_name(group->group_name);
1198     ccs_free_element(group);
1199     }
1200    
1201     static void ccs_del_reservedport(struct ccs_reserved_entry *ptr)
1202     {
1203     ccs_memory_free(ptr);
1204     }
1205    
1206     static void ccs_del_condition(struct ccs_condition *ptr)
1207     {
1208     int i;
1209     u16 condc = ptr->condc;
1210     u16 argc = ptr->argc;
1211     u16 envc = ptr->envc;
1212     u16 symlinkc = ptr->symlinkc;
1213     unsigned long *ptr2 = (unsigned long *) (ptr + 1);
1214     struct ccs_argv_entry *argv = (struct ccs_argv_entry *) (ptr2 + condc);
1215     struct ccs_envp_entry *envp = (struct ccs_envp_entry *) (argv + argc);
1216     struct ccs_symlinkp_entry *symlinkp
1217     = (struct ccs_symlinkp_entry *) (envp + envc);
1218     for (i = 0; i < argc; i++)
1219     ccs_put_name(argv[i].value);
1220     for (i = 0; i < envc; i++) {
1221     ccs_put_name(envp[i].name);
1222     ccs_put_name(envp[i].value);
1223     }
1224     for (i = 0; i < symlinkc; i++)
1225     ccs_put_name(symlinkp[i].value);
1226     ccs_memory_free(ptr);
1227     }
1228    
1229     static int ccs_gc_thread(void *unused)
1230     {
1231     static DEFINE_MUTEX(ccs_gc_mutex);
1232     static LIST_HEAD(ccs_gc_queue);
1233     if (!mutex_trylock(&ccs_gc_mutex))
1234     return 0;
1235 kumaneko 2690 mutex_lock(&ccs_policy_lock);
1236 kumaneko 2701 {
1237     struct ccs_globally_readable_file_entry *ptr;
1238     list_for_each_entry_rcu(ptr, &ccs_globally_readable_list,
1239     list) {
1240     if (!ptr->is_deleted)
1241     continue;
1242     if (ccs_add_to_gc(CCS_ID_GLOBALLY_READABLE, ptr,
1243     &ccs_gc_queue))
1244     list_del_rcu(&ptr->list);
1245     else
1246     break;
1247 kumaneko 2540 }
1248 kumaneko 2701 }
1249     {
1250     struct ccs_globally_usable_env_entry *ptr;
1251     list_for_each_entry_rcu(ptr, &ccs_globally_usable_env_list,
1252     list) {
1253     if (!ptr->is_deleted)
1254 kumaneko 2540 continue;
1255 kumaneko 2701 if (ccs_add_to_gc(CCS_ID_GLOBAL_ENV, ptr,
1256     &ccs_gc_queue))
1257     list_del_rcu(&ptr->list);
1258     else
1259     break;
1260 kumaneko 2540 }
1261 kumaneko 2701 }
1262     {
1263     struct ccs_pattern_entry *ptr;
1264     list_for_each_entry_rcu(ptr, &ccs_pattern_list, list) {
1265     if (!ptr->is_deleted)
1266     continue;
1267     if (ccs_add_to_gc(CCS_ID_PATTERN, ptr,
1268     &ccs_gc_queue))
1269     list_del_rcu(&ptr->list);
1270     else
1271     break;
1272 kumaneko 2540 }
1273     }
1274 kumaneko 2701 {
1275     struct ccs_no_rewrite_entry *ptr;
1276     list_for_each_entry_rcu(ptr, &ccs_no_rewrite_list, list) {
1277     if (!ptr->is_deleted)
1278     continue;
1279     if (ccs_add_to_gc(CCS_ID_NO_REWRITE, ptr,
1280     &ccs_gc_queue))
1281     list_del_rcu(&ptr->list);
1282 kumaneko 2540 else
1283 kumaneko 2701 break;
1284     }
1285     }
1286     {
1287     struct ccs_domain_initializer_entry *ptr;
1288     list_for_each_entry_rcu(ptr, &ccs_domain_initializer_list,
1289     list) {
1290     if (!ptr->is_deleted)
1291     continue;
1292     if (ccs_add_to_gc(CCS_ID_DOMAIN_INITIALIZER,
1293     ptr, &ccs_gc_queue))
1294     list_del_rcu(&ptr->list);
1295 kumaneko 2540 else
1296 kumaneko 2701 break;
1297     }
1298     }
1299     {
1300     struct ccs_domain_keeper_entry *ptr;
1301     list_for_each_entry_rcu(ptr, &ccs_domain_keeper_list, list) {
1302     if (!ptr->is_deleted)
1303     continue;
1304     if (ccs_add_to_gc(CCS_ID_DOMAIN_KEEPER, ptr,
1305     &ccs_gc_queue))
1306     list_del_rcu(&ptr->list);
1307 kumaneko 2540 else
1308 kumaneko 2701 break;
1309     }
1310     }
1311     {
1312     struct ccs_alias_entry *ptr;
1313     list_for_each_entry_rcu(ptr, &ccs_alias_list, list) {
1314     if (!ptr->is_deleted)
1315     continue;
1316     if (ccs_add_to_gc(CCS_ID_ALIAS, ptr, &ccs_gc_queue))
1317     list_del_rcu(&ptr->list);
1318 kumaneko 2540 else
1319 kumaneko 2701 break;
1320 kumaneko 2540 }
1321     }
1322 kumaneko 2701 {
1323     struct ccs_policy_manager_entry *ptr;
1324     list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {
1325     if (!ptr->is_deleted)
1326     continue;
1327     if (ccs_add_to_gc(CCS_ID_MANAGER, ptr, &ccs_gc_queue))
1328     list_del_rcu(&ptr->list);
1329     else
1330     break;
1331     }
1332 kumaneko 2540 }
1333 kumaneko 2701 {
1334     struct ccs_aggregator_entry *ptr;
1335     list_for_each_entry_rcu(ptr, &ccs_aggregator_list, list) {
1336     if (!ptr->is_deleted)
1337     continue;
1338     if (ccs_add_to_gc(CCS_ID_AGGREGATOR, ptr,
1339     &ccs_gc_queue))
1340     list_del_rcu(&ptr->list);
1341     else
1342 kumaneko 2575 break;
1343     }
1344     }
1345 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
1346 kumaneko 2701 {
1347     struct ccs_domain_info *domain;
1348     list_for_each_entry_rcu(domain, &ccs_domain_list, list) {
1349     struct ccs_acl_info *acl;
1350     list_for_each_entry_rcu(acl, &domain->acl_info_list,
1351     list) {
1352     if (!(acl->type & ACL_DELETED))
1353     continue;
1354     if (ccs_add_to_gc(CCS_ID_ACL, acl,
1355     &ccs_gc_queue))
1356     list_del_rcu(&acl->list);
1357     else
1358     break;
1359     }
1360     if (!domain->is_deleted ||
1361     ccs_used_by_task(domain))
1362     continue;
1363     if (ccs_add_to_gc(CCS_ID_DOMAIN, domain, &ccs_gc_queue))
1364     list_del_rcu(&domain->list);
1365     else
1366     break;
1367     }
1368 kumaneko 2575 }
1369 kumaneko 2701 {
1370     struct ccs_path_group_entry *group;
1371     list_for_each_entry_rcu(group, &ccs_path_group_list, list) {
1372     struct ccs_path_group_member *member;
1373     list_for_each_entry_rcu(member,
1374     &group->path_group_member_list,
1375     list) {
1376     if (!member->is_deleted)
1377     continue;
1378     if (ccs_add_to_gc(CCS_ID_PATH_GROUP_MEMBER,
1379     member, &ccs_gc_queue))
1380     list_del_rcu(&member->list);
1381     else
1382     break;
1383     }
1384     if (!list_empty(&group->path_group_member_list) ||
1385     atomic_read(&group->users))
1386     continue;
1387     if (ccs_add_to_gc(CCS_ID_PATH_GROUP, group,
1388     &ccs_gc_queue))
1389     list_del_rcu(&group->list);
1390     else
1391     break;
1392     }
1393 kumaneko 2575 }
1394 kumaneko 2701 {
1395     struct ccs_address_group_entry *group;
1396     list_for_each_entry_rcu(group, &ccs_address_group_list, list) {
1397     struct ccs_address_group_member *member;
1398     list_for_each_entry_rcu(member,
1399     &group->address_group_member_list,
1400     list) {
1401     if (!member->is_deleted)
1402     break;
1403     if (ccs_add_to_gc(CCS_ID_ADDRESS_GROUP_MEMBER,
1404     member, &ccs_gc_queue))
1405     list_del_rcu(&member->list);
1406     else
1407     break;
1408     }
1409     if (!list_empty(&group->address_group_member_list) ||
1410     atomic_read(&group->users))
1411     continue;
1412     if (ccs_add_to_gc(CCS_ID_ADDRESS_GROUP, group,
1413     &ccs_gc_queue))
1414     list_del_rcu(&group->list);
1415     else
1416 kumaneko 2575 break;
1417     }
1418 kumaneko 2701 }
1419     {
1420     struct ccs_reserved_entry *ptr;
1421     list_for_each_entry_rcu(ptr, &ccs_reservedport_list, list) {
1422     if (!ptr->is_deleted)
1423     continue;
1424     if (ccs_add_to_gc(CCS_ID_RESERVEDPORT, ptr,
1425     &ccs_gc_queue))
1426     list_del_rcu(&ptr->list);
1427     else
1428     break;
1429     }
1430 kumaneko 2575 }
1431 kumaneko 2701 {
1432     struct ccs_condition *ptr;
1433     list_for_each_entry_rcu(ptr, &ccs_condition_list, list) {
1434     if (atomic_read(&ptr->users))
1435     continue;
1436     if (ccs_add_to_gc(CCS_ID_CONDITION, ptr, &ccs_gc_queue))
1437     list_del_rcu(&ptr->list);
1438     else
1439     break;
1440     }
1441 kumaneko 2575 }
1442 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
1443 kumaneko 2701 if (list_empty(&ccs_gc_queue))
1444     goto done;
1445     synchronize_srcu(&ccs_ss);
1446     {
1447     struct ccs_gc_entry *p;
1448     struct ccs_gc_entry *tmp;
1449     list_for_each_entry_safe(p, tmp, &ccs_gc_queue, list) {
1450     switch (p->type) {
1451     case CCS_ID_DOMAIN_INITIALIZER:
1452     ccs_del_domain_initializer(p->element);
1453     break;
1454     case CCS_ID_DOMAIN_KEEPER:
1455     ccs_del_domain_keeper(p->element);
1456     break;
1457     case CCS_ID_ALIAS:
1458     ccs_del_alias(p->element);
1459     break;
1460     case CCS_ID_GLOBALLY_READABLE:
1461     ccs_del_allow_read(p->element);
1462     break;
1463     case CCS_ID_PATTERN:
1464     ccs_del_file_pattern(p->element);
1465     break;
1466     case CCS_ID_NO_REWRITE:
1467     ccs_del_no_rewrite(p->element);
1468     break;
1469     case CCS_ID_MANAGER:
1470     ccs_del_manager(p->element);
1471     break;
1472     case CCS_ID_GLOBAL_ENV:
1473     ccs_del_allow_env(p->element);
1474     break;
1475     case CCS_ID_AGGREGATOR:
1476     ccs_del_aggregator(p->element);
1477     break;
1478     case CCS_ID_PATH_GROUP_MEMBER:
1479     ccs_del_path_group_member(p->element);
1480     break;
1481     case CCS_ID_PATH_GROUP:
1482     ccs_del_path_group(p->element);
1483     break;
1484     case CCS_ID_ADDRESS_GROUP_MEMBER:
1485     ccs_del_address_group_member(p->element);
1486     break;
1487     case CCS_ID_ADDRESS_GROUP:
1488     ccs_del_address_group(p->element);
1489     break;
1490     case CCS_ID_RESERVEDPORT:
1491     ccs_del_reservedport(p->element);
1492     break;
1493     case CCS_ID_CONDITION:
1494     ccs_del_condition(p->element);
1495     break;
1496     case CCS_ID_ACL:
1497     ccs_del_acl(p->element);
1498     break;
1499     case CCS_ID_DOMAIN:
1500     if (!ccs_del_domain(p->element))
1501     continue;
1502     break;
1503     }
1504     ccs_free_element(p->element);
1505     list_del(&p->list);
1506     kfree(p);
1507     }
1508 kumaneko 2575 }
1509 kumaneko 2701 done:
1510     mutex_unlock(&ccs_gc_mutex);
1511     return 0;
1512 kumaneko 2575 }
1513    
1514 kumaneko 2716 #ifndef _LINUX_SRCU_H
1515 kumaneko 2575
1516 kumaneko 2701 static DEFINE_SPINLOCK(ccs_counter_lock);
1517    
1518 kumaneko 2716 int srcu_read_lock(struct srcu_struct *sp)
1519 kumaneko 2575 {
1520 kumaneko 2701 int idx;
1521     spin_lock(&ccs_counter_lock);
1522     idx = sp->counter_idx;
1523     sp->counter[idx]++;
1524     spin_unlock(&ccs_counter_lock);
1525     return idx;
1526 kumaneko 2575 }
1527    
1528 kumaneko 2716 void srcu_read_unlock(struct srcu_struct *sp, const int idx)
1529 kumaneko 2575 {
1530 kumaneko 2701 spin_lock(&ccs_counter_lock);
1531     sp->counter[idx]--;
1532     spin_unlock(&ccs_counter_lock);
1533 kumaneko 2575 }
1534    
1535 kumaneko 2716 void synchronize_srcu(struct srcu_struct *sp)
1536 kumaneko 2576 {
1537 kumaneko 2701 int idx;
1538     int v;
1539     spin_lock(&ccs_counter_lock);
1540     idx = sp->counter_idx;
1541     sp->counter_idx ^= 1;
1542     v = sp->counter[idx];
1543     spin_unlock(&ccs_counter_lock);
1544     while (v) {
1545     msleep(1000);
1546     spin_lock(&ccs_counter_lock);
1547     v = sp->counter[idx];
1548     spin_unlock(&ccs_counter_lock);
1549 kumaneko 2576 }
1550     }
1551    
1552 kumaneko 2701 #endif

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26