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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 894 - (hide annotations) (download) (as text)
Tue Jan 15 03:00:17 2008 UTC (16 years, 4 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 6352 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 860 * Version: 1.5.3-pre 2008/01/04
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     /***** 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 kumaneko 652 extern struct mutex domain_acl_lock;
26 kumaneko 111
27     /************************* AUDIT FUNCTIONS *************************/
28    
29 kumaneko 851 static int AuditSignalLog(const int signal, const struct path_info *dest_domain, const bool is_granted, const u8 profile, const u8 mode)
30 kumaneko 111 {
31     char *buf;
32     int len;
33     if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;
34     len = dest_domain->total_len;
35 kumaneko 815 if ((buf = InitAuditLog(&len, profile, mode)) == NULL) return -ENOMEM;
36 kumaneko 111 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 kumaneko 621 static int AddSignalEntry(const int sig, const char *dest_pattern, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
43 kumaneko 111 {
44     struct acl_info *ptr;
45 kumaneko 708 struct signal_acl_record *acl;
46 kumaneko 856 struct signal_acl_record_with_condition *p;
47 kumaneko 111 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 kumaneko 652 mutex_lock(&domain_acl_lock);
54 kumaneko 514 if (!is_delete) {
55 kumaneko 722 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
56 kumaneko 856 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 kumaneko 111 }
69 kumaneko 856 if (acl->sig != hash || pathcmp(acl->domainname, saved_dest_pattern)) continue;
70 kumaneko 860 acl->is_deleted = 0;
71 kumaneko 856 /* Found. Nothing to do. */
72     error = 0;
73     goto out;
74 kumaneko 111 }
75 kumaneko 708 /* Not found. Append it to the tail. */
76 kumaneko 856 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 kumaneko 708 acl->sig = hash;
86     acl->domainname = saved_dest_pattern;
87     error = AddDomainACL(domain, &acl->head);
88 kumaneko 111 } else {
89     error = -ENOENT;
90 kumaneko 722 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
91 kumaneko 856 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 kumaneko 860 if (acl->is_deleted || acl->sig != hash || pathcmp(acl->domainname, saved_dest_pattern)) continue;
105     acl->is_deleted = 1;
106     error = DelDomainACL();
107 kumaneko 111 break;
108     }
109     }
110 kumaneko 708 out: ;
111 kumaneko 652 mutex_unlock(&domain_acl_lock);
112 kumaneko 111 return error;
113     }
114    
115     int CheckSignalACL(const int sig, const int pid)
116     {
117     struct domain_info *domain = current->domain_info;
118     struct domain_info *dest = NULL;
119     const char *dest_pattern;
120     struct acl_info *ptr;
121     const u16 hash = sig;
122 kumaneko 815 const u8 profile = current->domain_info->profile;
123 kumaneko 851 const u8 mode = CheckCCSFlags(CCS_TOMOYO_MAC_FOR_SIGNAL);
124 kumaneko 815 const bool is_enforce = (mode == 3);
125 kumaneko 708 bool found = 0;
126 kumaneko 815 if (!mode) return 0;
127 kumaneko 111 if (!sig) return 0; /* No check for NULL signal. */
128     if (current->pid == pid) {
129 kumaneko 815 AuditSignalLog(sig, domain->domainname, 1, profile, mode);
130 kumaneko 111 return 0; /* No check for self. */
131     }
132     { /* Simplified checking. */
133     struct task_struct *p = NULL;
134     read_lock(&tasklist_lock);
135     if (pid > 0) p = find_task_by_pid((pid_t) pid);
136     else if (pid == 0) p = current;
137     else if (pid == -1) dest = &KERNEL_DOMAIN;
138     else p = find_task_by_pid((pid_t) -pid);
139     if (p) dest = p->domain_info;
140     read_unlock(&tasklist_lock);
141     if (!dest) return 0; /* I can't find destinatioin. */
142     }
143     if (domain == dest) {
144 kumaneko 815 AuditSignalLog(sig, dest->domainname, 1, profile, mode);
145 kumaneko 111 return 0;
146     }
147     dest_pattern = dest->domainname->name;
148 kumaneko 722 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
149 kumaneko 708 struct signal_acl_record *acl;
150 kumaneko 856 struct signal_acl_record_with_condition *p;
151     const struct condition_list *cond;
152     switch (ptr->type) {
153     default:
154     continue;
155     case TYPE_SIGNAL_ACL:
156     acl = container_of(ptr, struct signal_acl_record, head);
157     cond = NULL;
158     break;
159     case TYPE_SIGNAL_ACL_WITH_CONDITION:
160     p = container_of(ptr, struct signal_acl_record_with_condition, record.head);
161     acl = &p->record;
162     cond = p->condition;
163     break;
164     }
165 kumaneko 860 if (!acl->is_deleted && acl->sig == hash && CheckCondition(cond, NULL)) {
166 kumaneko 708 const int len = acl->domainname->total_len;
167 kumaneko 856 if (strncmp(acl->domainname->name, dest_pattern, len)) continue;
168     if (dest_pattern[len] != ' ' && dest_pattern[len] != '\0') continue;
169     found = 1;
170     break;
171 kumaneko 111 }
172     }
173 kumaneko 815 AuditSignalLog(sig, dest->domainname, found, profile, mode);
174 kumaneko 708 if (found) return 0;
175 kumaneko 111 if (TomoyoVerboseMode()) {
176     printk("TOMOYO-%s: Signal %d to %s denied for %s\n", GetMSG(is_enforce), sig, GetLastName(dest), GetLastName(domain));
177     }
178     if (is_enforce) return CheckSupervisor("%s\n" KEYWORD_ALLOW_SIGNAL "%d %s\n", domain->domainname->name, sig, dest_pattern);
179 kumaneko 856 else if (mode == 1 && CheckDomainQuota(domain)) AddSignalEntry(sig, dest_pattern, domain, NULL, 0);
180 kumaneko 111 return 0;
181     }
182    
183 kumaneko 621 int AddSignalPolicy(char *data, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
184 kumaneko 111 {
185     int sig;
186     char *domainname = strchr(data, ' ');
187     if (sscanf(data, "%d", &sig) == 1 && domainname && IsDomainDef(domainname + 1)) {
188 kumaneko 514 return AddSignalEntry(sig, domainname + 1, domain, condition, is_delete);
189 kumaneko 111 }
190     return -EINVAL;
191     }
192    
193     /***** TOMOYO Linux end. *****/

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