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

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 2942 by kumaneko, Wed Aug 19 04:26:56 2009 UTC revision 2943 by kumaneko, Mon Aug 24 04:58:42 2009 UTC
# Line 3  Line 3 
3   *   *
4   * Copyright (C) 2005-2009  NTT DATA CORPORATION   * Copyright (C) 2005-2009  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.0-pre   2009/08/08   * Version: 1.7.0-pre   2009/08/24
7   *   *
8   * 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.
9   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
# Line 34  static int ccs_audit_network_log(struct Line 34  static int ccs_audit_network_log(struct
34                                   const char *operation, const char *address,                                   const char *operation, const char *address,
35                                   const u16 port, const bool is_granted)                                   const u16 port, const bool is_granted)
36  {  {
37          if (!is_granted && ccs_verbose_mode(r->domain))          if (!is_granted)
38                  printk(KERN_WARNING "%s: %s to %s %u denied for %s\n",                  ccs_warn_log(r, "%s %s %u", operation, address, port);
                        ccs_get_msg(r->mode == 3), operation, address, port,  
                        ccs_get_last_name(r->domain));  
39          return ccs_write_audit_log(is_granted, r, CCS_KEYWORD_ALLOW_NETWORK          return ccs_write_audit_log(is_granted, r, CCS_KEYWORD_ALLOW_NETWORK
40                                     "%s %s %u\n", operation, address, port);                                     "%s %s %u\n", operation, address, port);
41  }  }
# Line 86  int ccs_parse_ip_address(char *address, Line 84  int ccs_parse_ip_address(char *address,
84  }  }
85    
86  #if !defined(NIP6)  #if !defined(NIP6)
87  #define NIP6(addr)      \  #define NIP6(addr)                                                      \
88          ntohs((addr).s6_addr16[0]), ntohs((addr).s6_addr16[1]), \          ntohs((addr).s6_addr16[0]), ntohs((addr).s6_addr16[1]),         \
89          ntohs((addr).s6_addr16[2]), ntohs((addr).s6_addr16[3]), \                  ntohs((addr).s6_addr16[2]), ntohs((addr).s6_addr16[3]), \
90          ntohs((addr).s6_addr16[4]), ntohs((addr).s6_addr16[5]), \                  ntohs((addr).s6_addr16[4]), ntohs((addr).s6_addr16[5]), \
91          ntohs((addr).s6_addr16[6]), ntohs((addr).s6_addr16[7])                  ntohs((addr).s6_addr16[6]), ntohs((addr).s6_addr16[7])
92  #endif  #endif
93    
94  /**  /**
# Line 161  const char *ccs_net2keyword(const u8 ope Line 159  const char *ccs_net2keyword(const u8 ope
159   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
160   */   */
161  static int ccs_network_entry2(const bool is_ipv6, const u8 operation,  static int ccs_network_entry2(const bool is_ipv6, const u8 operation,
162                                      const u32 *address, const u16 port)                                const u32 *address, const u16 port)
163  {  {
164          struct ccs_request_info r;          struct ccs_request_info r;
165          struct ccs_acl_info *ptr;          struct ccs_acl_info *ptr;
166          const char *keyword = ccs_net2keyword(operation);          const char *keyword = ccs_net2keyword(operation);
         bool is_enforce;  
167          const u16 perm = 1 << operation;          const u16 perm = 1 << operation;
168          /* using host byte order to allow u32 comparison than memcmp().*/          /* using host byte order to allow u32 comparison than memcmp().*/
169          const u32 ip = ntohl(*address);          const u32 ip = ntohl(*address);
170          int error;          int error;
171          char buf[64];          char buf[64];
172          ccs_assert_read_lock();          ccs_assert_read_lock();
173          if (!ccs_can_sleep() ||          if (ccs_init_request_info(&r, NULL,
174              !ccs_init_request_info(&r, NULL, CCS_MAC_NETWORK))                                    CCS_MAC_NETWORK_UDP_BIND + operation)
175                == CCS_MAC_MODE_DISABLED)
176                  return 0;                  return 0;
         is_enforce = (r.mode == 3);  
  retry:  
         error = -EPERM;  
         list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {  
                 struct ccs_ip_network_acl *acl;  
                 if (ptr->is_deleted || ptr->type != CCS_TYPE_IP_NETWORK_ACL)  
                         continue;  
                 acl = container_of(ptr, struct ccs_ip_network_acl, head);  
                 if (!(acl->perm & perm))  
                         continue;  
                 if (!ccs_compare_number_union(port, &acl->port) ||  
                     !ccs_condition(&r, ptr))  
                         continue;  
                 if (acl->address_type == CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP) {  
                         if (!ccs_address_matches_group(is_ipv6, address,  
                                                        acl->address.group))  
                                 continue;  
                 } else if (acl->address_type == CCS_IP_ADDRESS_TYPE_IPv4) {  
                         if (is_ipv6 ||  
                             ip < acl->address.ipv4.min ||  
                             acl->address.ipv4.max < ip)  
                                 continue;  
                 } else {  
                         if (!is_ipv6 ||  
                             memcmp(acl->address.ipv6.min, address, 16) > 0 ||  
                             memcmp(address, acl->address.ipv6.max, 16) > 0)  
                                 continue;  
                 }  
                 r.cond = ptr->cond;  
                 error = 0;  
                 break;  
         }  
177          memset(buf, 0, sizeof(buf));          memset(buf, 0, sizeof(buf));
178          if (is_ipv6)          if (is_ipv6)
179                  ccs_print_ipv6(buf, sizeof(buf),                  ccs_print_ipv6(buf, sizeof(buf), (const struct in6_addr *)
180                                 (const struct in6_addr *) address);                                 address);
181          else          else
182                  snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));                  snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));
183          ccs_audit_network_log(&r, keyword, buf, port, !error);          do {
184          if (error)                  error = -EPERM;
185                    list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {
186                            struct ccs_ip_network_acl *acl;
187                            if (ptr->is_deleted ||
188                                ptr->type != CCS_TYPE_IP_NETWORK_ACL)
189                                    continue;
190                            acl = container_of(ptr, struct ccs_ip_network_acl,
191                                               head);
192                            if (!(acl->perm & perm))
193                                    continue;
194                            if (!ccs_compare_number_union(port, &acl->port) ||
195                                !ccs_condition(&r, ptr))
196                                    continue;
197                            switch (acl->address_type) {
198                            case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:
199                                    if (!ccs_address_matches_group(is_ipv6,
200                                                                   address,
201                                                                   acl->address.
202                                                                   group))
203                                            continue;
204                                    break;
205                            case CCS_IP_ADDRESS_TYPE_IPv4:
206                                    if (is_ipv6 || ip < acl->address.ipv4.min ||
207                                        acl->address.ipv4.max < ip)
208                                            continue;
209                                    break;
210                            default:
211                                    if (!is_ipv6 ||
212                                        memcmp(acl->address.ipv6.min, address, 16)
213                                        > 0 ||
214                                        memcmp(address, acl->address.ipv6.max, 16)
215                                        > 0)
216                                            continue;
217                                    break;
218                            }
219                            r.cond = ptr->cond;
220                            error = 0;
221                            break;
222                    }
223                    ccs_audit_network_log(&r, keyword, buf, port, !error);
224                    if (!error)
225                            break;
226                  error = ccs_supervisor(&r, CCS_KEYWORD_ALLOW_NETWORK                  error = ccs_supervisor(&r, CCS_KEYWORD_ALLOW_NETWORK
227                                               "%s %s %u\n", keyword, buf, port);                                         "%s %s %u\n", keyword, buf, port);
228          if (error == 1)          } while (error == 1);
229                  goto retry;          if (r.mode != CCS_MAC_MODE_ENFORCING)
         if (!is_enforce)  
