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

Subversion リポジトリの参照

Contents of /branches/ccs-patch/security/ccsecurity/umount.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2897 - (show annotations) (download) (as text)
Wed Aug 12 06:16:57 2009 UTC (14 years, 9 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 4785 byte(s)


1 /*
2 * security/ccsecurity/umount.c
3 *
4 * Copyright (C) 2005-2009 NTT DATA CORPORATION
5 *
6 * Version: 1.7.0-pre 2009/08/08
7 *
8 * This file is applicable to both 2.4.30 and 2.6.11 and later.
9 * See README.ccs for ChangeLog.
10 *
11 */
12
13 #include <linux/slab.h>
14 #include <linux/version.h>
15 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
16 #include <linux/mount.h>
17 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
18 #include <linux/namespace.h>
19 #endif
20 #include "internal.h"
21
22 /**
23 * ccs_audit_umount_log - Audit unmount log.
24 *
25 * @r: Pointer to "struct ccs_request_info".
26 * @dir: Mount point.
27 * @is_granted: True if this is a granted log.
28 *
29 * Returns 0 on success, negative value otherwise.
30 */
31 static int ccs_audit_umount_log(struct ccs_request_info *r,
32 const char *dir, const bool is_granted)
33 {
34 if (!is_granted && ccs_verbose_mode(r->domain))
35 printk(KERN_WARNING "SAKURA-%s: umount %s denied for %s\n",
36 ccs_get_msg(r->mode == 3), dir,
37 ccs_get_last_name(r->domain));
38 return ccs_write_audit_log(is_granted, r, CCS_KEYWORD_ALLOW_UNMOUNT
39 "%s\n", dir);
40 }
41
42 /**
43 * ccs_update_umount_acl - Update "struct ccs_umount_acl_record" list.
44 *
45 * @dir: The name of directrory.
46 * @is_delete: True if it is a delete request.
47 *
48 * Returns 0 on success, negative value otherwise.
49 */
50 static int ccs_update_umount_acl(const char *dir,
51 struct ccs_domain_info *domain,
52 struct ccs_condition *condition,
53 const bool is_delete)
54 {
55 struct ccs_umount_acl_record *entry = NULL;
56 struct ccs_acl_info *ptr;
57 struct ccs_umount_acl_record e;
58 int error = is_delete ? -ENOENT : -ENOMEM;
59 memset(&e, 0, sizeof(e));
60 e.head.type = CCS_TYPE_UMOUNT_ACL;
61 e.head.cond = condition;
62 if (!ccs_parse_name_union(dir, &e.dir))
63 return error;
64 if (!is_delete)
65 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
66 mutex_lock(&ccs_policy_lock);
67 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
68 struct ccs_umount_acl_record *acl;
69 if (ccs_acl_type1(ptr) != CCS_TYPE_UMOUNT_ACL)
70 continue;
71 acl = container_of(ptr, struct ccs_umount_acl_record, head);
72 if (ccs_memcmp(acl, &e, offsetof(struct ccs_umount_acl_record,
73 head.cond), sizeof(e)))
74 continue;
75 if (is_delete)
76 error = ccs_del_domain_acl(ptr);
77 else
78 error = ccs_add_domain_acl(NULL, ptr);
79 break;
80 }
81 if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
82 memmove(entry, &e, sizeof(e));
83 memset(&e, 0, sizeof(e));
84 error = ccs_add_domain_acl(domain, &entry->head);
85 entry = NULL;
86 }
87 mutex_unlock(&ccs_policy_lock);
88 ccs_put_name_union(&e.dir);
89 kfree(entry);
90 return error;
91 }
92
93 /**
94 * ccs_may_umount2 - Check permission for unmount.
95 *
96 * @mnt: Pointer to "struct vfsmount".
97 *
98 * Returns 0 on success, negative value otherwise.
99 *
100 * Caller holds ccs_read_lock().
101 */
102 static int ccs_may_umount2(struct vfsmount *mnt)
103 {
104 struct ccs_request_info r;
105 int error;
106 const char *dir0;
107 bool is_enforce;
108 struct ccs_acl_info *ptr;
109 struct ccs_path_info dir;
110 ccs_check_read_lock();
111 if (!ccs_can_sleep())
112 return 0;
113 ccs_init_request_info(&r, NULL, CCS_MAC_FOR_NAMESPACE);
114 is_enforce = (r.mode == 3);
115 if (!r.mode)
116 return 0;
117 retry:
118 error = -EPERM;
119 dir0 = ccs_realpath_from_dentry(mnt->mnt_root, mnt);
120 if (!dir0)
121 goto out;
122 dir.name = dir0;
123 ccs_fill_path_info(&dir);
124 list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {
125 struct ccs_umount_acl_record *acl;
126 if (ccs_acl_type2(ptr) != CCS_TYPE_UMOUNT_ACL)
127 continue;
128 acl = container_of(ptr, struct ccs_umount_acl_record, head);
129 if (!ccs_compare_name_union(&dir, &acl->dir) ||
130 !ccs_check_condition(&r, ptr))
131 continue;
132 r.cond = ptr->cond;
133 error = 0;
134 break;
135 }
136 ccs_audit_umount_log(&r, dir0, !error);
137 if (error)
138 error = ccs_check_supervisor(&r, CCS_KEYWORD_ALLOW_UNMOUNT
139 "%s", ccs_file_pattern(&dir));
140 out:
141 kfree(dir0);
142 if (!is_enforce)
143 error = 0;
144 if (error == 1)
145 goto retry;
146 return error;
147 }
148
149 /**
150 * ccs_may_umount - Check permission for unmount.
151 *
152 * @mnt: Pointer to "struct vfsmount".
153 *
154 * Returns 0 on success, negative value otherwise.
155 */
156 int ccs_may_umount(struct vfsmount *mnt)
157 {
158 const int idx = ccs_read_lock();
159 const int error = ccs_may_umount2(mnt);
160 ccs_read_unlock(idx);
161 return error;
162 }
163
164 /**
165 * ccs_write_umount_policy - Write "struct ccs_umount_acl_record" list.
166 *
167 * @data: String to parse.
168 * @domain: Pointer to "struct ccs_domain_info".
169 * @condition: Pointer to "struct ccs_condition". May be NULL.
170 * @is_delete: True if it is a delete request.
171 *
172 * Returns 0 on sucess, negative value otherwise.
173 */
174 int ccs_write_umount_policy(char *data, struct ccs_domain_info *domain,
175 struct ccs_condition *condition,
176 const bool is_delete)
177 {
178 return ccs_update_umount_acl(data, domain, condition, is_delete);
179 }

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