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

Subversion リポジトリの参照

Contents of /branches/ccs-patch/fs/sakura_pivot.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2690 - (show annotations) (download) (as text)
Wed Jun 24 04:50:19 2009 UTC (14 years, 11 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 6163 byte(s)


1 /*
2 * fs/sakura_pivot.c
3 *
4 * Implementation of the Domain-Free Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 *
8 * Version: 1.6.8 2009/05/28
9 *
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
15 #include <linux/ccs_common.h>
16 #include <linux/sakura.h>
17 #include <linux/realpath.h>
18 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
19 #include <linux/namei.h>
20 #else
21 #include <linux/fs.h>
22 #endif
23
24 /* The list for "struct ccs_pivot_root_entry". */
25 LIST_HEAD(ccs_pivot_root_list);
26
27 /**
28 * ccs_update_pivot_root_acl - Update "struct ccs_pivot_root_entry" list.
29 *
30 * @old_root: The name of old root directory.
31 * @new_root: The name of new root directory.
32 * @is_delete: True if it is a delete request.
33 *
34 * Returns 0 on success, negative value otherwise.
35 */
36 static int ccs_update_pivot_root_acl(const char *old_root, const char *new_root,
37 const bool is_delete)
38 {
39 struct ccs_pivot_root_entry *entry = NULL;
40 struct ccs_pivot_root_entry *ptr;
41 const struct ccs_path_info *saved_old_root;
42 const struct ccs_path_info *saved_new_root;
43 int error = is_delete ? -ENOENT : -ENOMEM;
44 if (!ccs_is_correct_path(old_root, 1, 0, 1) ||
45 !ccs_is_correct_path(new_root, 1, 0, 1))
46 return -EINVAL;
47 saved_old_root = ccs_get_name(old_root);
48 saved_new_root = ccs_get_name(new_root);
49 if (!saved_old_root || !saved_new_root)
50 goto out;
51 if (!is_delete)
52 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
53 mutex_lock(&ccs_policy_lock);
54 list_for_each_entry_rcu(ptr, &ccs_pivot_root_list, list) {
55 if (ptr->old_root != saved_old_root ||
56 ptr->new_root != saved_new_root)
57 continue;
58 ptr->is_deleted = is_delete;
59 error = 0;
60 break;
61 }
62 if (!is_delete && error && ccs_memory_ok(entry)) {
63 entry->old_root = saved_old_root;
64 saved_old_root = NULL;
65 entry->new_root = saved_new_root;
66 saved_new_root = NULL;
67 list_add_tail_rcu(&entry->list, &ccs_pivot_root_list);
68 entry = NULL;
69 error = 0;
70 }
71 mutex_unlock(&ccs_policy_lock);
72 if (!is_delete && !error)
73 printk(KERN_CONT "%sAllow pivot_root(%s, %s)\n", ccs_log_level,
74 new_root, old_root);
75 out:
76 ccs_put_name(saved_old_root);
77 ccs_put_name(saved_new_root);
78 kfree(entry);
79 ccs_update_counter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);
80 return error;
81 }
82
83 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
84 #define PATH_or_NAMEIDATA path
85 #else
86 #define PATH_or_NAMEIDATA nameidata
87 #endif
88 /**
89 * ccs_check_pivot_root_permission - Check permission for pivot_root().
90 *
91 * @old_path: Pointer to "struct path" (for 2.6.27 and later).
92 * Pointer to "struct nameidata" (for 2.6.26 and earlier).
93 * @new_path: Pointer to "struct path" (for 2.6.27 and later).
94 * Pointer to "struct nameidata" (for 2.6.26 and earlier).
95 *
96 * Returns 0 on success, negative value otherwise.
97 *
98 * Caller holds srcu_read_lock(&ccs_ss).
99 */
100 int ccs_check_pivot_root_permission(struct PATH_or_NAMEIDATA *old_path,
101 struct PATH_or_NAMEIDATA *new_path)
102 {
103 struct ccs_request_info r;
104 int error;
105 char *old_root;
106 char *new_root;
107 if (!ccs_can_sleep())
108 return 0;
109 ccs_init_request_info(&r, NULL, CCS_RESTRICT_PIVOT_ROOT);
110 if (!r.mode) {
111 error = 0;
112 goto done;
113 }
114 retry:
115 error = -EPERM;
116 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
117 old_root = ccs_realpath_from_dentry(old_path->path.dentry,
118 old_path->path.mnt);
119 new_root = ccs_realpath_from_dentry(new_path->path.dentry,
120 new_path->path.mnt);
121 #else
122 old_root = ccs_realpath_from_dentry(old_path->dentry, old_path->mnt);
123 new_root = ccs_realpath_from_dentry(new_path->dentry, new_path->mnt);
124 #endif
125 if (old_root && new_root) {
126 struct ccs_path_info old_root_dir;
127 struct ccs_path_info new_root_dir;
128 old_root_dir.name = old_root;
129 ccs_fill_path_info(&old_root_dir);
130 new_root_dir.name = new_root;
131 ccs_fill_path_info(&new_root_dir);
132 if (old_root_dir.is_dir && new_root_dir.is_dir) {
133 struct ccs_pivot_root_entry *ptr;
134 list_for_each_entry_rcu(ptr, &ccs_pivot_root_list,
135 list) {
136 if (ptr->is_deleted)
137 continue;
138 if (!ccs_path_matches_pattern(&old_root_dir,
139 ptr->old_root) ||
140 !ccs_path_matches_pattern(&new_root_dir,
141 ptr->new_root))
142 continue;
143 error = 0;
144 break;
145 }
146 }
147 }
148 if (error) {
149 const bool is_enforce = (r.mode == 3);
150 const char *exename = ccs_get_exe();
151 printk(KERN_WARNING "SAKURA-%s: pivot_root %s %s "
152 "(pid=%d:exe=%s): Permission denied.\n",
153 ccs_get_msg(is_enforce), new_root, old_root,
154 (pid_t) sys_getpid(), exename);
155 if (is_enforce)
156 error = ccs_check_supervisor(&r, "# %s is requesting\n"
157 "pivot_root %s %s\n",
158 exename, new_root,
159 old_root);
160 else
161 error = 0;
162 if (exename)
163 ccs_free(exename);
164 if (r.mode == 1 && old_root && new_root)
165 ccs_update_pivot_root_acl(old_root, new_root, false);
166 }
167 ccs_free(old_root);
168 ccs_free(new_root);
169 if (error == 1)
170 goto retry;
171 done:
172 ccs_exit_request_info(&r);
173 return error;
174 }
175
176 /**
177 * ccs_write_pivot_root_policy - Write "struct ccs_pivot_root_entry" list.
178 *
179 * @data: String to parse.
180 * @is_delete: True if it is a delete request.
181 *
182 * Returns 0 on success, negative value otherwise.
183 */
184 int ccs_write_pivot_root_policy(char *data, const bool is_delete)
185 {
186 char *cp = strchr(data, ' ');
187 if (!cp)
188 return -EINVAL;
189 *cp++ = '\0';
190 return ccs_update_pivot_root_acl(cp, data, is_delete);
191 }
192
193 /**
194 * ccs_read_pivot_root_policy - Read "struct ccs_pivot_root_entry" list.
195 *
196 * @head: Pointer to "struct ccs_io_buffer".
197 *
198 * Returns true on success, false otherwise.
199 *
200 * Caller holds srcu_read_lock(&ccs_ss).
201 */
202 bool ccs_read_pivot_root_policy(struct ccs_io_buffer *head)
203 {
204 struct list_head *pos;
205 bool done = true;
206 list_for_each_cookie(pos, head->read_var2, &ccs_pivot_root_list) {
207 struct ccs_pivot_root_entry *ptr;
208 ptr = list_entry(pos, struct ccs_pivot_root_entry, list);
209 if (ptr->is_deleted)
210 continue;
211 done = ccs_io_printf(head, KEYWORD_ALLOW_PIVOT_ROOT "%s %s\n",
212 ptr->new_root->name, ptr->old_root->name);
213 if (!done)
214 break;
215 }
216 return done;
217 }

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