230                  error = 0;                  error = 0;
231          return error;          return error;
232  }  }
# Line 236  static int ccs_network_entry2(const bool Line 242  static int ccs_network_entry2(const bool
242   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
243   */   */
244  static int ccs_network_entry(const bool is_ipv6, const u8 operation,  static int ccs_network_entry(const bool is_ipv6, const u8 operation,
245                                     const u32 *address, const u16 port)                               const u32 *address, const u16 port)
246  {  {
247          const int idx = ccs_read_lock();          const int idx = ccs_read_lock();
248          const int error = ccs_network_entry2(is_ipv6, operation,          const int error = ccs_network_entry2(is_ipv6, operation,
249                                                     address, port);                                               address, port);
250          ccs_read_unlock(idx);          ccs_read_unlock(idx);
251          return error;          return error;
252  }  }
# Line 323  int ccs_write_network_policy(char *data, Line 329  int ccs_write_network_policy(char *data,
329          case 1:          case 1:
330                  e.address_type = CCS_IP_ADDRESS_TYPE_IPv4;                  e.address_type = CCS_IP_ADDRESS_TYPE_IPv4;
331                  /* use host byte order to allow u32 comparison.*/                  /* use host byte order to allow u32 comparison.*/
332                  e.address.ipv4.min = ntohl(* (u32 *) min_address);                  e.address.ipv4.min = ntohl(*(u32 *) min_address);
333                  e.address.ipv4.max = ntohl(* (u32 *) max_address);                  e.address.ipv4.max = ntohl(*(u32 *) max_address);
334                  break;                  break;
335          default:          default:
336                  if (w[2][0] != '@')                  if (w[2][0] != '@')
# Line 390  int ccs_write_network_policy(char *data, Line 396  int ccs_write_network_policy(char *data,
396   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
397   */   */
398  static inline int ccs_network_listen_acl(const bool is_ipv6,  static inline int ccs_network_listen_acl(const bool is_ipv6,
399                                                 const u8 *address,                                           const u8 *address,
400                                                 const u16 port)                                           const u16 port)
401  {  {
402          return ccs_network_entry(is_ipv6, CCS_NETWORK_TCP_LISTEN,          return ccs_network_entry(is_ipv6, CCS_NETWORK_TCP_LISTEN,
403                                         (const u32 *) address, ntohs(port));                                   (const u32 *) address, ntohs(port));
404  }  }
405    
406  /**  /**
# Line 408  static inline int ccs_network_listen_acl Line 414  static inline int ccs_network_listen_acl
414   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
415   */   */
416  static inline int ccs_network_connect_acl(const bool is_ipv6,  static inline int ccs_network_connect_acl(const bool is_ipv6,
417                                                  const int sock_type,                                            const int sock_type,
418                                                  const u8 *address,                                            const u8 *address,
419                                                  const u16 port)                                            const u16 port)
420  {  {
421          u8 operation;          u8 operation;
422          switch (sock_type) {          switch (sock_type) {
# Line 424  static inline int ccs_network_connect_ac Line 430  static inline int ccs_network_connect_ac
430                  operation = CCS_NETWORK_RAW_CONNECT;                  operation = CCS_NETWORK_RAW_CONNECT;
431          }          }
432          return ccs_network_entry(is_ipv6, operation,          return ccs_network_entry(is_ipv6, operation,
433                                         (const u32 *) address, ntohs(port));                                   (const u32 *) address, ntohs(port));
434  }  }
435    
436  /**  /**
# Line 438  static inline int ccs_network_connect_ac Line 444  static inline int ccs_network_connect_ac
444   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
445   */   */
446  static int ccs_network_bind_acl(const bool is_ipv6, const int sock_type,  static int ccs_network_bind_acl(const bool is_ipv6, const int sock_type,
447                                        const u8 *address, const u16 port)                                  const u8 *address, const u16 port)
448  {  {
449          u8 operation;          u8 operation;
450          switch (sock_type) {          switch (sock_type) {
# Line 452  static int ccs_network_bind_acl(const bo Line 458  static int ccs_network_bind_acl(const bo
458                  operation = CCS_NETWORK_RAW_BIND;                  operation = CCS_NETWORK_RAW_BIND;
459          }          }
460          return ccs_network_entry(is_ipv6, operation,          return ccs_network_entry(is_ipv6, operation,
461                                         (const u32 *) address, ntohs(port));                                   (const u32 *) address, ntohs(port));
462  }  }
463    
464  /**  /**
# Line 465  static int ccs_network_bind_acl(const bo Line 471  static int ccs_network_bind_acl(const bo
471   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
472   */   */
473  static inline int ccs_network_accept_acl(const bool is_ipv6,  static inline int ccs_network_accept_acl(const bool is_ipv6,
474                                                 const u8 *address,                                           const u8 *address,
475                                                 const u16 port)                                           const u16 port)
476  {  {
477          int retval;          int retval;
478          current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
479          retval = ccs_network_entry(is_ipv6, CCS_NETWORK_TCP_ACCEPT,          retval = ccs_network_entry(is_ipv6, CCS_NETWORK_TCP_ACCEPT,
480                                           (const u32 *) address, ntohs(port));                                     (const u32 *) address, ntohs(port));
481          current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
482          return retval;          return retval;
483  }  }
# Line 487  static inline int ccs_network_accept_acl Line 493  static inline int ccs_network_accept_acl
493   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
494   */   */
495  static inline int ccs_network_sendmsg_acl(const bool is_ipv6,  static inline int ccs_network_sendmsg_acl(const bool is_ipv6,
496                                                  const int sock_type,                                            const int sock_type,
497                                                  const u8 *address,                                            const u8 *address,
498                                                  const u16 port)                                            const u16 port)
499  {  {
500          u8 operation;          u8 operation;
501          if (sock_type == SOCK_DGRAM)          if (sock_type == SOCK_DGRAM)
# Line 497  static inline int ccs_network_sendmsg_ac Line 503  static inline int ccs_network_sendmsg_ac
503          else          else
504                  operation = CCS_NETWORK_RAW_CONNECT;                  operation = CCS_NETWORK_RAW_CONNECT;
505          return ccs_network_entry(is_ipv6, operation,          return ccs_network_entry(is_ipv6, operation,
506                                         (const u32 *) address, ntohs(port));                                   (const u32 *) address, ntohs(port));
507  }  }
508    
509  /**  /**
# Line 511  static inline int ccs_network_sendmsg_ac Line 517  static inline int ccs_network_sendmsg_ac
517   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
518   */   */
519  static inline int ccs_network_recvmsg_acl(const bool is_ipv6,  static inline int ccs_network_recvmsg_acl(const bool is_ipv6,
520                                                  const int sock_type,                                            const int sock_type,
521                                                  const u8 *address,                                            const u8 *address,
522                                                  const u16 port)                                            const u16 port)
523  {  {
524          int retval;          int retval;
525          const u8 operation          const u8 operation
# Line 521  static inline int ccs_network_recvmsg_ac Line 527  static inline int ccs_network_recvmsg_ac
527                  CCS_NETWORK_UDP_CONNECT : CCS_NETWORK_RAW_CONNECT;                  CCS_NETWORK_UDP_CONNECT : CCS_NETWORK_RAW_CONNECT;
528          current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
529          retval = ccs_network_entry(is_ipv6, operation,          retval = ccs_network_entry(is_ipv6, operation,
530                                           (const u32 *) address, ntohs(port));                                     (const u32 *) address, ntohs(port));
531          current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
532          return retval;          return retval;
533  }  }
# Line 586  int ccs_socket_listen_permission(struct Line 592  int ccs_socket_listen_permission(struct
592          case AF_INET6:          case AF_INET6:
593                  addr6 = (struct sockaddr_in6 *) addr;                  addr6 = (struct sockaddr_in6 *) addr;
594                  error = ccs_network_listen_acl(true,                  error = ccs_network_listen_acl(true,
595                                                       addr6->sin6_addr.s6_addr,                                                 addr6->sin6_addr.s6_addr,
596                                                       addr6->sin6_port);                                                 addr6->sin6_port);
597                  break;                  break;
598          case AF_INET:          case AF_INET:
599                  addr4 = (struct sockaddr_in *) addr;                  addr4 = (struct sockaddr_in *) addr;
600                  error = ccs_network_listen_acl(false,                  error = ccs_network_listen_acl(false,
601                                                       (u8 *) &addr4->sin_addr,                                                 (u8 *) &addr4->sin_addr,
602                                                       addr4->sin_port);                                                 addr4->sin_port);
603                  break;                  break;
604          }          }
605          return error;          return error;
# Line 629  int ccs_socket_connect_permission(struct Line 635  int ccs_socket_connect_permission(struct
635                  else                  else
636                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
637                  error = ccs_network_connect_acl(true, type,                  error = ccs_network_connect_acl(true, type,
638                                                        addr6->sin6_addr.s6_addr,                                                  addr6->sin6_addr.s6_addr,
639                                                        port);                                                  port);
640                  break;                  break;
641          case AF_INET:          case AF_INET:
642                  if (addr_len < sizeof(struct sockaddr_in))                  if (addr_len < sizeof(struct sockaddr_in))
# Line 641  int ccs_socket_connect_permission(struct Line 647  int ccs_socket_connect_permission(struct
647                  else                  else
648                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
649                  error = ccs_network_connect_acl(false, type,                  error = ccs_network_connect_acl(false, type,
650                                                        (u8 *) &addr4->sin_addr,                                                  (u8 *) &addr4->sin_addr,
651                                                        port);                                                  port);
652                  break;                  break;
653          }          }
654          if (type != SOCK_STREAM)          if (type != SOCK_STREAM)
# Line 687  int ccs_socket_bind_permission(struct so Line 693  int ccs_socket_bind_permission(struct so
693                  else                  else
694                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
695                  error = ccs_network_bind_acl(true, type,                  error = ccs_network_bind_acl(true, type,
696                                                     addr6->sin6_addr.s6_addr,                                               addr6->sin6_addr.s6_addr,
697                                                     port);                                               port);
698                  break;                  break;
699          case AF_INET:          case AF_INET:
700                  if (addr_len < sizeof(struct sockaddr_in))                  if (addr_len < sizeof(struct sockaddr_in))
# Line 699  int ccs_socket_bind_permission(struct so Line 705  int ccs_socket_bind_permission(struct so
705                  else                  else
706                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
707                  error = ccs_network_bind_acl(false, type,                  error = ccs_network_bind_acl(false, type,
708                                                     (u8 *) &addr4->sin_addr,                                               (u8 *) &addr4->sin_addr,
709                                                     port);                                               port);
710                  break;                  break;
711          }          }
712          return error;          return error;
# Line 734  int ccs_socket_accept_permission(struct Line 740  int ccs_socket_accept_permission(struct
740          case AF_INET6:          case AF_INET6:
741                  addr6 = (struct sockaddr_in6 *) addr;                  addr6 = (struct sockaddr_in6 *) addr;
742                  error = ccs_network_accept_acl(true,                  error = ccs_network_accept_acl(true,
743                                                       addr6->sin6_addr.s6_addr,                                                 addr6->sin6_addr.s6_addr,
744                                                       addr6->sin6_port);                                                 addr6->sin6_port);
745                  break;                  break;
746          case AF_INET:          case AF_INET:
747                  addr4 = (struct sockaddr_in *) addr;                  addr4 = (struct sockaddr_in *) addr;
748                  error = ccs_network_accept_acl(false,                  error = ccs_network_accept_acl(false,
749                                                       (u8 *) &addr4->sin_addr,                                                 (u8 *) &addr4->sin_addr,
750                                                       addr4->sin_port);                                                 addr4->sin_port);
751                  break;                  break;
752          }          }
753          return error;          return error;
# Line 771  int ccs_socket_sendmsg_permission(struct Line 777  int ccs_socket_sendmsg_permission(struct
777                  else                  else
778                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
779                  error = ccs_network_sendmsg_acl(true, type,                  error = ccs_network_sendmsg_acl(true, type,
780                                                        addr6->sin6_addr.s6_addr,                                                  addr6->sin6_addr.s6_addr,
781                                                        port);                                                  port);
782                  break;                  break;
783          case AF_INET:          case AF_INET:
784                  if (addr_len < sizeof(struct sockaddr_in))                  if (addr_len < sizeof(struct sockaddr_in))
# Line 783  int ccs_socket_sendmsg_permission(struct Line 789  int ccs_socket_sendmsg_permission(struct
789                  else                  else
790                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
791                  error = ccs_network_sendmsg_acl(false, type,                  error = ccs_network_sendmsg_acl(false, type,
792                                                        (u8 *) &addr4->sin_addr,                                                  (u8 *) &addr4->sin_addr,
793                                                        port);                                                  port);
794                  break;                  break;
795          }          }
796          return error;          return error;
# Line 883  int ccs_socket_recvmsg_permission(struct Line 889  int ccs_socket_recvmsg_permission(struct
889                          port = htons(sk->sk_protocol);                          port = htons(sk->sk_protocol);
890                  }                  }
891                  error = ccs_network_recvmsg_acl(true, type,                  error = ccs_network_recvmsg_acl(true, type,
892                                                        (u8 *) &sin6, port);                                                  (u8 *) &sin6, port);
893                  break;                  break;
894          case PF_INET:          case PF_INET:
895                  if (type == SOCK_DGRAM) { /* UDP IPv4 */                  if (type == SOCK_DGRAM) { /* UDP IPv4 */
# Line 894  int ccs_socket_recvmsg_permission(struct Line 900  int ccs_socket_recvmsg_permission(struct
900                          port = htons(sk->sk_protocol);                          port = htons(sk->sk_protocol);
901                  }                  }
902                  error = ccs_network_recvmsg_acl(false, type,                  error = ccs_network_recvmsg_acl(false, type,
903                                                        (u8 *) &sin4, port);                                                  (u8 *) &sin4, port);
904                  break;                  break;
905          }          }
906          if (!error)          if (!error)

Legend:
Removed from v.2942  
changed lines
  Added in v.2943

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