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

Subversion リポジトリの参照

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

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

revision 1052 by kumaneko, Mon Mar 24 03:50:04 2008 UTC revision 1084 by kumaneko, Thu Apr 3 09:54:46 2008 UTC
# Line 5  Line 5 
5   *   *
6   * Copyright (C) 2005-2008  NTT DATA CORPORATION   * Copyright (C) 2005-2008  NTT DATA CORPORATION
7   *   *
8   * Version: 1.6.0-pre   2008/03/24   * Version: 1.6.0   2008/04/01
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 15  Line 15 
15  #include <linux/ccs_common.h>  #include <linux/ccs_common.h>
16  #include <linux/tomoyo.h>  #include <linux/tomoyo.h>
17  #include <linux/realpath.h>  #include <linux/realpath.h>
18  #include <net/ip.h>  #include <linux/net.h>
19    #include <linux/inet.h>
20    #include <linux/in.h>
21    #include <linux/in6.h>
22    
23  /**  /**
24   * audit_network_log - Audit network log.   * audit_network_log - Audit network log.
# Line 25  Line 28 
28   * @address:    An IPv4 or IPv6 address.   * @address:    An IPv4 or IPv6 address.
29   * @port:       Port number.   * @port:       Port number.
30   * @is_granted: True if this is a granted log.   * @is_granted: True if this is a granted log.
31   * @profile:    Profile number.   * @profile:    Profile number used.
32   * @mode:       Access control mode.   * @mode:       Access control mode used.
33   *   *
34   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
35   */   */
36  static int audit_network_log(const bool is_ipv6, const char *operation,  static int audit_network_log(const bool is_ipv6, const char *operation,
37                               const u32 *address, const u16 port,                               const char *address, const u16 port,
38                               const bool is_granted, const u8 profile,                               const bool is_granted,
39                               const u8 mode)                               const u8 profile, const u8 mode)
40  {  {
41          char *buf;          char *buf;
42          int len = 256, len2;          int len = 256;
43            int len2;
44          if (ccs_can_save_audit_log(is_granted) < 0)          if (ccs_can_save_audit_log(is_granted) < 0)
45                  return -ENOMEM;                  return -ENOMEM;
46          buf = ccs_init_audit_log(&len, profile, mode, NULL);          buf = ccs_init_audit_log(&len, profile, mode, NULL);
47          if (!buf)          if (!buf)
48                  return -ENOMEM;                  return -ENOMEM;
49          len2 = strlen(buf);          len2 = strlen(buf);
50          snprintf(buf + len2, len - len2 - 1, KEYWORD_ALLOW_NETWORK "%s ",          snprintf(buf + len2, len - len2 - 1, KEYWORD_ALLOW_NETWORK "%s %s %u\n",
51                   operation);                   operation, address, port);
         len2 = strlen(buf);  
         if (is_ipv6) {  
                 ccs_print_ipv6(buf + len2, len - len2,  
                                (const struct in6_addr *) address);  
         } else {  
                 u32 ip = *address;  
                 snprintf(buf + len2, len - len2 - 1, "%u.%u.%u.%u",  
                          NIPQUAD(ip));  
         }  
         len2 = strlen(buf);  
         snprintf(buf + len2, len - len2 - 1, " %u\n", port);  
52          return ccs_write_audit_log(buf, is_granted);          return ccs_write_audit_log(buf, is_granted);
53  }  }
54    
# Line 85  static const struct in6_addr *save_ipv6_ Line 78  static const struct in6_addr *save_ipv6_
78          mutex_lock(&lock);          mutex_lock(&lock);
79          list1_for_each_entry(ptr, &address_list, list) {          list1_for_each_entry(ptr, &address_list, list) {
80                  for (i = 0; i < ptr->in_use_count; i++) {                  for (i = 0; i < ptr->in_use_count; i++) {
81                          if (memcmp(&ptr->addr[i], addr, sizeof(*addr)) == 0)                          if (!memcmp(&ptr->addr[i], addr, sizeof(*addr)))
82                                  goto ok;                                  goto ok;
83                  }                  }
84                  if (i < block_size)                  if (i < block_size)
# Line 110  static LIST1_HEAD(address_group_list); Line 103  static LIST1_HEAD(address_group_list);
103  /**  /**
104   * update_address_group_entry - Update "struct address_group_entry" list.   * update_address_group_entry - Update "struct address_group_entry" list.
105   *   *
106   * @group_name:  The name of group.   * @group_name:  The name of address group.
107   * @is_ipv6:     True if @address is an IPv6 address.   * @is_ipv6:     True if @min_address and @max_address are IPv6 addresses.
108   * @min_address: Start of IPv4 or IPv6 address range.   * @min_address: Start of IPv4 or IPv6 address range.
109   * @max_address: End of IPv4 or IPv6 address range.   * @max_address: End of IPv4 or IPv6 address range.
110   * @is_delete:   True if it is a delete request.   * @is_delete:   True if it is a delete request.
# Line 125  static int update_address_group_entry(co Line 118  static int update_address_group_entry(co
118                                        const bool is_delete)                                        const bool is_delete)
119  {  {
120          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
121          struct address_group_entry *new_group, *group;          struct address_group_entry *new_group;
122          struct address_group_member *new_member, *member;          struct address_group_entry *group;
123            struct address_group_member *new_member;
124            struct address_group_member *member;
125          const struct path_info *saved_group_name;          const struct path_info *saved_group_name;
126          const struct in6_addr *saved_min_address = NULL;          const struct in6_addr *saved_min_address = NULL;
127          const struct in6_addr *saved_max_address = NULL;          const struct in6_addr *saved_max_address = NULL;
# Line 199  static int update_address_group_entry(co Line 194  static int update_address_group_entry(co
194          error = 0;          error = 0;
195   out:   out:
196          mutex_unlock(&lock);          mutex_unlock(&lock);
197            ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
198          return error;          return error;
199  }  }
200    
# Line 214  int ccs_write_address_group_policy(char Line 210  int ccs_write_address_group_policy(char
210  {  {
211          u8 count;          u8 count;
212          bool is_ipv6;          bool is_ipv6;
213          u16 min_address[8], max_address[8];          u16 min_address[8];
214            u16 max_address[8];
215          char *cp = strchr(data, ' ');          char *cp = strchr(data, ' ');
216          if (!cp)          if (!cp)
217                  return -EINVAL;                  return -EINVAL;
# Line 258  int ccs_write_address_group_policy(char Line 255  int ccs_write_address_group_policy(char
255                                + (u8) max_address[3]);                                + (u8) max_address[3]);
256                  *(u32 *) max_address = ip;                  *(u32 *) max_address = ip;
257                  is_ipv6 = false;                  is_ipv6 = false;
258          } else {                  goto ok;
                 return -EINVAL;  
259          }          }
260            return -EINVAL;
261   ok:   ok:
262          return update_address_group_entry(data, is_ipv6,          return update_address_group_entry(data, is_ipv6,
263                                            min_address, max_address, is_delete);                                            min_address, max_address, is_delete);
# Line 269  int ccs_write_address_group_policy(char Line 266  int ccs_write_address_group_policy(char
266  /**  /**
267   * find_or_assign_new_address_group - Create address group.   * find_or_assign_new_address_group - Create address group.
268   *   *
269   * @group_name: The name of group.   * @group_name: The name of address group.
270   *   *
271   * Returns pointer to "struct address_group_entry" on success, NULL otherwise.   * Returns pointer to "struct address_group_entry" on success, NULL otherwise.
272   */   */
# Line 280  find_or_assign_new_address_group(const c Line 277  find_or_assign_new_address_group(const c
277          struct address_group_entry *group;          struct address_group_entry *group;
278          for (i = 0; i <= 1; i++) {          for (i = 0; i <= 1; i++) {
279                  list1_for_each_entry(group, &address_group_list, list) {                  list1_for_each_entry(group, &address_group_list, list) {
280                          if (strcmp(group_name, group->group_name->name) == 0)                          if (!strcmp(group_name, group->group_name->name))
281                                  return group;                                  return group;
282                  }                  }
283                  if (i == 0) {                  if (!i) {
284                          const u16 dummy[2] = { 0, 0 };                          const u16 dummy[2] = { 0, 0 };
285                          update_address_group_entry(group_name, false,                          update_address_group_entry(group_name, false,
286                                                     dummy, dummy, false);                                                     dummy, dummy, false);
# Line 295  find_or_assign_new_address_group(const c Line 292  find_or_assign_new_address_group(const c
292  }  }
293    
294  /**  /**
295   * address_matches_to_group - Check whether the given address matches members   * address_matches_to_group - Check whether the given address matches members of the given address group.
  *                            of the given address group.  
296   *   *
297   * @is_ipv6: True if @address is an IPv6 address.   * @is_ipv6: True if @address is an IPv6 address.
298   * @address: An IPv4 or IPv6 address.   * @address: An IPv4 or IPv6 address.
# Line 327  static bool address_matches_to_group(con Line 323  static bool address_matches_to_group(con
323  }  }
324    
325  /**  /**
326   * ccs_read_address_group_policy - Dump "struct address_group_entry" list.   * ccs_read_address_group_policy - Read "struct address_group_entry" list.
327   *   *
328   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
329   *   *
# Line 348  bool ccs_read_address_group_policy(struc Line 344  bool ccs_read_address_group_policy(struc
344                                               list);                                               list);
345                          if (member->is_deleted)                          if (member->is_deleted)
346                                  continue;                                  continue;
347                          if (!member->is_ipv6) {                          if (member->is_ipv6) {
348                                  const struct in6_addr *min_address                                  const struct in6_addr *min_address
349                                          = member->min.ipv6;                                          = member->min.ipv6;
350                                  const struct in6_addr *max_address                                  const struct in6_addr *max_address
# Line 389  bool ccs_read_address_group_policy(struc Line 385  bool ccs_read_address_group_policy(struc
385    
386  #if !defined(NIP6)  #if !defined(NIP6)
387  #define NIP6(addr)      \  #define NIP6(addr)      \
388          ntohs((addr).s6_addr16[0]),ntohs((addr).s6_addr16[1]),\          ntohs((addr).s6_addr16[0]), ntohs((addr).s6_addr16[1]), \
389          ntohs((addr).s6_addr16[2]),ntohs((addr).s6_addr16[3]),\          ntohs((addr).s6_addr16[2]), ntohs((addr).s6_addr16[3]), \
390          ntohs((addr).s6_addr16[4]),ntohs((addr).s6_addr16[5]),\          ntohs((addr).s6_addr16[4]), ntohs((addr).s6_addr16[5]), \
391          ntohs((addr).s6_addr16[6]),ntohs((addr).s6_addr16[7])          ntohs((addr).s6_addr16[6]), ntohs((addr).s6_addr16[7])
392  #endif  #endif
393    
394  /**  /**
395   * ccs_print_ipv6 - Dump an IPv6 address.   * ccs_print_ipv6 - Print an IPv6 address.
396   *   *
397   * @buffer:     Buffer to write to.   * @buffer:     Buffer to write to.
398   * @buffer_len: Size of @buffer .   * @buffer_len: Size of @buffer.
399   * @ip:         Pointer to "struct in6_addr".   * @ip:         Pointer to "struct in6_addr".
400   *   *
401   * Returns @buffer.   * Returns nothing.
402   */   */
403  char *ccs_print_ipv6(char *buffer, const int buffer_len,  void ccs_print_ipv6(char *buffer, const int buffer_len,
404                       const struct in6_addr *ip)                      const struct in6_addr *ip)
405  {  {
406          memset(buffer, 0, buffer_len);          memset(buffer, 0, buffer_len);
407          snprintf(buffer, buffer_len - 1, "%x:%x:%x:%x:%x:%x:%x:%x", NIP6(*ip));          snprintf(buffer, buffer_len - 1, "%x:%x:%x:%x:%x:%x:%x:%x", NIP6(*ip));
         return buffer;  
408  }  }
409    
410  /**  /**
# Line 496  static int update_network_entry(const u8 Line 491  static int update_network_entry(const u8
491          if (is_delete)          if (is_delete)
492                  goto delete;                  goto delete;
493          list1_for_each_entry(ptr, &domain->acl_info_list, list) {          list1_for_each_entry(ptr, &domain->acl_info_list, list) {
494                  if ((ptr->type & ~(ACL_DELETED | ACL_WITH_CONDITION))                  if (ccs_acl_type1(ptr) != TYPE_IP_NETWORK_ACL)
                     != TYPE_IP_NETWORK_ACL)  
495                          continue;                          continue;
496                  if (ccs_get_condition_part(ptr) != condition)                  if (ccs_get_condition_part(ptr) != condition)
497                          continue;                          continue;
# Line 543  static int update_network_entry(const u8 Line 537  static int update_network_entry(const u8
537   delete:   delete:
538          error = -ENOENT;          error = -ENOENT;
539          list1_for_each_entry(ptr, &domain->acl_info_list, list) {          list1_for_each_entry(ptr, &domain->acl_info_list, list) {
540                  if ((ptr->type & ~ACL_WITH_CONDITION) != TYPE_IP_NETWORK_ACL)                  if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
541                          continue;                          continue;
542                  if (ccs_get_condition_part(ptr) != condition)                  if (ccs_get_condition_part(ptr) != condition)
543                          continue;                          continue;
# Line 594  static int check_network_entry(const boo Line 588  static int check_network_entry(const boo
588          /* using host byte order to allow u32 comparison than memcmp().*/          /* using host byte order to allow u32 comparison than memcmp().*/
589          const u32 ip = ntohl(*address);          const u32 ip = ntohl(*address);
590          bool found = false;          bool found = false;
591            char buf[64];
592          if (!mode)          if (!mode)
593                  return 0;                  return 0;
594          list1_for_each_entry(ptr, &domain->acl_info_list, list) {          list1_for_each_entry(ptr, &domain->acl_info_list, list) {
595                  struct ip_network_acl_record *acl;                  struct ip_network_acl_record *acl;
596                  if ((ptr->type & ~ACL_WITH_CONDITION) != TYPE_IP_NETWORK_ACL)                  if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
597                          continue;                          continue;
598                  acl = container_of(ptr, struct ip_network_acl_record, head);                  acl = container_of(ptr, struct ip_network_acl_record, head);
599                  if (acl->operation_type != operation || port < acl->min_port ||                  if (acl->operation_type != operation || port < acl->min_port ||
# Line 622  static int check_network_entry(const boo Line 617  static int check_network_entry(const boo
617                  found = true;                  found = true;
618                  break;                  break;
619          }          }
620          audit_network_log(is_ipv6, keyword, address, port, found, profile,          memset(buf, 0, sizeof(buf));
621                            mode);          if (is_ipv6)
622                    ccs_print_ipv6(buf, sizeof(buf),
623                                   (const struct in6_addr *) address);
624            else
625                    snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));
626            audit_network_log(is_ipv6, keyword, buf, port, found, profile, mode);
627          if (found)          if (found)
628                  return 0;                  return 0;
629          if (ccs_verbose_mode()) {          if (ccs_verbose_mode())
630                  if (is_ipv6) {                  printk(KERN_WARNING "TOMOYO-%s: %s to %s %u denied for %s\n",
631                          char buf[64];                         ccs_get_msg(is_enforce), keyword, buf, port,
632                          ccs_print_ipv6(buf, sizeof(buf),                         ccs_get_last_name(domain));
633                                         (const struct in6_addr *) address);          if (is_enforce)
                         printk(KERN_WARNING "TOMOYO-%s: %s to %s %u "  
                                "denied for %s\n", ccs_get_msg(is_enforce),  
                                keyword, buf, port, ccs_get_last_name(domain));  
                 } else {  
                         printk(KERN_WARNING "TOMOYO-%s: %s to %u.%u.%u.%u %u "  
                                "denied for %s\n", ccs_get_msg(is_enforce),  
                                keyword, HIPQUAD(ip), port,  
                                ccs_get_last_name(domain));  
                 }  
         }  
         if (is_enforce) {  
                 if (is_ipv6) {  
                         char buf[64];  
                         ccs_print_ipv6(buf, sizeof(buf),  
                                        (const struct in6_addr *) address);  
                         return ccs_check_supervisor("%s\n"  
                                                     KEYWORD_ALLOW_NETWORK "%s "  
                                                     "%s %u\n",  
                                                     domain->domainname->name,  
                                                     keyword, buf, port);  
                 }  
634                  return ccs_check_supervisor("%s\n" KEYWORD_ALLOW_NETWORK "%s "                  return ccs_check_supervisor("%s\n" KEYWORD_ALLOW_NETWORK "%s "
635                                              "%u.%u.%u.%u %u\n",                                              "%s %u\n", domain->domainname->name,
636                                              domain->domainname->name, keyword,                                              keyword, buf, port);
637                                              HIPQUAD(ip), port);          if (mode == 1 && ccs_check_domain_quota(domain))
         } else if (mode == 1 && ccs_check_domain_quota(domain))  
638                  update_network_entry(operation, is_ipv6 ?                  update_network_entry(operation, is_ipv6 ?
639                                       IP_RECORD_TYPE_IPv6 : IP_RECORD_TYPE_IPv4,                                       IP_RECORD_TYPE_IPv6 : IP_RECORD_TYPE_IPv4,
640                                       NULL, address, address, port, port, domain,                                       NULL, address, address, port, port, domain,
# Line 678  int ccs_write_network_policy(char *data, Line 656  int ccs_write_network_policy(char *data,
656                               const struct condition_list *condition,                               const struct condition_list *condition,
657                               const bool is_delete)                               const bool is_delete)
658  {  {
659          u8 sock_type, operation, record_type;          u8 sock_type;
660          u16 min_address[8], max_address[8];          u8 operation;
661            u8 record_type;
662            u16 min_address[8];
663            u16 max_address[8];
664          struct address_group_entry *group = NULL;          struct address_group_entry *group = NULL;
665          u16 min_port, max_port;          u16 min_port;
666            u16 max_port;
667          u8 count;          u8 count;
668          char *cp1 = NULL, *cp2 = NULL;          char *cp1 = strchr(data, ' ');
669          cp1 = strchr(data, ' ');          char *cp2;
670          if (!cp1)          if (!cp1)
671                  goto out;                  goto out;
672          cp1++;          cp1++;
# Line 771  int ccs_write_network_policy(char *data, Line 753  int ccs_write_network_policy(char *data,
753                                     + (u8) max_address[3]);                                     + (u8) max_address[3]);
754                  *(u32 *) max_address = ip;                  *(u32 *) max_address = ip;
755                  record_type = IP_RECORD_TYPE_IPv4;                  record_type = IP_RECORD_TYPE_IPv4;
756          } else if (*cp2 == '@') {                  goto ok;
757            }
758            if (*cp2 == '@') {
759                  group = find_or_assign_new_address_group(cp2 + 1);                  group = find_or_assign_new_address_group(cp2 + 1);
760                  if (!group)                  if (!group)
761                          return -ENOMEM;                          return -ENOMEM;
762                  record_type = IP_RECORD_TYPE_ADDRESS_GROUP;                  record_type = IP_RECORD_TYPE_ADDRESS_GROUP;
763          } else {                  goto ok;
                 goto out;  
764          }          }
765     out:
766            return -EINVAL;
767   ok:   ok:
768          if (strchr(cp1, ' '))          if (strchr(cp1, ' '))
769                  goto out;                  goto out;
# Line 791  int ccs_write_network_policy(char *data, Line 776  int ccs_write_network_policy(char *data,
776                                      (u32 *) min_address, (u32 *) max_address,                                      (u32 *) min_address, (u32 *) max_address,
777                                      min_port, max_port, domain, condition,                                      min_port, max_port, domain, condition,
778                                      is_delete);                                      is_delete);
  out:  
         return -EINVAL;  
779  }  }
780    
781  /**  /**
# Line 924  int ccs_check_network_recvmsg_acl(const Line 907  int ccs_check_network_recvmsg_acl(const
907  {  {
908          int retval;          int retval;
909          const u8 operation          const u8 operation
910                  = sock_type == SOCK_DGRAM ?                  = (sock_type == SOCK_DGRAM) ?
911                  NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT;                  NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT;
912          current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
913          retval = check_network_entry(is_ipv6, operation, (const u32 *) address,          retval = check_network_entry(is_ipv6, operation, (const u32 *) address,

Legend:
Removed from v.1052  
changed lines
  Added in v.1084

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