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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1886 - (show annotations) (download) (as text)
Tue Nov 25 05:41:59 2008 UTC (15 years, 6 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 5079 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.5 2008/11/11
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 /**
25 * update_chroot_acl - Update "struct chroot_entry" list.
26 *
27 * @dir: The name of directory.
28 * @domain: Pointer to "struct domain_info".
29 * @condition: Pointer to "struct condition_list". May be NULL.
30 * @is_delete: True if it is a delete request.
31 *
32 * Returns 0 on success, negative value otherwise.
33 */
34 static int update_chroot_acl(const char *dir, struct domain_info *domain,
35 const struct condition_list *condition,
36 const bool is_delete)
37 {
38 struct acl_info *ptr;
39 struct chroot_entry *acl;
40 const struct path_info *saved_dir;
41 static DEFINE_MUTEX(lock);
42 int error = -ENOMEM;
43 if (!ccs_is_correct_path(dir, 1, 0, 1, __func__))
44 return -EINVAL;
45 saved_dir = ccs_save_name(dir);
46 if (!saved_dir)
47 return -ENOMEM;
48 mutex_lock(&lock);
49 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
50 if (ccs_acl_type1(ptr) != TYPE_CHROOT_ACL)
51 continue;
52 if (ccs_get_condition_part(ptr) != condition)
53 continue;
54 acl = container_of(ptr, struct chroot_entry, head);
55 if (acl->dir != saved_dir)
56 continue;
57 if (is_delete)
58 ptr->type |= ACL_DELETED;
59 else
60 ptr->type &= ~ACL_DELETED;
61 error = 0;
62 goto out;
63 }
64 if (is_delete) {
65 error = -ENOENT;
66 goto out;
67 }
68 acl = ccs_alloc_acl_element(TYPE_CHROOT_ACL, condition);
69 if (!acl)
70 goto out;
71 acl->dir = saved_dir;
72 error = ccs_add_domain_acl(domain, &acl->head);
73 printk(KERN_CONT "%sAllow chroot() to %s\n", ccs_log_level, dir);
74 out:
75 mutex_unlock(&lock);
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, r->domain, ccs_handler_cond(),
106 false);
107 return error;
108 }
109
110 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
111 #define PATH_or_NAMEIDATA path
112 #else
113 #define PATH_or_NAMEIDATA nameidata
114 #endif
115 /**
116 * ccs_check_chroot_permission - Check permission for chroot().
117 *
118 * @path: Pointer to "struct path" (for 2.6.27 and later).
119 * Pointer to "struct nameidata" (for 2.6.26 and earlier).
120 *
121 * Returns 0 on success, negative value otherwise.
122 */
123 int ccs_check_chroot_permission(struct PATH_or_NAMEIDATA *path)
124 {
125 struct ccs_request_info r;
126 int error;
127 char *root_name;
128 if (!ccs_can_sleep())
129 return 0;
130 ccs_init_request_info(&r, NULL, CCS_SAKURA_RESTRICT_CHROOT);
131 if (!r.mode)
132 return 0;
133 retry:
134 error = -EPERM;
135 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
136 root_name = ccs_realpath_from_dentry(path->path.dentry, path->path.mnt);
137 #else
138 root_name = ccs_realpath_from_dentry(path->dentry, path->mnt);
139 #endif
140 if (root_name) {
141 struct path_info dir;
142 dir.name = root_name;
143 ccs_fill_path_info(&dir);
144 if (dir.is_dir) {
145 struct acl_info *ptr;
146 list1_for_each_entry(ptr, &r.domain->acl_info_list,
147 list) {
148 struct chroot_entry *acl;
149 if (ccs_acl_type2(ptr) != TYPE_NO_UMOUNT_ACL)
150 continue;
151 acl = container_of(ptr, struct chroot_entry,
152 head);
153 if (!ccs_path_matches_pattern(&dir, acl->dir))
154 continue;
155 if (!ccs_check_condition(&r, ptr))
156 continue;
157 error = 0;
158 break;
159 }
160 }
161 }
162 if (error)
163 error = print_error(&r, root_name);
164 ccs_free(root_name);
165 if (error == 1)
166 goto retry;
167 return error;
168 }
169
170 /**
171 * ccs_write_chroot_policy - Write "struct chroot_entry" list.
172 *
173 * @data: String to parse.
174 * @domain: Pointer to "struct domain_info".
175 * @condition: Pointer to "struct condition_list". May be NULL.
176 * @is_delete: True if it is a delete request.
177 *
178 * Returns 0 on success, negative value otherwise.
179 */
180 int ccs_write_chroot_policy(char *data, struct domain_info *domain,
181 const struct condition_list *condition,
182 const bool is_delete)
183 {
184 return update_chroot_acl(data, condition, domain, is_delete);
185 }

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