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

Subversion リポジトリの参照

Contents of /trunk/1.5.x/ccs-patch/fs/tomoyo_signal.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 856 - (show annotations) (download) (as text)
Thu Jan 3 07:16:18 2008 UTC (16 years, 4 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 6331 byte(s)
Change internal structure.
1 /*
2 * fs/tomoyo_signal.c
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 *
8 * Version: 1.5.3-pre 2008/01/03
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 /***** TOMOYO Linux start. *****/
15
16 #include <linux/ccs_common.h>
17 #include <linux/tomoyo.h>
18 #include <linux/realpath.h>
19
20 /************************* VARIABLES *************************/
21
22 /* The initial domain. */
23 extern struct domain_info KERNEL_DOMAIN;
24
25 extern struct mutex domain_acl_lock;
26
27 /************************* AUDIT FUNCTIONS *************************/
28
29 static int AuditSignalLog(const int signal, const struct path_info *dest_domain, const bool is_granted, const u8 profile, const u8 mode)
30 {
31 char *buf;
32 int len;
33 if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;
34 len = dest_domain->total_len;
35 if ((buf = InitAuditLog(&len, profile, mode)) == NULL) return -ENOMEM;
36 snprintf(buf + strlen(buf), len - strlen(buf) - 1, KEYWORD_ALLOW_SIGNAL "%d %s\n", signal, dest_domain->name);
37 return WriteAuditLog(buf, is_granted);
38 }
39
40 /************************* SIGNAL ACL HANDLER *************************/
41
42 static int AddSignalEntry(const int sig, const char *dest_pattern, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
43 {
44 struct acl_info *ptr;
45 struct signal_acl_record *acl;
46 struct signal_acl_record_with_condition *p;
47 const struct path_info *saved_dest_pattern;
48 const u16 hash = sig;
49 int error = -ENOMEM;
50 if (!domain) return -EINVAL;
51 if (!dest_pattern || !IsCorrectDomain(dest_pattern, __FUNCTION__)) return -EINVAL;
52 if ((saved_dest_pattern = SaveName(dest_pattern)) == NULL) return -ENOMEM;
53 mutex_lock(&domain_acl_lock);
54 if (!is_delete) {
55 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
56 switch (ptr->type) {
57 case TYPE_SIGNAL_ACL:
58 if (condition) continue;
59 acl = container_of(ptr, struct signal_acl_record, head);
60 break;
61 case TYPE_SIGNAL_ACL_WITH_CONDITION:
62 p = container_of(ptr, struct signal_acl_record_with_condition, record.head);
63 if (p->condition != condition) continue;
64 acl = &p->record;
65 break;
66 default:
67 continue;
68 }
69 if (acl->sig != hash || pathcmp(acl->domainname, saved_dest_pattern)) continue;
70 ptr->is_deleted = 0;
71 /* Found. Nothing to do. */
72 error = 0;
73 goto out;
74 }
75 /* Not found. Append it to the tail. */
76 if (condition) {
77 if ((p = alloc_element(sizeof(*p))) == NULL) goto out;
78 acl = &p->record;
79 p->condition = condition;
80 acl->head.type = TYPE_SIGNAL_ACL_WITH_CONDITION;
81 } else {
82 if ((acl = alloc_element(sizeof(*acl))) == NULL) goto out;
83 acl->head.type = TYPE_SIGNAL_ACL;
84 }
85 acl->sig = hash;
86 acl->domainname = saved_dest_pattern;
87 error = AddDomainACL(domain, &acl->head);
88 } else {
89 error = -ENOENT;
90 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
91 switch (ptr->type) {
92 case TYPE_SIGNAL_ACL:
93 if (condition) continue;
94 acl = container_of(ptr, struct signal_acl_record, head);
95 break;
96 case TYPE_SIGNAL_ACL_WITH_CONDITION:
97 p = container_of(ptr, struct signal_acl_record_with_condition, record.head);
98 if (p->condition != condition) continue;
99 acl = &p->record;
100 break;
101 default:
102 continue;
103 }
104 if (ptr->is_deleted || acl->sig != hash || pathcmp(acl->domainname, saved_dest_pattern)) continue;
105 error = DelDomainACL(ptr);
106 break;
107 }
108 }
109 out: ;
110 mutex_unlock(&domain_acl_lock);
111 return error;
112 }
113
114 int CheckSignalACL(const int sig, const int pid)
115 {
116 struct domain_info *domain = current->domain_info;
117 struct domain_info *dest = NULL;
118 const char *dest_pattern;
119 struct acl_info *ptr;
120 const u16 hash = sig;
121 const u8 profile = current->domain_info->profile;
122 const u8 mode = CheckCCSFlags(CCS_TOMOYO_MAC_FOR_SIGNAL);
123 const bool is_enforce = (mode == 3);
124 bool found = 0;
125 if (!mode) return 0;
126 if (!sig) return 0; /* No check for NULL signal. */
127 if (current->pid == pid) {
128 AuditSignalLog(sig, domain->domainname, 1, profile, mode);
129 return 0; /* No check for self. */
130 }
131 { /* Simplified checking. */
132 struct task_struct *p = NULL;
133 read_lock(&tasklist_lock);
134 if (pid > 0) p = find_task_by_pid((pid_t) pid);
135 else if (pid == 0) p = current;
136 else if (pid == -1) dest = &KERNEL_DOMAIN;
137 else p = find_task_by_pid((pid_t) -pid);
138 if (p) dest = p->domain_info;
139 read_unlock(&tasklist_lock);
140 if (!dest) return 0; /* I can't find destinatioin. */
141 }
142 if (domain == dest) {
143 AuditSignalLog(sig, dest->domainname, 1, profile, mode);
144 return 0;
145 }
146 dest_pattern = dest->domainname->name;
147 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
148 struct signal_acl_record *acl;
149 struct signal_acl_record_with_condition *p;
150 const struct condition_list *cond;
151 switch (ptr->type) {
152 default:
153 continue;
154 case TYPE_SIGNAL_ACL:
155 acl = container_of(ptr, struct signal_acl_record, head);
156 cond = NULL;
157 break;
158 case TYPE_SIGNAL_ACL_WITH_CONDITION:
159 p = container_of(ptr, struct signal_acl_record_with_condition, record.head);
160 acl = &p->record;
161 cond = p->condition;
162 break;
163 }
164 if (!ptr->is_deleted && acl->sig == hash && CheckCondition(cond, NULL)) {
165 const int len = acl->domainname->total_len;
166 if (strncmp(acl->domainname->name, dest_pattern, len)) continue;
167 if (dest_pattern[len] != ' ' && dest_pattern[len] != '\0') continue;
168 found = 1;
169 break;
170 }
171 }
172 AuditSignalLog(sig, dest->domainname, found, profile, mode);
173 if (found) return 0;
174 if (TomoyoVerboseMode()) {
175 printk("TOMOYO-%s: Signal %d to %s denied for %s\n", GetMSG(is_enforce), sig, GetLastName(dest), GetLastName(domain));
176 }
177 if (is_enforce) return CheckSupervisor("%s\n" KEYWORD_ALLOW_SIGNAL "%d %s\n", domain->domainname->name, sig, dest_pattern);
178 else if (mode == 1 && CheckDomainQuota(domain)) AddSignalEntry(sig, dest_pattern, domain, NULL, 0);
179 return 0;
180 }
181
182 int AddSignalPolicy(char *data, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
183 {
184 int sig;
185 char *domainname = strchr(data, ' ');
186 if (sscanf(data, "%d", &sig) == 1 && domainname && IsDomainDef(domainname + 1)) {
187 return AddSignalEntry(sig, domainname + 1, domain, condition, is_delete);
188 }
189 return -EINVAL;
190 }
191
192 /***** TOMOYO Linux end. *****/

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