Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Contents of /trunk/1.7.x/ccs-patch/security/ccsecurity/chroot.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2975 - (show annotations) (download) (as text)
Tue Sep 1 05:34:46 2009 UTC (14 years, 8 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 4554 byte(s)


1 /*
2 * security/ccsecurity/chroot.c
3 *
4 * Copyright (C) 2005-2009 NTT DATA CORPORATION
5 *
6 * Version: 1.7.0-rc 2009/09/01
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
22 /**
23 * ccs_audit_chroot_log - Audit chroot log.
24 *
25 * @r: Pointer to "struct ccs_request_info".
26 * @root: New root directory.
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_chroot_log(struct ccs_request_info *r,
32 const char *root, const bool is_granted)
33 {
34 if (!is_granted)
35 ccs_warn_log(r, "chroot %s", root);
36 return ccs_write_audit_log(is_granted, r, CCS_KEYWORD_ALLOW_CHROOT
37 "%s\n", root);
38 }
39
40 /**
41 * ccs_chroot_acl - Check permission for chroot().
42 *
43 * @path: Pointer to "struct path".
44 *
45 * Returns 0 on success, negative value otherwise.
46 *
47 * Caller holds ccs_read_lock().
48 */
49 static int ccs_chroot_acl(struct path *path)
50 {
51 struct ccs_request_info r;
52 int error;
53 struct ccs_path_info dir;
54 char *root_name;
55 struct ccs_obj_info obj = {
56 .path1 = *path
57 };
58 if (ccs_init_request_info(&r, NULL, CCS_MAC_FILE_CHROOT)
59 == CCS_CONFIG_DISABLED)
60 return 0;
61 r.obj = &obj;
62 error = -ENOMEM;
63 root_name = ccs_realpath_from_path(path);
64 if (!root_name)
65 goto out;
66 dir.name = root_name;
67 ccs_fill_path_info(&dir);
68 if (!dir.is_dir)
69 goto out;
70 do {
71 struct ccs_acl_info *ptr;
72 error = -EPERM;
73 list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {
74 struct ccs_chroot_acl *acl;
75 if (ptr->is_deleted ||
76 ptr->type != CCS_TYPE_CHROOT_ACL)
77 continue;
78 acl = container_of(ptr, struct ccs_chroot_acl,
79 head);
80 if (!ccs_compare_name_union(&dir, &acl->dir) ||
81 !ccs_condition(&r, ptr))
82 continue;
83 r.cond = ptr->cond;
84 error = 0;
85 break;
86 }
87 ccs_audit_chroot_log(&r, root_name, !error);
88 if (!error)
89 break;
90 error = ccs_supervisor(&r, CCS_KEYWORD_ALLOW_CHROOT
91 "%s\n", ccs_file_pattern(&dir));
92 } while (error == 1);
93 out:
94 kfree(root_name);
95 if (r.mode != CCS_CONFIG_ENFORCING)
96 error = 0;
97 return error;
98 }
99
100 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
101 #define PATH_or_NAMEIDATA path
102 #else
103 #define PATH_or_NAMEIDATA nameidata
104 #endif
105
106 /**
107 * ccs_chroot_permission - Check permission for chroot().
108 *
109 * @path: Pointer to "struct path" (for 2.6.27 and later).
110 * Pointer to "struct nameidata" (for 2.6.26 and earlier).
111 *
112 * Returns 0 on success, negative value otherwise.
113 */
114 int ccs_chroot_permission(struct PATH_or_NAMEIDATA *path)
115 {
116 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 25) || LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 26)
117 struct path tmp_path = { path->path.mnt, path->path.dentry };
118 #else
119 struct path tmp_path = { path->mnt, path->dentry };
120 #endif
121 const int idx = ccs_read_lock();
122 const int error = ccs_chroot_acl(&tmp_path);
123 ccs_read_unlock(idx);
124 return error;
125 }
126
127 /**
128 * ccs_write_chroot_policy - Write "struct ccs_chroot_acl" list.
129 *
130 * @data: String to parse.
131 * @domain: Pointer to "struct ccs_domain_info".
132 * @condition: Pointer to "struct ccs_condition". May be NULL.
133 * @is_delete: True if it is a delete request.
134 *
135 * Returns 0 on success, negative value otherwise.
136 */
137 int ccs_write_chroot_policy(char *data, struct ccs_domain_info *domain,
138 struct ccs_condition *condition,
139 const bool is_delete)
140 {
141 struct ccs_chroot_acl *entry = NULL;
142 struct ccs_acl_info *ptr;
143 struct ccs_chroot_acl e = {
144 .head.type = CCS_TYPE_CHROOT_ACL,
145 .head.cond = condition
146 };
147 int error = is_delete ? -ENOENT : -ENOMEM;
148 if (data[0] != '@' && !ccs_is_correct_path(data, 1, 0, 1))
149 return -EINVAL;
150 if (!ccs_parse_name_union(data, &e.dir))
151 return error;
152 if (!is_delete)
153 entry = kmalloc(sizeof(e), GFP_KERNEL);
154 mutex_lock(&ccs_policy_lock);
155 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
156 struct ccs_chroot_acl *acl =
157 container_of(ptr, struct ccs_chroot_acl, head);
158 if (ptr->type != CCS_TYPE_CHROOT_ACL || ptr->cond != condition
159 || memcmp(&acl->dir, &e.dir, sizeof(e.dir)))
160 continue;
161 ptr->is_deleted = is_delete;
162 error = 0;
163 break;
164 }
165 if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) {
166 ccs_add_domain_acl(domain, &entry->head);
167 entry = NULL;
168 error = 0;
169 }
170 mutex_unlock(&ccs_policy_lock);
171 ccs_put_name_union(&e.dir);
172 kfree(entry);
173 return error;
174 }

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