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

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/1.5.x/ccs-patch/fs/tomoyo_signal.c revision 502 by kumaneko, Tue Sep 25 13:33:45 2007 UTC trunk/1.6.x/ccs-patch/fs/tomoyo_signal.c revision 989 by kumaneko, Fri Feb 15 13:33:40 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.5.0   2007/09/20   * Version: 1.6.0-pre   2008/02/15
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    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
21    #define find_task_by_pid find_task_by_vpid
22    #endif
23    
24  /*************************  VARIABLES  *************************/  /*************************  VARIABLES  *************************/
25    
26  /* The initial domain. */  /* The initial domain. */
27  extern struct domain_info KERNEL_DOMAIN;  extern struct domain_info KERNEL_DOMAIN;
28    
29  extern struct semaphore domain_acl_lock;  extern struct mutex domain_acl_lock;
30    
31  /*************************  AUDIT FUNCTIONS  *************************/  /*************************  AUDIT FUNCTIONS  *************************/
32    
33  static int AuditSignalLog(const int signal, const struct path_info *dest_domain, const int is_granted)  static int AuditSignalLog(const int signal, const struct path_info *dest_domain, const bool is_granted, const u8 profile, const u8 mode)
34  {  {
35          char *buf;          char *buf;
36          int len;          int len;
37          if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;          if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;
38          len = dest_domain->total_len;          len = dest_domain->total_len;
39          if ((buf = InitAuditLog(&len)) == NULL) return -ENOMEM;          if ((buf = InitAuditLog(&len, profile, mode, NULL)) == NULL) return -ENOMEM;
40          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);
41          return WriteAuditLog(buf, is_granted);          return WriteAuditLog(buf, is_granted);
42  }  }
43    
44  /*************************  SIGNAL ACL HANDLER  *************************/  /*************************  SIGNAL ACL HANDLER  *************************/
45    
46  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)
47  {  {
48          struct acl_info *ptr;          struct acl_info *ptr;
49            struct signal_acl_record *acl;
50          const struct path_info *saved_dest_pattern;          const struct path_info *saved_dest_pattern;
51          const u16 hash = sig;          const u16 hash = sig;
52          int error = -ENOMEM;          int error = -ENOMEM;
53          if (!domain) return -EINVAL;          if (!domain) return -EINVAL;
54          if (!dest_pattern || !IsCorrectDomain(dest_pattern, __FUNCTION__)) return -EINVAL;          if (!dest_pattern || !IsCorrectDomain(dest_pattern, __FUNCTION__)) return -EINVAL;
55          if ((saved_dest_pattern = SaveName(dest_pattern)) == NULL) return -ENOMEM;          if ((saved_dest_pattern = SaveName(dest_pattern)) == NULL) return -ENOMEM;
56          down(&domain_acl_lock);          mutex_lock(&domain_acl_lock);
57          if (is_add) {          if (!is_delete) {
58                  if ((ptr = domain->first_acl_ptr) == NULL) goto first_entry;                  list1_for_each_entry(ptr, &domain->acl_info_list, list) {
59                  while (1) {                          if ((ptr->type & ~(ACL_DELETED | ACL_WITH_CONDITION)) != TYPE_SIGNAL_ACL) continue;
60                          struct signal_acl_record *new_ptr = (struct signal_acl_record *) ptr;                          if (GetConditionPart(ptr) != condition) continue;
61                          if (ptr->type == TYPE_SIGNAL_ACL && new_ptr->sig == hash && ptr->cond == condition) {                          acl = container_of(ptr, struct signal_acl_record, head);
62                                  if (!pathcmp(new_ptr->domainname, saved_dest_pattern)) {                          if (acl->sig != hash || pathcmp(acl->domainname, saved_dest_pattern)) continue;
63                                          ptr->is_deleted = 0;                          error = AddDomainACL(NULL, ptr);
64                                          /* 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 = alloc_element(sizeof(*new_ptr))) == NULL) break;  
                         new_ptr->head.type = TYPE_SIGNAL_ACL;  
                         new_ptr->sig = hash;  
                         new_ptr->head.cond = condition;  
                         new_ptr->domainname = saved_dest_pattern;  
                         error = AddDomainACL(ptr, domain, (struct acl_info *) new_ptr);  
                         break;  
65                  }                  }
66                    /* Not found. Append it to the tail. */
67                    if ((acl = alloc_acl_element(TYPE_SIGNAL_ACL, condition)) == NULL) goto out;
68                    acl->sig = hash;
69                    acl->domainname = saved_dest_pattern;
70                    error = AddDomainACL(domain, &acl->head);
71          } else {          } else {
72                  error = -ENOENT;                  error = -ENOENT;
73                  for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {                  list1_for_each_entry(ptr, &domain->acl_info_list, list) {
74                          struct signal_acl_record *ptr2 = (struct signal_acl_record *) ptr;                          if ((ptr->type & ~ACL_WITH_CONDITION) != TYPE_SIGNAL_ACL) continue;
75                          if (ptr->type != TYPE_SIGNAL_ACL || ptr->is_deleted || ptr2->sig != hash || ptr->cond != condition) continue;                          if (GetConditionPart(ptr) != condition) continue;
76                          if (pathcmp(ptr2->domainname, saved_dest_pattern)) continue;                          acl = container_of(ptr, struct signal_acl_record, head);
77                            if (acl->sig != hash || pathcmp(acl->domainname, saved_dest_pattern)) continue;
78                          error = DelDomainACL(ptr);                          error = DelDomainACL(ptr);
79                          break;                          break;
80                  }                  }
81          }          }
82          up(&domain_acl_lock);   out: ;
83            mutex_unlock(&domain_acl_lock);
84          return error;          return error;
85  }  }
86    
# Line 97  int CheckSignalACL(const int sig, const Line 91  int CheckSignalACL(const int sig, const
91          const char *dest_pattern;          const char *dest_pattern;
92          struct acl_info *ptr;          struct acl_info *ptr;
93          const u16 hash = sig;          const u16 hash = sig;
94          const int is_enforce = CheckCCSEnforce(CCS_TOMOYO_MAC_FOR_SIGNAL);          const u8 profile = current->domain_info->profile;
95          if (!CheckCCSFlags(CCS_TOMOYO_MAC_FOR_SIGNAL)) return 0;          const u8 mode = CheckCCSFlags(CCS_TOMOYO_MAC_FOR_SIGNAL);
96            const bool is_enforce = (mode == 3);
97            bool found = 0;
98            if (!mode) return 0;
99          if (!sig) return 0;                               /* No check for NULL signal. */          if (!sig) return 0;                               /* No check for NULL signal. */
100          if (current->pid == pid) {          if (current->pid == pid) {
101                  AuditSignalLog(sig, domain->domainname, 1);                  AuditSignalLog(sig, domain->domainname, 1, profile, mode);
102                  return 0;                /* No check for self. */                  return 0;                /* No check for self. */
103          }          }
104          { /* Simplified checking. */          { /* Simplified checking. */
# Line 116  int CheckSignalACL(const int sig, const Line 113  int CheckSignalACL(const int sig, const
113                  if (!dest) return 0; /* I can't find destinatioin. */                  if (!dest) return 0; /* I can't find destinatioin. */
114          }          }
115          if (domain == dest) {          if (domain == dest) {
116                  AuditSignalLog(sig, dest->domainname, 1);                  AuditSignalLog(sig, dest->domainname, 1, profile, mode);
117                  return 0;                  return 0;
118          }          }
119          dest_pattern = dest->domainname->name;          dest_pattern = dest->domainname->name;
120          for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {          list1_for_each_entry(ptr, &domain->acl_info_list, list) {
121                  struct signal_acl_record *ptr2 = (struct signal_acl_record *) ptr;                  struct signal_acl_record *acl;
122                  if (ptr->type == TYPE_SIGNAL_ACL && ptr->is_deleted == 0 && ptr2->sig == hash && CheckCondition(ptr->cond, NULL) == 0) {                  if ((ptr->type & ~ACL_WITH_CONDITION) != TYPE_SIGNAL_ACL) continue;
123                          const int len = ptr2->domainname->total_len;                  acl = container_of(ptr, struct signal_acl_record, head);
124                          if (strncmp(ptr2->domainname->name, dest_pattern, len) == 0 && (dest_pattern[len] == ' ' || dest_pattern[len] == '\0')) break;                  if (acl->sig == hash && CheckCondition(ptr, NULL)) {
125                            const int len = acl->domainname->total_len;
126                            if (strncmp(acl->domainname->name, dest_pattern, len)) continue;
127                            if (dest_pattern[len] != ' ' && dest_pattern[len] != '\0') continue;
128                            found = 1;
129                            break;
130                  }                  }
131          }          }
132          if (ptr) {          AuditSignalLog(sig, dest->domainname, found, profile, mode);
133                  AuditSignalLog(sig, dest->domainname, 1);          if (found) return 0;
                 return 0;  
         }  
134          if (TomoyoVerboseMode()) {          if (TomoyoVerboseMode()) {
135                  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));
136          }          }
         AuditSignalLog(sig, dest->domainname, 0);  
137          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);
138          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);
139          return 0;          return 0;
140  }  }
 EXPORT_SYMBOL(CheckSignalACL);  
141    
142  int AddSignalPolicy(char *data, struct domain_info *domain, const int is_delete)  int AddSignalPolicy(char *data, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
143  {  {
144          int sig;          int sig;
145          char *domainname = strchr(data, ' ');          char *domainname = strchr(data, ' ');
146          if (sscanf(data, "%d", &sig) == 1 && domainname && IsDomainDef(domainname + 1)) {          if (sscanf(data, "%d", &sig) == 1 && domainname && IsDomainDef(domainname + 1)) {
147                  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);  
148          }          }
149          return -EINVAL;          return -EINVAL;
150  }  }

Legend:
Removed from v.502  
changed lines
  Added in v.989

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