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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/ccs-patch/fs/tomoyo_signal.c revision 150 by kumaneko, Sat Mar 24 04:57:21 2007 UTC trunk/1.6.x/ccs-patch/fs/tomoyo_signal.c revision 1032 by kumaneko, Tue Mar 11 08:25:41 2008 UTC
# Line 3  Line 3 
3   *   *
4   * Implementation of the Domain-Based Mandatory Access Control.   * Implementation of the Domain-Based Mandatory Access Control.
5   *   *
6   * Copyright (C) 2005-2007  NTT DATA CORPORATION   * Copyright (C) 2005-2008  NTT DATA CORPORATION
7   *   *
8   * Version: 1.4   2007/04/01   * Version: 1.6.0-pre   2008/03/04
9   *   *
10   * This file is applicable to both 2.4.30 and 2.6.11 and later.   * This file is applicable to both 2.4.30 and 2.6.11 and later.
11   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
# Line 16  Line 16 
16  #include <linux/ccs_common.h>  #include <linux/ccs_common.h>
17  #include <linux/tomoyo.h>  #include <linux/tomoyo.h>
18  #include <linux/realpath.h>  #include <linux/realpath.h>
19    #include <linux/version.h>
20  /*************************  VARIABLES  *************************/  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
21    #define find_task_by_pid find_task_by_vpid
22  /* The initial domain. */  #endif
 extern struct domain_info KERNEL_DOMAIN;  
   
 extern struct semaphore domain_acl_lock;  
23    
24  /*************************  AUDIT FUNCTIONS  *************************/  /*************************  AUDIT FUNCTIONS  *************************/
25    
26  #ifdef CONFIG_TOMOYO_AUDIT  static int AuditSignalLog(const int signal, const struct path_info *dest_domain, const bool is_granted, const u8 profile, const u8 mode)
 static int AuditSignalLog(const int signal, const struct path_info *dest_domain, const int is_granted)  
27  {  {
28          char *buf;          char *buf;
29          int len;          int len;
30          if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;          if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;
31          len = dest_domain->total_len;          len = dest_domain->total_len;
32          if ((buf = InitAuditLog(&len)) == NULL) return -ENOMEM;          if ((buf = InitAuditLog(&len, profile, mode, NULL)) == NULL) return -ENOMEM;
33          snprintf(buf + strlen(buf), len - strlen(buf) - 1, KEYWORD_ALLOW_SIGNAL "%d %s\n", signal, dest_domain->name);          snprintf(buf + strlen(buf), len - strlen(buf) - 1, KEYWORD_ALLOW_SIGNAL "%d %s\n", signal, dest_domain->name);
34          return WriteAuditLog(buf, is_granted);          return WriteAuditLog(buf, is_granted);
35  }  }
 #else  
 static inline void AuditSignalLog(const int signal, const struct path_info *dest_domain, const int is_granted) {}  
 #endif  
