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

Subversion リポジトリの参照

Contents of /trunk/1.6.x/ccs-patch/fs/sakura_chroot.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1903 - (show annotations) (download) (as text)
Mon Dec 1 06:16:16 2008 UTC (15 years, 5 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 4948 byte(s)


1 /*
2 * fs/sakura_chroot.c
3 *
4 * Implementation of the Domain-Free Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 *
8 * Version: 1.6.6-pre 2008/12/01
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 /* Structure for "allow_chroot" keyword. */
25 struct chroot_entry {
26 struct list1_head list;
27 const struct path_info *dir;
28 bool is_deleted;
29 };
30
31 /* The list for "struct chroot_entry". */
32 static LIST1_HEAD(chroot_list);
33
34 /**
35 * update_chroot_acl - Update "struct chroot_entry" list.
36 *
37 * @dir: The name of directory.
38 * @is_delete: True if it is a delete request.
39 *
40 * Returns 0 on success, negative value otherwise.
41 */
42 static int update_chroot_acl(const char *dir, const bool is_delete)
43 {
44 struct chroot_entry *new_entry;
45 struct chroot_entry *ptr;
46 const struct path_info *saved_dir;
47 static DEFINE_MUTEX(lock);
48 int error = -ENOMEM;
49 if (!ccs_is_correct_path(dir, 1, 0, 1, __func__))
50 return -EINVAL;
51 saved_dir = ccs_save_name(dir);
52 if (!saved_dir)
53 return -ENOMEM;
54 mutex_lock(&lock);
55 list1_for_each_entry(ptr, &chroot_list, list) {
56 if (ptr->dir != saved_dir)
57 continue;
58 ptr->is_deleted = is_delete;
59 error = 0;
60 goto out;
61 }
62 if (is_delete) {
63 error = -ENOENT;
64 goto out;
65 }
66 new_entry = ccs_alloc_element(sizeof(*new_entry));
67 if (!new_entry)
68 goto out;
69 new_entry->dir = saved_dir;
70 list1_add_tail_mb(&new_entry->list, &chroot_list);
71 error = 0;
72 printk(KERN_CONT "%sAllow chroot() to %s\n", ccs_log_level, dir);
73 out:
74 mutex_unlock(&lock);
75 ccs_update_counter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);
76 return error;
77 }
78
79 /**
80 * print_error - Print error message.
81 *
82 * @r: Pointer to "struct ccs_request_info".
83 * @root_name: Requested directory name.
84 *
85 * Returns 0 if @r->mode is not enforcing mode or permitted by the
86 * administrator's decision, negative value otherwise.
87 */
88 static int print_error(struct ccs_request_info *r, const char *root_name)
89 {
90 int error;
91 const bool is_enforce = (r->mode == 3);
92 const char *exename = ccs_get_exe();
93 printk(KERN_WARNING "SAKURA-%s: chroot %s (pid=%d:exe=%s): "
94 "Permission denied.\n", ccs_get_msg(is_enforce),
95 root_name, (pid_t) sys_getpid(), exename);
96 if (is_enforce)
97 error = ccs_check_supervisor(r,
98 "# %s is requesting\nchroot %s\n",
99 exename, root_name);
100 else
101 error = 0;
102 if (exename)
103 ccs_free(exename);
104 if (r->mode == 1 && root_name)
105 update_chroot_acl(root_name, false);
106 return error;
107 }
108
109 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
110 #define PATH_or_NAMEIDATA path
111 #else
112 #define PATH_or_NAMEIDATA nameidata
113 #endif
114 /**
115 * ccs_check_chroot_permission - Check permission for chroot().
116 *
117 * @path: Pointer to "struct path" (for 2.6.27 and later).
118 * Pointer to "struct nameidata" (for 2.6.26 and earlier).
119 *
120 * Returns 0 on success, negative value otherwise.
121 */
122 int ccs_check_chroot_permission(struct PATH_or_NAMEIDATA *path)
123 {
124 struct ccs_request_info r;
125 int error;
126 char *root_name;
127 if (!ccs_can_sleep())
128 return 0;
129 ccs_init_request_info(&r, NULL, CCS_SAKURA_RESTRICT_CHROOT);
130 if (!r.mode)
131 return 0;
132 retry:
133 error = -EPERM;
134 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
135 root_name = ccs_realpath_from_dentry(path->path.dentry, path->path.mnt);
136 #else
137 root_name = ccs_realpath_from_dentry(path->dentry, path->mnt);
138 #endif
139 if (root_name) {
140 struct path_info dir;
141 dir.name = root_name;
142 ccs_fill_path_info(&dir);
143 if (dir.is_dir) {
144 struct chroot_entry *ptr;
145 list1_for_each_entry(ptr, &chroot_list, list) {
146 if (ptr->is_deleted)
147 continue;
148 if (!ccs_path_matches_pattern(&dir, ptr->dir))
149 continue;
150 error = 0;
151 break;
152 }
153 }
154 }
155 if (error)
156 error = print_error(&r, root_name);
157 ccs_free(root_name);
158 if (error == 1)
159 goto retry;
160 return error;
161 }
162
163 /**
164 * ccs_write_chroot_policy - Write "struct chroot_entry" list.
165 *
166 * @data: String to parse.
167 * @is_delete: True if it is a delete request.
168 *
169 * Returns 0 on success, negative value otherwise.
170 */
171 int ccs_write_chroot_policy(char *data, const bool is_delete)
172 {
173 return update_chroot_acl(data, is_delete);
174 }
175
176 /**
177 * ccs_read_chroot_policy - Read "struct chroot_entry" list.
178 *
179 * @head: Pointer to "struct ccs_io_buffer".
180 *
181 * Returns true on success, false otherwise.
182 */
183 bool ccs_read_chroot_policy(struct ccs_io_buffer *head)
184 {
185 struct list1_head *pos;
186 list1_for_each_cookie(pos, head->read_var2, &chroot_list) {
187 struct chroot_entry *ptr;
188 ptr = list1_entry(pos, struct chroot_entry, list);
189 if (ptr->is_deleted)
190 continue;
191 if (!ccs_io_printf(head, KEYWORD_ALLOW_CHROOT "%s\n",
192 ptr->dir->name))
193 goto out;
194 }
195 return true;
196 out:
197 return false;
198 }

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