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

Subversion リポジトリの参照

Diff of /trunk/1.8.x/ccs-patch/security/ccsecurity/network.c

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

trunk/1.5.x/ccs-patch/fs/tomoyo_network.c revision 776 by kumaneko, Wed Dec 5 05:29:11 2007 UTC trunk/1.6.x/ccs-patch/fs/tomoyo_network.c revision 912 by kumaneko, Mon Jan 21 11:59:49 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.3-pre   2007/12/03   * Version: 1.6.0-pre   2008/01/21
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 24  extern struct mutex domain_acl_lock; Line 24  extern struct mutex domain_acl_lock;
24    
25  /*************************  AUDIT FUNCTIONS  *************************/  /*************************  AUDIT FUNCTIONS  *************************/
26    
27  static int AuditNetworkLog(const bool is_ipv6, const char *operation, const u32 *address, const u16 port, const bool is_granted)  static int AuditNetworkLog(const bool is_ipv6, const char *operation, const u32 *address, const u16 port, const bool is_granted, const u8 profile, const u8 mode)
28  {  {
29          char *buf;          char *buf;
30          int len = 256;          int len = 256;
31          if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;          if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;
32          if ((buf = InitAuditLog(&len)) == NULL) return -ENOMEM;          if ((buf = InitAuditLog(&len, profile, mode)) == NULL) return -ENOMEM;
33          snprintf(buf + strlen(buf), len - strlen(buf) - 1, KEYWORD_ALLOW_NETWORK "%s ", operation);          snprintf(buf + strlen(buf), len - strlen(buf) - 1, KEYWORD_ALLOW_NETWORK "%s ", operation);
34          if (is_ipv6) {          if (is_ipv6) {
35                  print_ipv6(buf + strlen(buf), len - strlen(buf), (const struct in6_addr *) address);                  print_ipv6(buf + strlen(buf), len - strlen(buf), (const struct in6_addr *) address);
# Line 46  static int AuditNetworkLog(const bool is Line 46  static int AuditNetworkLog(const bool is
46  /* Keep the given IPv6 address on the RAM. The RAM is shared, so NEVER try to modify or kfree() the returned address. */  /* Keep the given IPv6 address on the RAM. The RAM is shared, so NEVER try to modify or kfree() the returned address. */
47  static const struct in6_addr *SaveIPv6Address(const struct in6_addr *addr)  static const struct in6_addr *SaveIPv6Address(const struct in6_addr *addr)
48  {  {
49          static const int block_size = 16;          static const u8 block_size = 16;
50          struct addr_list {          struct addr_list {
51                  struct in6_addr addr[block_size];                  struct in6_addr addr[block_size];
52                  struct list1_head list;                  struct list1_head list;
# Line 55  static const struct in6_addr *SaveIPv6Ad Line 55  static const struct in6_addr *SaveIPv6Ad
55          static LIST1_HEAD(address_list);          static LIST1_HEAD(address_list);
56          struct addr_list *ptr;          struct addr_list *ptr;
57          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
58          int i = block_size;          u8 i = block_size;
59          if (!addr) return NULL;          if (!addr) return NULL;
60          mutex_lock(&lock);          mutex_lock(&lock);
61          list1_for_each_entry(ptr, &address_list, list) {          list1_for_each_entry(ptr, &address_list, list) {
# Line 141  static int AddAddressGroupEntry(const ch Line 141  static int AddAddressGroupEntry(const ch
141    
142  int AddAddressGroupPolicy(char *data, const bool is_delete)  int AddAddressGroupPolicy(char *data, const bool is_delete)
143  {  {
144          int count, is_ipv6;          u8 count;
145            bool is_ipv6;
146          u16 min_address[8], max_address[8];          u16 min_address[8], max_address[8];
147          char *cp = strchr(data, ' ');          char *cp = strchr(data, ' ');
148          if (!cp) return -EINVAL;          if (!cp) return -EINVAL;
# Line 151  int AddAddressGroupPolicy(char *data, co Line 152  int AddAddressGroupPolicy(char *data, co
152                              &min_address[4], &min_address[5], &min_address[6], &min_address[7],                              &min_address[4], &min_address[5], &min_address[6], &min_address[7],
153                              &max_address[0], &max_address[1], &max_address[2], &max_address[3],                              &max_address[0], &max_address[1], &max_address[2], &max_address[3],
154                              &max_address[4], &max_address[5], &max_address[6], &max_address[7])) == 8 || count == 16) {                              &max_address[4], &max_address[5], &max_address[6], &max_address[7])) == 8 || count == 16) {
155                  int i;                  u8 i;
156                  for (i = 0; i < 8; i++) {                  for (i = 0; i < 8; i++) {
157                          min_address[i] = htons(min_address[i]);                          min_address[i] = htons(min_address[i]);
158                          max_address[i] = htons(max_address[i]);                          max_address[i] = htons(max_address[i]);
# Line 174  int AddAddressGroupPolicy(char *data, co Line 175  int AddAddressGroupPolicy(char *data, co
175    
176  static struct address_group_entry *FindOrAssignNewAddressGroup(const char *group_name)  static struct address_group_entry *FindOrAssignNewAddressGroup(const char *group_name)
177  {  {
178          int i;          u8 i;
179          struct address_group_entry *group;          struct address_group_entry *group;
180          for (i = 0; i <= 1; i++) {          for (i = 0; i <= 1; i++) {
181                  list1_for_each_entry(group, &address_group_list, list) {                  list1_for_each_entry(group, &address_group_list, list) {
# Line 189  static struct address_group_entry *FindO Line 190  static struct address_group_entry *FindO
190          return NULL;          return NULL;
191  }  }
192    
193  static int AddressMatchesToGroup(const bool is_ipv6, const u32 *address, const struct address_group_entry *group)  static bool AddressMatchesToGroup(const bool is_ipv6, const u32 *address, const struct address_group_entry *group)
194  {  {
195          struct address_group_member *member;          struct address_group_member *member;
196          const u32 ip = ntohl(*address);          const u32 ip = ntohl(*address);
# Line 260  char *print_ipv6(char *buffer, const int Line 261  char *print_ipv6(char *buffer, const int
261          return buffer;          return buffer;
262  }  }
263    
264  const char *network2keyword(const unsigned int operation)  const char *net_operation2keyword(const u8 operation)
265  {  {
266          const char *keyword = "unknown";          const char *keyword = "unknown";
267          switch (operation) {          switch (operation) {
# Line 307  static int AddNetworkEntry(const u8 oper Line 308  static int AddNetworkEntry(const u8 oper
308          mutex_lock(&domain_acl_lock);          mutex_lock(&domain_acl_lock);
309          if (!is_delete) {          if (!is_delete) {
310                  list1_for_each_entry(ptr, &domain->acl_info_list, list) {                  list1_for_each_entry(ptr, &domain->acl_info_list, list) {
311                            if ((ptr->type & ~(ACL_DELETED | ACL_WITH_CONDITION)) != TYPE_IP_NETWORK_ACL) continue;
312                            if (GetConditionPart(ptr) != condition) continue;
313                          acl = container_of(ptr, struct ip_network_acl_record, head);                          acl = container_of(ptr, struct ip_network_acl_record, head);
314                          if (ptr->type == TYPE_IP_NETWORK_ACL && acl->operation_type == operation && acl->record_type == record_type && ptr->cond == condition && acl->min_port == min_port && max_port == acl->max_port) {                          if (acl->operation_type != operation || acl->record_type != record_type || acl->min_port != min_port || max_port != acl->max_port) continue;
315                                  if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {                          if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
316                                          if (acl->u.group == group) {                                  if (acl->u.group != group) continue;
317                                                  ptr->is_deleted = 0;                          } else if (record_type == IP_RECORD_TYPE_IPv4) {
318                                                  /* Found. Nothing to do. */                                  if (acl->u.ipv4.min != min_ip || max_ip != acl->u.ipv4.max) continue;
319                                                  error = 0;                          } else if (record_type == IP_RECORD_TYPE_IPv6) {
320                                                  goto out;                                  if (acl->u.ipv6.min != saved_min_address || saved_max_address != acl->u.ipv6.max) continue;
                                         }  
                                 } else if (record_type == IP_RECORD_TYPE_IPv4) {  
                                         if (acl->u.ipv4.min == min_ip && max_ip == acl->u.ipv4.max) {  
                                                 ptr->is_deleted = 0;  
                                                 /* Found. Nothing to do. */  
                                                 error = 0;  
                                                 goto out;  
                                         }  
                                 } else if (record_type == IP_RECORD_TYPE_IPv6) {  
                                         if (acl->u.ipv6.min == saved_min_address && saved_max_address == acl->u.ipv6.max) {  
                                                 ptr->is_deleted = 0;  
                                                 /* Found. Nothing to do. */  
                                                 error = 0;  
                                                 goto out;  
                                         }  
                                 }  
321                          }                          }
322                            error = AddDomainACL(NULL, ptr);
323                            goto out;
324                  }                  }
325                  /* Not found. Append it to the tail. */                  /* Not found. Append it to the tail. */
326                  if ((acl = alloc_element(sizeof(*acl))) == NULL) goto out;                  if ((acl = alloc_acl_element(TYPE_IP_NETWORK_ACL, condition)) == NULL) goto out;
                 acl->head.type = TYPE_IP_NETWORK_ACL;  
327                  acl->operation_type = operation;                  acl->operation_type = operation;
328                  acl->record_type = record_type;                  acl->record_type = record_type;
                 acl->head.cond = condition;  
329                  if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {                  if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
330                          acl->u.group = group;                          acl->u.group = group;
331                  } else if (record_type == IP_RECORD_TYPE_IPv4) {                  } else if (record_type == IP_RECORD_TYPE_IPv4) {
# Line 354  static int AddNetworkEntry(const u8 oper Line 341  static int AddNetworkEntry(const u8 oper
341          } else {          } else {
342                  error = -ENOENT;                  error = -ENOENT;
343                  list1_for_each_entry(ptr, &domain->acl_info_list, list) {                  list1_for_each_entry(ptr, &domain->acl_info_list, list) {
344                            if ((ptr->type & ~ACL_WITH_CONDITION) != TYPE_IP_NETWORK_ACL) continue;
345                            if (GetConditionPart(ptr) != condition) continue;
346                          acl = container_of(ptr, struct ip_network_acl_record, head);                          acl = container_of(ptr, struct ip_network_acl_record, head);
347                          if (ptr->type != TYPE_IP_NETWORK_ACL || ptr->is_deleted || acl->operation_type != operation || acl->record_type != record_type || ptr->cond != condition || acl->min_port != min_port || acl->max_port != max_port) continue;                          if (acl->operation_type != operation || acl->record_type != record_type || acl->min_port != min_port || max_port != acl->max_port) continue;
348                          if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {                          if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
349                                  if (acl->u.group != group) continue;                                  if (acl->u.group != group) continue;
350                          } else if (record_type == IP_RECORD_TYPE_IPv4) {                          } else if (record_type == IP_RECORD_TYPE_IPv4) {
# Line 372  static int AddNetworkEntry(const u8 oper Line 361  static int AddNetworkEntry(const u8 oper
361          return error;          return error;
362  }  }
363    
364  static int CheckNetworkEntry(const bool is_ipv6, const int operation, const u32 *address, const u16 port)  static int CheckNetworkEntry(const bool is_ipv6, const u8 operation, const u32 *address, const u16 port)
365  {  {
366          struct domain_info * const domain = current->domain_info;          struct domain_info * const domain = current->domain_info;
367          struct acl_info *ptr;          struct acl_info *ptr;
368          const char *keyword = network2keyword(operation);          const char *keyword = net_operation2keyword(operation);
369          const bool is_enforce = CheckCCSEnforce(CCS_TOMOYO_MAC_FOR_NETWORK);          const u8 profile = current->domain_info->profile;
370            const u8 mode = CheckCCSFlags(CCS_TOMOYO_MAC_FOR_NETWORK);
371            const bool is_enforce = (mode == 3);
372          const u32 ip = ntohl(*address); /* using host byte order to allow u32 comparison than memcmp().*/          const u32 ip = ntohl(*address); /* using host byte order to allow u32 comparison than memcmp().*/
373          bool found = 0;          bool found = 0;
374          if (!CheckCCSFlags(CCS_TOMOYO_MAC_FOR_NETWORK)) return 0;          if (!mode) return 0;
375          list1_for_each_entry(ptr, &domain->acl_info_list, list) {          list1_for_each_entry(ptr, &domain->acl_info_list, list) {
376                  struct ip_network_acl_record *acl;                  struct ip_network_acl_record *acl;
377                    if ((ptr->type & ~ACL_WITH_CONDITION) != TYPE_IP_NETWORK_ACL) continue;
378                  acl = container_of(ptr, struct ip_network_acl_record, head);                  acl = container_of(ptr, struct ip_network_acl_record, head);
379                  if (ptr->type != TYPE_IP_NETWORK_ACL || ptr->is_deleted || acl->operation_type != operation || port < acl->min_port || acl->max_port < port || CheckCondition(ptr->cond, NULL)) continue;                  if (acl->operation_type != operation || port < acl->min_port || acl->max_port < port || !CheckCondition(ptr, NULL)) continue;
380                  if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {                  if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
381                          if (!AddressMatchesToGroup(is_ipv6, address, acl->u.group)) continue;                          if (!AddressMatchesToGroup(is_ipv6, address, acl->u.group)) continue;
382                  } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {                  } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {
# Line 394  static int CheckNetworkEntry(const bool Line 386  static int CheckNetworkEntry(const bool
386                  }                  }
387                  found = 1;                  found = 1;
388                  break;                  break;
                           
389          }          }
390          AuditNetworkLog(is_ipv6, keyword, address, port, found);          AuditNetworkLog(is_ipv6, keyword, address, port, found, profile, mode);
391          if (found) return 0;          if (found) return 0;
392          if (TomoyoVerboseMode()) {          if (TomoyoVerboseMode()) {
393                  if (is_ipv6) {                  if (is_ipv6) {
# Line 407  static int CheckNetworkEntry(const bool Line 398  static int CheckNetworkEntry(const bool
398                          printk("TOMOYO-%s: %s to %u.%u.%u.%u %u denied for %s\n", GetMSG(is_enforce), keyword, HIPQUAD(ip), port, GetLastName(domain));                          printk("TOMOYO-%s: %s to %u.%u.%u.%u %u denied for %s\n", GetMSG(is_enforce), keyword, HIPQUAD(ip), port, GetLastName(domain));
399                  }                  }
400          }          }
         AuditNetworkLog(is_ipv6, keyword, address, port, 0);  
401          if (is_enforce) {          if (is_enforce) {
402                  if (is_ipv6) {                  if (is_ipv6) {
403                          char buf[64];                          char buf[64];
# Line 416  static int CheckNetworkEntry(const bool Line 406  static int CheckNetworkEntry(const bool
406                  }                  }
407                  return CheckSupervisor("%s\n" KEYWORD_ALLOW_NETWORK "%s %u.%u.%u.%u %u\n", domain->domainname->name, keyword, HIPQUAD(ip), port);                  return CheckSupervisor("%s\n" KEYWORD_ALLOW_NETWORK "%s %u.%u.%u.%u %u\n", domain->domainname->name, keyword, HIPQUAD(ip), port);
408          }          }
409          if (CheckCCSAccept(CCS_TOMOYO_MAC_FOR_NETWORK, domain)) AddNetworkEntry(operation, is_ipv6 ? IP_RECORD_TYPE_IPv6 : IP_RECORD_TYPE_IPv4, NULL, address, address, port, port, domain, NULL, 0);          else if (mode == 1 && CheckDomainQuota(domain)) AddNetworkEntry(operation, is_ipv6 ? IP_RECORD_TYPE_IPv6 : IP_RECORD_TYPE_IPv4, NULL, address, address, port, port, domain, NULL, 0);
410          return 0;          return 0;
411  }  }
412    
# Line 426  int AddNetworkPolicy(char *data, struct Line 416  int AddNetworkPolicy(char *data, struct
416          u16 min_address[8], max_address[8];          u16 min_address[8], max_address[8];
417          struct address_group_entry *group = NULL;          struct address_group_entry *group = NULL;
418          u16 min_port, max_port;          u16 min_port, max_port;
419          int count;          u8 count;
420          char *cp1 = NULL, *cp2 = NULL;          char *cp1 = NULL, *cp2 = NULL;
421          if ((cp1 = strchr(data, ' ')) == NULL) goto out; cp1++;          if ((cp1 = strchr(data, ' ')) == NULL) goto out; cp1++;
422          if (strncmp(data, "TCP ", 4) == 0) sock_type = SOCK_STREAM;          if (strncmp(data, "TCP ", 4) == 0) sock_type = SOCK_STREAM;
# Line 451  int AddNetworkPolicy(char *data, struct Line 441  int AddNetworkPolicy(char *data, struct
441                              &min_address[4], &min_address[5], &min_address[6], &min_address[7],                              &min_address[4], &min_address[5], &min_address[6], &min_address[7],
442                              &max_address[0], &max_address[1], &max_address[2], &max_address[3],                              &max_address[0], &max_address[1], &max_address[2], &max_address[3],
443                              &max_address[4], &max_address[5], &max_address[6], &max_address[7])) == 8 || count == 16) {                              &max_address[4], &max_address[5], &max_address[6], &max_address[7])) == 8 || count == 16) {
444                  int i;                  u8 i;
445                  for (i = 0; i < 8; i++) {                  for (i = 0; i < 8; i++) {
446                          min_address[i] = htons(min_address[i]);                          min_address[i] = htons(min_address[i]);
447                          max_address[i] = htons(max_address[i]);                          max_address[i] = htons(max_address[i]);
# Line 485  int CheckNetworkListenACL(const _Bool is Line 475  int CheckNetworkListenACL(const _Bool is
475  {  {
476          return CheckNetworkEntry(is_ipv6, NETWORK_ACL_TCP_LISTEN, (const u32 *) address, ntohs(port));          return CheckNetworkEntry(is_ipv6, NETWORK_ACL_TCP_LISTEN, (const u32 *) address, ntohs(port));
477  }  }
 EXPORT_SYMBOL(CheckNetworkListenACL);  
478    
479  int CheckNetworkConnectACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)  int CheckNetworkConnectACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
480  {  {
481          return CheckNetworkEntry(is_ipv6, sock_type == SOCK_STREAM ? NETWORK_ACL_TCP_CONNECT : (sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT), (const u32 *) address, ntohs(port));          return CheckNetworkEntry(is_ipv6, sock_type == SOCK_STREAM ? NETWORK_ACL_TCP_CONNECT : (sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT), (const u32 *) address, ntohs(port));
482  }  }
 EXPORT_SYMBOL(CheckNetworkConnectACL);  
483    
484  int CheckNetworkBindACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)  int CheckNetworkBindACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
485  {  {
486          return CheckNetworkEntry(is_ipv6, sock_type == SOCK_STREAM ? NETWORK_ACL_TCP_BIND : (sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_BIND : NETWORK_ACL_RAW_BIND), (const u32 *) address, ntohs(port));          return CheckNetworkEntry(is_ipv6, sock_type == SOCK_STREAM ? NETWORK_ACL_TCP_BIND : (sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_BIND : NETWORK_ACL_RAW_BIND), (const u32 *) address, ntohs(port));
487  }  }
 EXPORT_SYMBOL(CheckNetworkBindACL);  
488    
489  int CheckNetworkAcceptACL(const _Bool is_ipv6, const u8 *address, const u16 port)  int CheckNetworkAcceptACL(const _Bool is_ipv6, const u8 *address, const u16 port)
490  {  {
# Line 507  int CheckNetworkAcceptACL(const _Bool is Line 494  int CheckNetworkAcceptACL(const _Bool is
494          current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
495          return retval;          return retval;
496  }  }
 EXPORT_SYMBOL(CheckNetworkAcceptACL);  
497    
498  int CheckNetworkSendMsgACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)  int CheckNetworkSendMsgACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
499  {  {
500          return CheckNetworkEntry(is_ipv6, sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT, (const u32 *) address, ntohs(port));          return CheckNetworkEntry(is_ipv6, sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT, (const u32 *) address, ntohs(port));
501  }  }
 EXPORT_SYMBOL(CheckNetworkSendMsgACL);  
502    
503  int CheckNetworkRecvMsgACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)  int CheckNetworkRecvMsgACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
504  {  {
# Line 523  int CheckNetworkRecvMsgACL(const _Bool i Line 508  int CheckNetworkRecvMsgACL(const _Bool i
508          current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
509          return retval;          return retval;
510  }  }
 EXPORT_SYMBOL(CheckNetworkRecvMsgACL);  
511    
512  /***** TOMOYO Linux end. *****/  /***** TOMOYO Linux end. *****/

Legend:
Removed from v.776  
changed lines
  Added in v.912

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