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

Subversion リポジトリの参照

Annotation of /trunk/1.6.x/ccs-patch/fs/tomoyo_signal.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1264 - (hide annotations) (download) (as text)
Sat Jun 7 07:16:21 2008 UTC (15 years, 11 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 6725 byte(s)


1 kumaneko 111 /*
2     * fs/tomoyo_signal.c
3     *
4     * Implementation of the Domain-Based Mandatory Access Control.
5     *
6 kumaneko 851 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 kumaneko 111 *
8 kumaneko 1264 * Version: 1.6.2-pre 2008/06/07
9 kumaneko 111 *
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/tomoyo.h>
17     #include <linux/realpath.h>
18 kumaneko 964 #include <linux/version.h>
19 kumaneko 1052
20     /* To support PID namespace. */
21     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
22 kumaneko 964 #define find_task_by_pid find_task_by_vpid
23     #endif
24 kumaneko 111
25 kumaneko 1052 /**
26     * audit_signal_log - Audit signal log.
27     *
28     * @signal: Signal number.
29     * @dest_domain: Destination domainname.
30     * @is_granted: True if this is a granted log.
31 kumaneko 1064 * @profile: Profile number used.
32     * @mode: Access control mode used.
33 kumaneko 1052 *
34     * Returns 0 on success, negative value otherwise.
35     */
36     static int audit_signal_log(const int signal,
37     const struct path_info *dest_domain,
38     const bool is_granted, const u8 profile,
39     const u8 mode)
40 kumaneko 111 {
41     char *buf;
42     int len;
43 kumaneko 1064 int len2;
44 kumaneko 1052 if (ccs_can_save_audit_log(is_granted) < 0)
45     return -ENOMEM;
46 kumaneko 1064 len = dest_domain->total_len + 64;
47 kumaneko 1052 buf = ccs_init_audit_log(&len, profile, mode, NULL);
48     if (!buf)
49     return -ENOMEM;
50 kumaneko 1064 len2 = strlen(buf);
51     snprintf(buf + len2, len - len2 - 1, KEYWORD_ALLOW_SIGNAL "%d %s\n",
52     signal, dest_domain->name);
53 kumaneko 1052 return ccs_write_audit_log(buf, is_granted);
54 kumaneko 111 }
55    
56 kumaneko 1052 /**
57     * update_signal_acl - Update "struct signal_acl_record" list.
58     *
59     * @sig: Signal number.
60     * @dest_pattern: Destination domainname.
61     * @domain: Pointer to "struct domain_info".
62     * @condition: Pointer to "struct condition_list". May be NULL.
63     * @is_delete: True if it is a delete request.
64     *
65     * Returns 0 on success, negative value otherwise.
66     */
67     static int update_signal_acl(const int sig, const char *dest_pattern,
68     struct domain_info *domain,
69     const struct condition_list *condition,
70     const bool is_delete)
71 kumaneko 111 {
72     struct acl_info *ptr;
73 kumaneko 708 struct signal_acl_record *acl;
74 kumaneko 111 const struct path_info *saved_dest_pattern;
75     const u16 hash = sig;
76     int error = -ENOMEM;
77 kumaneko 1052 if (!domain)
78     return -EINVAL;
79     if (!dest_pattern || !ccs_is_correct_domain(dest_pattern, __func__))
80     return -EINVAL;
81     saved_dest_pattern = ccs_save_name(dest_pattern);
82     if (!saved_dest_pattern)
83     return -ENOMEM;
84 kumaneko 652 mutex_lock(&domain_acl_lock);
85 kumaneko 1052 if (is_delete)
86     goto delete;
87     list1_for_each_entry(ptr, &domain->acl_info_list, list) {
88 kumaneko 1064 if (ccs_acl_type1(ptr) != TYPE_SIGNAL_ACL)
89 kumaneko 1052 continue;
90     if (ccs_get_condition_part(ptr) != condition)
91     continue;
92     acl = container_of(ptr, struct signal_acl_record, head);
93     if (acl->sig != hash ||
94     ccs_pathcmp(acl->domainname, saved_dest_pattern))
95     continue;
96     error = ccs_add_domain_acl(NULL, ptr);
97     goto out;
98 kumaneko 111 }
99 kumaneko 1052 /* Not found. Append it to the tail. */
100     acl = ccs_alloc_acl_element(TYPE_SIGNAL_ACL, condition);
101     if (!acl)
102     goto out;
103     acl->sig = hash;
104     acl->domainname = saved_dest_pattern;
105     error = ccs_add_domain_acl(domain, &acl->head);
106     goto out;
107     delete:
108     error = -ENOENT;
109     list1_for_each_entry(ptr, &domain->acl_info_list, list) {
110 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_SIGNAL_ACL)
111 kumaneko 1052 continue;
112     if (ccs_get_condition_part(ptr) != condition)
113     continue;
114     acl = container_of(ptr, struct signal_acl_record, head);
115     if (acl->sig != hash ||
116     ccs_pathcmp(acl->domainname, saved_dest_pattern))
117     continue;
118     error = ccs_del_domain_acl(ptr);
119     break;
120     }
121     out:
122 kumaneko 652 mutex_unlock(&domain_acl_lock);
123 kumaneko 111 return error;
124     }
125    
126 kumaneko 1052 /**
127     * ccs_check_signal_acl - Check permission for signal.
128     *
129     * @sig: Signal number.
130     * @pid: Target's PID.
131     *
132     * Returns 0 on success, negative value otherwise.
133     */
134     int ccs_check_signal_acl(const int sig, const int pid)
135 kumaneko 111 {
136     struct domain_info *domain = current->domain_info;
137     struct domain_info *dest = NULL;
138     const char *dest_pattern;
139     struct acl_info *ptr;
140     const u16 hash = sig;
141 kumaneko 815 const u8 profile = current->domain_info->profile;
142 kumaneko 1052 const u8 mode = ccs_check_flags(CCS_TOMOYO_MAC_FOR_SIGNAL);
143 kumaneko 815 const bool is_enforce = (mode == 3);
144 kumaneko 1016 bool found = false;
145 kumaneko 1052 if (!mode)
146     return 0;
147     if (!sig)
148     return 0; /* No check for NULL signal. */
149 kumaneko 111 if (current->pid == pid) {
150 kumaneko 1064 audit_signal_log(sig, domain->domainname, true, profile, mode);
151     return 0; /* No check for self process. */
152 kumaneko 111 }
153     { /* Simplified checking. */
154     struct task_struct *p = NULL;
155 kumaneko 1064 /***** CRITICAL SECTION START *****/
156 kumaneko 111 read_lock(&tasklist_lock);
157 kumaneko 1052 if (pid > 0)
158     p = find_task_by_pid((pid_t) pid);
159     else if (pid == 0)
160     p = current;
161     else if (pid == -1)
162     dest = &KERNEL_DOMAIN;
163     else
164     p = find_task_by_pid((pid_t) -pid);
165     if (p)
166     dest = p->domain_info;
167 kumaneko 111 read_unlock(&tasklist_lock);
168 kumaneko 1064 /***** CRITICAL SECTION END *****/
169 kumaneko 1052 if (!dest)
170     return 0; /* I can't find destinatioin. */
171 kumaneko 111 }
172     if (domain == dest) {
173 kumaneko 1064 audit_signal_log(sig, dest->domainname, true, profile, mode);
174     return 0; /* No check for self domain. */
175 kumaneko 111 }
176     dest_pattern = dest->domainname->name;
177 kumaneko 722 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
178 kumaneko 708 struct signal_acl_record *acl;
179 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_SIGNAL_ACL)
180 kumaneko 1052 continue;
181 kumaneko 912 acl = container_of(ptr, struct signal_acl_record, head);
182 kumaneko 1052 if (acl->sig == hash && ccs_check_condition(ptr, NULL)) {
183 kumaneko 708 const int len = acl->domainname->total_len;
184 kumaneko 1052 if (strncmp(acl->domainname->name, dest_pattern, len))
185     continue;
186 kumaneko 1064 switch (dest_pattern[len]) {
187     case ' ':
188     case '\0':
189     break;
190     default:
191 kumaneko 1052 continue;
192 kumaneko 1064 }
193 kumaneko 1052 ccs_update_condition(ptr);
194 kumaneko 1016 found = true;
195 kumaneko 856 break;
196 kumaneko 111 }
197     }
198 kumaneko 1052 audit_signal_log(sig, dest->domainname, found, profile, mode);
199     if (found)
200     return 0;
201     if (ccs_verbose_mode())
202     printk(KERN_WARNING "TOMOYO-%s: Signal %d "
203     "to %s denied for %s\n", ccs_get_msg(is_enforce), sig,
204     ccs_get_last_name(dest), ccs_get_last_name(domain));
205     if (is_enforce)
206 kumaneko 1260 return ccs_check_supervisor(NULL, KEYWORD_ALLOW_SIGNAL
207     "%d %s\n", sig, dest_pattern);
208 kumaneko 1064 if (mode == 1 && ccs_check_domain_quota(domain))
209     update_signal_acl(sig, dest_pattern, domain, NULL, false);
210 kumaneko 111 return 0;
211     }
212    
213 kumaneko 1052 /**
214     * ccs_write_signal_policy - Write "struct signal_acl_record" list.
215     *
216     * @data: String to parse.
217     * @domain: Pointer to "struct domain_info".
218     * @condition: Pointer to "struct condition_list". May be NULL.
219     * @is_delete: True if it is a delete request.
220     *
221     * Returns 0 on success, negative value otherwise.
222     */
223     int ccs_write_signal_policy(char *data, struct domain_info *domain,
224     const struct condition_list *condition,
225     const bool is_delete)
226 kumaneko 111 {
227     int sig;
228     char *domainname = strchr(data, ' ');
229 kumaneko 1052 if (sscanf(data, "%d", &sig) == 1 && domainname &&
230     ccs_is_domain_def(domainname + 1))
231     return update_signal_acl(sig, domainname + 1, domain,
232     condition, is_delete);
233 kumaneko 111 return -EINVAL;
234     }

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