36    
37  /*************************  SIGNAL ACL HANDLER  *************************/  /*************************  SIGNAL ACL HANDLER  *************************/
38    
39  static int AddSignalEntry(const int sig, const char *dest_pattern, struct domain_info *domain, const u8 is_add, const struct condition_list *condition)  static int AddSignalEntry(const int sig, const char *dest_pattern, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
40  {  {
41          struct acl_info *ptr;          struct acl_info *ptr;
42            struct signal_acl_record *acl;
43          const struct path_info *saved_dest_pattern;          const struct path_info *saved_dest_pattern;
44          const u16 hash = sig;          const u16 hash = sig;
45          int error = -ENOMEM;          int error = -ENOMEM;
46          if (!domain) return -EINVAL;          if (!domain) return -EINVAL;
47          if (!dest_pattern || !IsCorrectDomain(dest_pattern, __FUNCTION__)) return -EINVAL;          if (!dest_pattern || !IsCorrectDomain(dest_pattern, __FUNCTION__)) return -EINVAL;
48          if ((saved_dest_pattern = SaveName(dest_pattern)) == NULL) return -ENOMEM;          if ((saved_dest_pattern = SaveName(dest_pattern)) == NULL) return -ENOMEM;
49          down(&domain_acl_lock);          mutex_lock(&domain_acl_lock);
50          if (is_add) {          if (!is_delete) {
51                  if ((ptr = domain->first_acl_ptr) == NULL) goto first_entry;                  list1_for_each_entry(ptr, &domain->acl_info_list, list) {
52                  while (1) {                          if ((ptr->type & ~(ACL_DELETED | ACL_WITH_CONDITION)) != TYPE_SIGNAL_ACL) continue;
53                          SIGNAL_ACL_RECORD *new_ptr;                          if (GetConditionPart(ptr) != condition) continue;
54                          if (ptr->type == TYPE_SIGNAL_ACL && ptr->u.w == hash && ptr->cond == condition) {                          acl = container_of(ptr, struct signal_acl_record, head);
55                                  if (!pathcmp(((SIGNAL_ACL_RECORD *) ptr)->domainname, saved_dest_pattern)) {                          if (acl->sig != hash || pathcmp(acl->domainname, saved_dest_pattern)) continue;
56                                          ptr->is_deleted = 0;                          error = AddDomainACL(NULL, ptr);
57                                          /* Found. Nothing to do. */                          goto out;
                                         error = 0;  
                                         break;  
                                 }  
                         }  
                         if (ptr->next) {  
                                 ptr = ptr->next;  
                                 continue;  
                         }  
                 first_entry: ;  
                         if (is_add == 1 && TooManyDomainACL(domain)) break;  
                         /* Not found. Append it to the tail. */  
                         if ((new_ptr = (SIGNAL_ACL_RECORD *) alloc_element(sizeof(SIGNAL_ACL_RECORD))) == NULL) break;  
                         new_ptr->head.type = TYPE_SIGNAL_ACL;  
                         new_ptr->head.u.w = hash;  
                         new_ptr->head.cond = condition;  
                         new_ptr->domainname = saved_dest_pattern;  
                         error = AddDomainACL(ptr, domain, (struct acl_info *) new_ptr);  
                         break;  
58                  }                  }
59                    /* Not found. Append it to the tail. */
60                    if ((acl = alloc_acl_element(TYPE_SIGNAL_ACL, condition)) == NULL) goto out;
61                    acl->sig = hash;
62                    acl->domainname = saved_dest_pattern;
63                    error = AddDomainACL(domain, &acl->head);
64          } else {          } else {
65                  error = -ENOENT;                  error = -ENOENT;
66                  for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {                  list1_for_each_entry(ptr, &domain->acl_info_list, list) {
67                          if (ptr->type != TYPE_SIGNAL_ACL || ptr->is_deleted || ptr->u.w != hash || ptr->cond != condition) continue;                          if ((ptr->type & ~ACL_WITH_CONDITION) != TYPE_SIGNAL_ACL) continue;
68                          if (pathcmp(((SIGNAL_ACL_RECORD *) ptr)->domainname, saved_dest_pattern)) continue;                          if (GetConditionPart(ptr) != condition) continue;
69                            acl = container_of(ptr, struct signal_acl_record, head);
70                            if (acl->sig != hash || pathcmp(acl->domainname, saved_dest_pattern)) continue;
71                          error = DelDomainACL(ptr);                          error = DelDomainACL(ptr);
72                          break;                          break;
73                  }                  }
74          }          }
75          up(&domain_acl_lock);   out: ;
76            mutex_unlock(&domain_acl_lock);
77          return error;          return error;
78  }  }
79    
# Line 100  int CheckSignalACL(const int sig, const Line 84  int CheckSignalACL(const int sig, const
84          const char *dest_pattern;          const char *dest_pattern;
85          struct acl_info *ptr;          struct acl_info *ptr;
86          const u16 hash = sig;          const u16 hash = sig;
87          const int is_enforce = CheckCCSEnforce(CCS_TOMOYO_MAC_FOR_SIGNAL);          const u8 profile = current->domain_info->profile;
88          if (!CheckCCSFlags(CCS_TOMOYO_MAC_FOR_SIGNAL)) return 0;          const u8 mode = CheckCCSFlags(CCS_TOMOYO_MAC_FOR_SIGNAL);
89            const bool is_enforce = (mode == 3);
90            bool found = false;
91            if (!mode) return 0;
92          if (!sig) return 0;                               /* No check for NULL signal. */          if (!sig) return 0;                               /* No check for NULL signal. */
93          if (current->pid == pid) {          if (current->pid == pid) {
94                  AuditSignalLog(sig, domain->domainname, 1);                  AuditSignalLog(sig, domain->domainname, 1, profile, mode);
95                  return 0;                /* No check for self. */                  return 0;                /* No check for self. */
96          }          }
97          { /* Simplified checking. */          { /* Simplified checking. */
# Line 119  int CheckSignalACL(const int sig, const Line 106  int CheckSignalACL(const int sig, const
106                  if (!dest) return 0; /* I can't find destinatioin. */                  if (!dest) return 0; /* I can't find destinatioin. */
107          }          }
108          if (domain == dest) {          if (domain == dest) {
109                  AuditSignalLog(sig, dest->domainname, 1);                  AuditSignalLog(sig, dest->domainname, 1, profile, mode);
110                  return 0;                  return 0;
111          }          }
112          dest_pattern = dest->domainname->name;          dest_pattern = dest->domainname->name;
113          for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {          list1_for_each_entry(ptr, &domain->acl_info_list, list) {
114                  if (ptr->type == TYPE_SIGNAL_ACL && ptr->is_deleted == 0 && ptr->u.w == hash && CheckCondition(ptr->cond, NULL) == 0) {                  struct signal_acl_record *acl;
115                          const int len = ((SIGNAL_ACL_RECORD *) ptr)->domainname->total_len;                  if ((ptr->type & ~ACL_WITH_CONDITION) != TYPE_SIGNAL_ACL) continue;
116                          if (strncmp(((SIGNAL_ACL_RECORD *) ptr)->domainname->name, dest_pattern, len) == 0 && (dest_pattern[len] == ' ' || dest_pattern[len] == '\0')) break;                  acl = container_of(ptr, struct signal_acl_record, head);
117                    if (acl->sig == hash && CheckCondition(ptr, NULL)) {
118                            const int len = acl->domainname->total_len;
119                            if (strncmp(acl->domainname->name, dest_pattern, len)) continue;
120                            if (dest_pattern[len] != ' ' && dest_pattern[len] != '\0') continue;
121                            UpdateCondition(ptr);
122                            found = true;
123                            break;
124                  }                  }
125          }          }
126          if (ptr) {          AuditSignalLog(sig, dest->domainname, found, profile, mode);
127                  AuditSignalLog(sig, dest->domainname, 1);          if (found) return 0;
                 return 0;  
         }  
128          if (TomoyoVerboseMode()) {          if (TomoyoVerboseMode()) {
129                  printk("TOMOYO-%s: Signal %d to %s denied for %s\n", GetMSG(is_enforce), sig, GetLastName(dest), GetLastName(domain));                  printk("TOMOYO-%s: Signal %d to %s denied for %s\n", GetMSG(is_enforce), sig, GetLastName(dest), GetLastName(domain));
130          }          }
         AuditSignalLog(sig, dest->domainname, 0);  
131          if (is_enforce) return CheckSupervisor("%s\n" KEYWORD_ALLOW_SIGNAL "%d %s\n", domain->domainname->name, sig, dest_pattern);          if (is_enforce) return CheckSupervisor("%s\n" KEYWORD_ALLOW_SIGNAL "%d %s\n", domain->domainname->name, sig, dest_pattern);
132          if (CheckCCSAccept(CCS_TOMOYO_MAC_FOR_SIGNAL)) AddSignalEntry(sig, dest_pattern, domain, 1, NULL);          else if (mode == 1 && CheckDomainQuota(domain)) AddSignalEntry(sig, dest_pattern, domain, NULL, 0);
133          return 0;          return 0;
134  }  }
135    
136    int AddSignalPolicy(char *data, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
 int AddSignalPolicy(char *data, struct domain_info *domain, const int is_delete)  
137  {  {
138          int sig;          int sig;
139          char *domainname = strchr(data, ' ');          char *domainname = strchr(data, ' ');
140          if (sscanf(data, "%d", &sig) == 1 && domainname && IsDomainDef(domainname + 1)) {          if (sscanf(data, "%d", &sig) == 1 && domainname && IsDomainDef(domainname + 1)) {
141                  const struct condition_list *condition = NULL;                  return AddSignalEntry(sig, domainname + 1, domain, condition, is_delete);
                 const char *cp = FindConditionPart(domainname + 1);  
                 if (cp && (condition = FindOrAssignNewCondition(cp)) == NULL) return -EINVAL;  
                 return AddSignalEntry(sig, domainname + 1, domain, is_delete ? 0 : -1, condition);  
142          }          }
143          return -EINVAL;          return -EINVAL;
144  }  }
145    
 EXPORT_SYMBOL(CheckSignalACL);  
   
146  /***** TOMOYO Linux end. *****/  /***** TOMOYO Linux end. *****/

Legend:
Removed from v.150  
changed lines
  Added in v.1032

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