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

Subversion リポジトリの参照

Contents of /branches/ccs-patch/fs/ccsecurity/chroot.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2854 - (show annotations) (download) (as text)
Wed Aug 5 11:57:20 2009 UTC (14 years, 10 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 5528 byte(s)


1 /*
2 * fs/ccsecurity/chroot.c
3 *
4 * Copyright (C) 2005-2009 NTT DATA CORPORATION
5 *
6 * Version: 1.7.0-pre 2009/07/03
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/version.h>
14 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
15 #include <linux/dcache.h>
16 #include <linux/namei.h>
17 #else
18 #include <linux/fs.h>
19 #endif
20 #include "internal.h"
21 #include <linux/ccsecurity.h>
22
23 /**
24 * ccs_audit_chroot_log - Audit chroot log.
25 *
26 * @r: Pointer to "struct ccs_request_info".
27 * @root: New root directory.
28 * @is_granted: True if this is a granted log.
29 *
30 * Returns 0 on success, negative value otherwise.
31 */
32 static int ccs_audit_chroot_log(struct ccs_request_info *r,
33 const char *root, const bool is_granted)
34 {
35 if (!is_granted && ccs_verbose_mode(r->domain))
36 printk(KERN_WARNING "SAKURA-%s: chroot %s denied for %s\n",
37 ccs_get_msg(r->mode == 3), root,
38 ccs_get_last_name(r->domain));
39 return ccs_write_audit_log(is_granted, r, KEYWORD_ALLOW_CHROOT
40 "%s\n", root);
41 }
42
43 /**
44 * ccs_update_chroot_acl - Update "struct ccs_chroot_acl_record" list.
45 *
46 * @dir: The name of directory.
47 * @is_delete: True if it is a delete request.
48 *
49 * Returns 0 on success, negative value otherwise.
50 */
51 static int ccs_update_chroot_acl(const char *dir,
52 struct ccs_domain_info *domain,
53 struct ccs_condition *condition,
54 const bool is_delete)
55 {
56 struct ccs_chroot_acl_record *entry = NULL;
57 struct ccs_acl_info *ptr;
58 const struct ccs_path_info *saved_dir;
59 int error = is_delete ? -ENOENT : -ENOMEM;
60 if (!ccs_is_correct_path(dir, 1, 0, 1))
61 return -EINVAL;
62 saved_dir = ccs_get_name(dir);
63 if (!saved_dir)
64 return -ENOMEM;
65 if (!is_delete)
66 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
67 mutex_lock(&ccs_policy_lock);
68 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
69 struct ccs_chroot_acl_record *acl;
70 if (ccs_acl_type1(ptr) != TYPE_CHROOT_ACL)
71 continue;
72 if (ptr->cond != condition)
73 continue;
74 acl = container_of(ptr, struct ccs_chroot_acl_record, head);
75 if (acl->dir != saved_dir)
76 continue;
77 if (is_delete)
78 error = ccs_del_domain_acl(ptr);
79 else
80 error = ccs_add_domain_acl(NULL, ptr);
81 break;
82 }
83 if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
84 entry->head.type = TYPE_CHROOT_ACL;
85 entry->head.cond = condition;
86 entry->dir = saved_dir;
87 saved_dir = NULL;
88 error = ccs_add_domain_acl(domain, &entry->head);
89 entry = NULL;
90 }
91 mutex_unlock(&ccs_policy_lock);
92 ccs_put_name(saved_dir);
93 kfree(entry);
94 return error;
95 }
96
97 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
98 #define PATH_or_NAMEIDATA path
99 #else
100 #define PATH_or_NAMEIDATA nameidata
101 #endif
102 /**
103 * ccs_check_chroot_permission2 - Check permission for chroot().
104 *
105 * @path: Pointer to "struct path" (for 2.6.27 and later).
106 * Pointer to "struct nameidata" (for 2.6.26 and earlier).
107 *
108 * Returns 0 on success, negative value otherwise.
109 *
110 * Caller holds ccs_read_lock().
111 */
112 static int ccs_check_chroot_permission2(struct PATH_or_NAMEIDATA *path)
113 {
114 struct ccs_request_info r;
115 int error;
116 struct ccs_path_info dir;
117 char *root_name;
118 bool is_enforce;
119 ccs_check_read_lock();
120 if (!ccs_can_sleep())
121 return 0;
122 ccs_init_request_info(&r, NULL, CCS_MAC_FOR_NAMESPACE);
123 is_enforce = (r.mode == 3);
124 if (!r.mode)
125 return 0;
126 retry:
127 error = -EPERM;
128 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
129 root_name = ccs_realpath_from_dentry(path->path.dentry, path->path.mnt);
130 #else
131 root_name = ccs_realpath_from_dentry(path->dentry, path->mnt);
132 #endif
133 if (!root_name)
134 goto out;
135 dir.name = root_name;
136 ccs_fill_path_info(&dir);
137 if (dir.is_dir) {
138 struct ccs_acl_info *ptr;
139 list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {
140 struct ccs_chroot_acl_record *acl;
141 if (ccs_acl_type2(ptr) != TYPE_CHROOT_ACL)
142 continue;
143 acl = container_of(ptr, struct ccs_chroot_acl_record,
144 head);
145 if (!ccs_path_matches_pattern(&dir, acl->dir) ||
146 !ccs_check_condition(&r, ptr))
147 continue;
148 r.cond = ptr->cond;
149 error = 0;
150 break;
151 }
152 }
153 ccs_audit_chroot_log(&r, root_name, !error);
154 if (!error)
155 goto out;
156 if (is_enforce)
157 error = ccs_check_supervisor(&r, KEYWORD_ALLOW_CHROOT"%s\n",
158 root_name);
159 else if (ccs_domain_quota_ok(&r))
160 ccs_update_chroot_acl(root_name, r.domain, NULL, false);
161 out:
162 kfree(root_name);
163 if (error == 1)
164 goto retry;
165 if (!is_enforce)
166 error = 0;
167 return error;
168 }
169
170 /**
171 * ccs_check_chroot_permission - Check permission for chroot().
172 *
173 * @path: Pointer to "struct path" (for 2.6.27 and later).
174 * Pointer to "struct nameidata" (for 2.6.26 and earlier).
175 *
176 * Returns 0 on success, negative value otherwise.
177 */
178 int ccs_check_chroot_permission(struct PATH_or_NAMEIDATA *path)
179 {
180 const int idx = ccs_read_lock();
181 const int error = ccs_check_chroot_permission2(path);
182 ccs_read_unlock(idx);
183 return error;
184 }
185
186 /**
187 * ccs_write_chroot_policy - Write "struct ccs_chroot_acl_record" list.
188 *
189 * @data: String to parse.
190 * @domain: Pointer to "struct ccs_domain_info".
191 * @condition: Pointer to "struct ccs_condition". May be NULL.
192 * @is_delete: True if it is a delete request.
193 *
194 * Returns 0 on success, negative value otherwise.
195 */
196 int ccs_write_chroot_policy(char *data, struct ccs_domain_info *domain,
197 struct ccs_condition *condition,
198 const bool is_delete)
199 {
200 return ccs_update_chroot_acl(data, domain, condition, is_delete);
201 }

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