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

Subversion リポジトリの参照

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

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

branches/ccs-patch/security/ccsecurity/network.c revision 2918 by kumaneko, Tue Aug 18 05:21:21 2009 UTC trunk/1.7.x/ccs-patch/security/ccsecurity/network.c revision 3512 by kumaneko, Fri Mar 19 08:37:22 2010 UTC
# Line 1  Line 1 
1  /*  /*
2   * security/ccsecurity/network.c   * security/ccsecurity/network.c
3   *   *
4   * Copyright (C) 2005-2009  NTT DATA CORPORATION   * Copyright (C) 2005-2010  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.0-pre   2009/08/08   * Version: 1.7.2-pre   2010/03/08
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 149  const char *ccs_net2keyword(const u8 ope Line 147  const char *ccs_net2keyword(const u8 ope
147  }  }
148    
149  /**  /**
150   * ccs_check_network_entry2 - Check permission for network operation.   * ccs_network_entry2 - Check permission for network operation.
151   *   *
152   * @is_ipv6:   True if @address is an IPv6 address.   * @is_ipv6:   True if @address is an IPv6 address.
153   * @operation: Type of operation.   * @operation: Type of operation.
# Line 160  const char *ccs_net2keyword(const u8 ope Line 158  const char *ccs_net2keyword(const u8 ope
158   *   *
159   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
160   */   */
161  static int ccs_check_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_check_read_lock();          if (ccs_init_request_info(&r, NULL,
173          if (!ccs_can_sleep() ||                                    CCS_MAC_NETWORK_UDP_BIND + operation)
174              !ccs_init_request_info(&r, NULL, CCS_MAC_NETWORK))              == CCS_CONFIG_DISABLED)
175                  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_check_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;  
         }  
176          memset(buf, 0, sizeof(buf));          memset(buf, 0, sizeof(buf));
177          if (is_ipv6)          if (is_ipv6)
178                  ccs_print_ipv6(buf, sizeof(buf),                  ccs_print_ipv6(buf, sizeof(buf), (const struct in6_addr *)
179                                 (const struct in6_addr *) address);                                 address);
180          else          else
181                  snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));                  snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));
182          ccs_audit_network_log(&r, keyword, buf, port, !error);          do {
183          if (error)                  error = -EPERM;
184                  error = ccs_check_supervisor(&r, CCS_KEYWORD_ALLOW_NETWORK                  list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {
185                                               "%s %s %u\n", keyword, buf, port);                          struct ccs_ip_network_acl *acl;
186          if (error == 1)                          if (ptr->is_deleted ||
187                  goto retry;                              ptr->type != CCS_TYPE_IP_NETWORK_ACL)
188          if (!is_enforce)                                  continue;
189                            acl = container_of(ptr, struct ccs_ip_network_acl,
190                                               head);
191                            if (!(acl->perm & perm))
192                                    continue;
193                            if (!ccs_compare_number_union(port, &acl->port) ||
194                                !ccs_condition(&r, ptr))
195                                    continue;
196                            switch (acl->address_type) {
197                            case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:
198                                    if (!ccs_address_matches_group(is_ipv6,
199                                                                   address,
200                                                                   acl->address.
201                                                                   group))
202                                            continue;
203                                    break;
204                            case CCS_IP_ADDRESS_TYPE_IPv4:
205                                    if (is_ipv6 || ip < acl->address.ipv4.min ||
206                                        acl->address.ipv4.max < ip)
207                                            continue;
208                                    break;
209                            default:
210                                    if (!is_ipv6 ||
211                                        memcmp(acl->address.ipv6.min, address, 16)
212                                        > 0 ||
213                                        memcmp(address, acl->address.ipv6.max, 16)
214                                        > 0)
215                                            continue;
216                                    break;
217                            }
218                            r.cond = ptr->cond;
219                            error = 0;
220                            break;
221                    }
222                    ccs_audit_network_log(&r, keyword, buf, port, !error);
223                    if (!error)
224                            break;
225                    error = ccs_supervisor(&r, CCS_KEYWORD_ALLOW_NETWORK
226                                           "%s %s %u\n", keyword, buf, port);
227            } while (error == CCS_RETRY_REQUEST);
228            if (r.mode != CCS_CONFIG_ENFORCING)
229                  error = 0;                  error = 0;
230          return error;          return error;
231  }  }
232    
233  /**  /**
234   * ccs_check_network_entry - Check permission for network operation.   * ccs_network_entry - Check permission for network operation.
235   *   *
236   * @is_ipv6:   True if @address is an IPv6 address.   * @is_ipv6:   True if @address is an IPv6 address.
237   * @operation: Type of operation.   * @operation: Type of operation.
# Line 235  static int ccs_check_network_entry2(cons Line 240  static int ccs_check_network_entry2(cons
240   *   *
241   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
242   */   */
243  static int ccs_check_network_entry(const bool is_ipv6, const u8 operation,  static int ccs_network_entry(const bool is_ipv6, const u8 operation,
244                                     const u32 *address, const u16 port)                               const u32 *address, const u16 port)
245  {  {
246          const int idx = ccs_read_lock();          const int idx = ccs_read_lock();
247          const int error = ccs_check_network_entry2(is_ipv6, operation,          const int error = ccs_network_entry2(is_ipv6, operation, address,
248                                                     address, port);                                               port);
249          ccs_read_unlock(idx);          ccs_read_unlock(idx);
250          return error;          return error;
251  }  }
# Line 259  int ccs_write_network_policy(char *data, Line 264  int ccs_write_network_policy(char *data,
264                               struct ccs_condition *condition,                               struct ccs_condition *condition,
265                               const bool is_delete)                               const bool is_delete)
266  {  {
         struct ccs_ip_network_acl *entry = NULL;  
267          struct ccs_acl_info *ptr;          struct ccs_acl_info *ptr;
268          struct ccs_ip_network_acl e = {          struct ccs_ip_network_acl e = {
269                  .head.type = CCS_TYPE_IP_NETWORK_ACL,                  .head.type = CCS_TYPE_IP_NETWORK_ACL,
# Line 323  int ccs_write_network_policy(char *data, Line 327  int ccs_write_network_policy(char *data,
327          case 1:          case 1:
328                  e.address_type = CCS_IP_ADDRESS_TYPE_IPv4;                  e.address_type = CCS_IP_ADDRESS_TYPE_IPv4;
329                  /* use host byte order to allow u32 comparison.*/                  /* use host byte order to allow u32 comparison.*/
330                  e.address.ipv4.min = ntohl(* (u32 *) min_address);                  e.address.ipv4.min = ntohl(*(u32 *) min_address);
331                  e.address.ipv4.max = ntohl(* (u32 *) max_address);                  e.address.ipv4.max = ntohl(*(u32 *) max_address);
332                  break;                  break;
333          default:          default:
334                  if (w[2][0] != '@')                  if (w[2][0] != '@')
# Line 337  int ccs_write_network_policy(char *data, Line 341  int ccs_write_network_policy(char *data,
341          }          }
342          if (!ccs_parse_number_union(w[3], &e.port))          if (!ccs_parse_number_union(w[3], &e.port))
343                  goto out;                  goto out;
         if (!is_delete)  
                 entry = kmalloc(sizeof(e), GFP_KERNEL);  
344          mutex_lock(&ccs_policy_lock);          mutex_lock(&ccs_policy_lock);
345          list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {          list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
346                  struct ccs_ip_network_acl *acl =                  struct ccs_ip_network_acl *acl =
347                          container_of(ptr, struct ccs_ip_network_acl,                          container_of(ptr, struct ccs_ip_network_acl, head);
                                      head);  
348                  if (ptr->type != CCS_TYPE_IP_NETWORK_ACL ||                  if (ptr->type != CCS_TYPE_IP_NETWORK_ACL ||
349                      ptr->cond != condition ||                      ptr->cond != condition ||
350                      ccs_memcmp(acl, &e, offsetof(typeof(e), address_type),                      ccs_memcmp(acl, &e, offsetof(typeof(e), address_type),
# Line 362  int ccs_write_network_policy(char *data, Line 363  int ccs_write_network_policy(char *data,
363                  error = 0;                  error = 0;
364                  break;                  break;
365          }          }
366          if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) {          if (!is_delete && error) {
367                  ccs_add_domain_acl(domain, &entry->head);                  struct ccs_ip_network_acl *entry =
368                  entry = NULL;                          ccs_commit_ok(&e, sizeof(e));
369                  error = 0;                  if (entry) {
370                            ccs_add_domain_acl(domain, &entry->head);
371                            error = 0;
372                    }
373          }          }
374          mutex_unlock(&ccs_policy_lock);          mutex_unlock(&ccs_policy_lock);
375   out:   out:
# Line 376  int ccs_write_network_policy(char *data, Line 380  int ccs_write_network_policy(char *data,
380                  ccs_put_ipv6_address(e.address.ipv6.max);                  ccs_put_ipv6_address(e.address.ipv6.max);
381          }          }
382          ccs_put_number_union(&e.port);          ccs_put_number_union(&e.port);
         kfree(entry);  
383          return error;          return error;
384  }  }
385    
386  /**  /**
387   * ccs_check_network_listen_acl - Check permission for listen() operation.   * ccs_network_listen_acl - Check permission for listen() operation.
388   *   *
389   * @is_ipv6: True if @address is an IPv6 address.   * @is_ipv6: True if @address is an IPv6 address.
390   * @address: An IPv4 or IPv6 address.   * @address: An IPv4 or IPv6 address.
# Line 389  int ccs_write_network_policy(char *data, Line 392  int ccs_write_network_policy(char *data,
392   *   *
393   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
394   */   */
395  static inline int ccs_check_network_listen_acl(const bool is_ipv6,  static inline int ccs_network_listen_acl(const bool is_ipv6, const u8 *address,
396                                                 const u8 *address,                                           const u16 port)
                                                const u16 port)  
397  {  {
398          return ccs_check_network_entry(is_ipv6, CCS_NETWORK_TCP_LISTEN,          return ccs_network_entry(is_ipv6, CCS_NETWORK_TCP_LISTEN,
399                                         (const u32 *) address, ntohs(port));                                   (const u32 *) address, ntohs(port));
400  }  }
401    
402  /**  /**
403   * ccs_check_network_connect_acl - Check permission for connect() operation.   * ccs_network_connect_acl - Check permission for connect() operation.
404   *   *
405   * @is_ipv6:   True if @address is an IPv6 address.   * @is_ipv6:   True if @address is an IPv6 address.
406   * @sock_type: Type of socket. (TCP or UDP or RAW)   * @sock_type: Type of socket. (TCP or UDP or RAW)
# Line 407  static inline int ccs_check_network_list Line 409  static inline int ccs_check_network_list
409   *   *
410   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
411   */   */
412  static inline int ccs_check_network_connect_acl(const bool is_ipv6,  static inline int ccs_network_connect_acl(const bool is_ipv6,
413                                                  const int sock_type,                                            const int sock_type,
414                                                  const u8 *address,                                            const u8 *address, const u16 port)
                                                 const u16 port)  
415  {  {
416          u8 operation;          u8 operation;
417          switch (sock_type) {          switch (sock_type) {
# Line 423  static inline int ccs_check_network_conn Line 424  static inline int ccs_check_network_conn
424          default:          default:
425                  operation = CCS_NETWORK_RAW_CONNECT;                  operation = CCS_NETWORK_RAW_CONNECT;
426          }          }
427          return ccs_check_network_entry(is_ipv6, operation,          return ccs_network_entry(is_ipv6, operation,
428                                         (const u32 *) address, ntohs(port));                                   (const u32 *) address, ntohs(port));
429  }  }
430    
431  /**  /**
432   * ccs_check_network_bind_acl - Check permission for bind() operation.   * ccs_network_bind_acl - Check permission for bind() operation.
433   *   *
434   * @is_ipv6:   True if @address is an IPv6 address.   * @is_ipv6:   True if @address is an IPv6 address.
435   * @sock_type: Type of socket. (TCP or UDP or RAW)   * @sock_type: Type of socket. (TCP or UDP or RAW)
# Line 437  static inline int ccs_check_network_conn Line 438  static inline int ccs_check_network_conn
438   *   *
439   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
440   */   */
441  static int ccs_check_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,
442                                        const u8 *address, const u16 port)                                  const u8 *address, const u16 port)
443  {  {
444          u8 operation;          u8 operation;
445          switch (sock_type) {          switch (sock_type) {
# Line 451  static int ccs_check_network_bind_acl(co Line 452  static int ccs_check_network_bind_acl(co
452          default:          default:
453                  operation = CCS_NETWORK_RAW_BIND;                  operation = CCS_NETWORK_RAW_BIND;
454          }          }
455          return ccs_check_network_entry(is_ipv6, operation,          return ccs_network_entry(is_ipv6, operation,
456                                         (const u32 *) address, ntohs(port));                                   (const u32 *) address, ntohs(port));
457  }  }
458    
459  /**  /**
460   * ccs_check_network_accept_acl - Check permission for accept() operation.   * ccs_network_accept_acl - Check permission for accept() operation.
461   *   *
462   * @is_ipv6: True if @address is an IPv6 address.   * @is_ipv6: True if @address is an IPv6 address.
463   * @address: An IPv4 or IPv6 address.   * @address: An IPv4 or IPv6 address.
# Line 464  static int ccs_check_network_bind_acl(co Line 465  static int ccs_check_network_bind_acl(co
465   *   *
466   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
467   */   */
468  static inline int ccs_check_network_accept_acl(const bool is_ipv6,  static inline int ccs_network_accept_acl(const bool is_ipv6, const u8 *address,
469                                                 const u8 *address,                                           const u16 port)
                                                const u16 port)  
470  {  {
471          int retval;          int retval;
472          current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
473          retval = ccs_check_network_entry(is_ipv6, CCS_NETWORK_TCP_ACCEPT,          retval = ccs_network_entry(is_ipv6, CCS_NETWORK_TCP_ACCEPT,
474                                           (const u32 *) address, ntohs(port));                                     (const u32 *) address, ntohs(port));
475          current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
476          return retval;          return retval;
477  }  }
478    
479  /**  /**
480   * ccs_check_network_sendmsg_acl - Check permission for sendmsg() operation.   * ccs_network_sendmsg_acl - Check permission for sendmsg() operation.
481   *   *
482   * @is_ipv6:   True if @address is an IPv6 address.   * @is_ipv6:   True if @address is an IPv6 address.
483   * @sock_type: Type of socket. (UDP or RAW)   * @sock_type: Type of socket. (UDP or RAW)
# Line 486  static inline int ccs_check_network_acce Line 486  static inline int ccs_check_network_acce
486   *   *
487   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
488   */   */
489  static inline int ccs_check_network_sendmsg_acl(const bool is_ipv6,  static inline int ccs_network_sendmsg_acl(const bool is_ipv6,
490                                                  const int sock_type,                                            const int sock_type,
491                                                  const u8 *address,                                            const u8 *address, const u16 port)
                                                 const u16 port)  
492  {  {
493          u8 operation;          u8 operation;
494          if (sock_type == SOCK_DGRAM)          if (sock_type == SOCK_DGRAM)
495                  operation = CCS_NETWORK_UDP_CONNECT;                  operation = CCS_NETWORK_UDP_CONNECT;
496          else          else
497                  operation = CCS_NETWORK_RAW_CONNECT;                  operation = CCS_NETWORK_RAW_CONNECT;
498          return ccs_check_network_entry(is_ipv6, operation,          return ccs_network_entry(is_ipv6, operation,
499                                         (const u32 *) address, ntohs(port));                                   (const u32 *) address, ntohs(port));
500  }  }
501    
502  /**  /**
503   * ccs_check_network_recvmsg_acl - Check permission for recvmsg() operation.   * ccs_network_recvmsg_acl - Check permission for recvmsg() operation.
504   *   *
505   * @is_ipv6:   True if @address is an IPv6 address.   * @is_ipv6:   True if @address is an IPv6 address.
506   * @sock_type: Type of socket. (UDP or RAW)   * @sock_type: Type of socket. (UDP or RAW)
# Line 510  static inline int ccs_check_network_send Line 509  static inline int ccs_check_network_send
509   *   *
510   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
511   */   */
512  static inline int ccs_check_network_recvmsg_acl(const bool is_ipv6,  static inline int ccs_network_recvmsg_acl(const bool is_ipv6,
513                                                  const int sock_type,                                            const int sock_type,
514                                                  const u8 *address,                                            const u8 *address, const u16 port)
                                                 const u16 port)  
515  {  {
516          int retval;          int retval;
517          const u8 operation          const u8 operation
518                  = (sock_type == SOCK_DGRAM) ?                  = (sock_type == SOCK_DGRAM) ?
519                  CCS_NETWORK_UDP_CONNECT : CCS_NETWORK_RAW_CONNECT;                  CCS_NETWORK_UDP_CONNECT : CCS_NETWORK_RAW_CONNECT;
520          current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
521          retval = ccs_check_network_entry(is_ipv6, operation,          retval = ccs_network_entry(is_ipv6, operation,
522                                           (const u32 *) address, ntohs(port));                                     (const u32 *) address, ntohs(port));
523          current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
524          return retval;          return retval;
525  }  }
# Line 529  static inline int ccs_check_network_recv Line 527  static inline int ccs_check_network_recv
527  #define MAX_SOCK_ADDR 128 /* net/socket.c */  #define MAX_SOCK_ADDR 128 /* net/socket.c */
528    
529  /* Check permission for creating a socket. */  /* Check permission for creating a socket. */
530  int ccs_socket_create_permission(int family, int type, int protocol)  static int __ccs_socket_create_permission(int family, int type, int protocol)
531  {  {
532          int error = 0;          int error = 0;
533          /* Nothing to do if I am a kernel service. */          /* Nothing to do if I am a kernel service. */
# Line 559  int ccs_socket_create_permission(int fam Line 557  int ccs_socket_create_permission(int fam
557  }  }
558    
559  /* Check permission for listening a TCP socket. */  /* Check permission for listening a TCP socket. */
560  int ccs_socket_listen_permission(struct socket *sock)  static int __ccs_socket_listen_permission(struct socket *sock)
561  {  {
562          int error = 0;          int error = 0;
563          char addr[MAX_SOCK_ADDR];          char addr[MAX_SOCK_ADDR];
# Line 585  int ccs_socket_listen_permission(struct Line 583  int ccs_socket_listen_permission(struct
583                  struct sockaddr_in *addr4;                  struct sockaddr_in *addr4;
584          case AF_INET6:          case AF_INET6:
585                  addr6 = (struct sockaddr_in6 *) addr;                  addr6 = (struct sockaddr_in6 *) addr;
586                  error = ccs_check_network_listen_acl(true,                  error = ccs_network_listen_acl(true,
587                                                       addr6->sin6_addr.s6_addr,                                                 addr6->sin6_addr.s6_addr,
588                                                       addr6->sin6_port);                                                 addr6->sin6_port);
589                  break;                  break;
590          case AF_INET:          case AF_INET:
591                  addr4 = (struct sockaddr_in *) addr;                  addr4 = (struct sockaddr_in *) addr;
592                  error = ccs_check_network_listen_acl(false,                  error = ccs_network_listen_acl(false,
593                                                       (u8 *) &addr4->sin_addr,                                                 (u8 *) &addr4->sin_addr,
594                                                       addr4->sin_port);                                                 addr4->sin_port);
595                  break;                  break;
596          }          }
597          return error;          return error;
598  }  }
599    
600  /* Check permission for setting the remote IP address/port pair of a socket. */  /* Check permission for setting the remote IP address/port pair of a socket. */
601  int ccs_socket_connect_permission(struct socket *sock, struct sockaddr *addr,  static int __ccs_socket_connect_permission(struct socket *sock,
602                                    int addr_len)                                             struct sockaddr *addr, int addr_len)
603  {  {
604          int error = 0;          int error = 0;
605          const unsigned int type = sock->type;          const unsigned int type = sock->type;
# Line 628  int ccs_socket_connect_permission(struct Line 626  int ccs_socket_connect_permission(struct
626                          port = addr6->sin6_port;                          port = addr6->sin6_port;
627                  else                  else
628                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
629                  error = ccs_check_network_connect_acl(true, type,                  error = ccs_network_connect_acl(true, type,
630                                                        addr6->sin6_addr.s6_addr,                                                  addr6->sin6_addr.s6_addr,
631                                                        port);                                                  port);
632                  break;                  break;
633          case AF_INET:          case AF_INET:
634                  if (addr_len < sizeof(struct sockaddr_in))                  if (addr_len < sizeof(struct sockaddr_in))
# Line 640  int ccs_socket_connect_permission(struct Line 638  int ccs_socket_connect_permission(struct
638                          port = addr4->sin_port;                          port = addr4->sin_port;
639                  else                  else
640                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
641                  error = ccs_check_network_connect_acl(false, type,                  error = ccs_network_connect_acl(false, type,
642                                                        (u8 *) &addr4->sin_addr,                                                  (u8 *) &addr4->sin_addr,
643                                                        port);                                                  port);
644                  break;                  break;
645          }          }
646          if (type != SOCK_STREAM)          if (type != SOCK_STREAM)
# Line 658  int ccs_socket_connect_permission(struct Line 656  int ccs_socket_connect_permission(struct
656  }  }
657    
658  /* Check permission for setting the local IP address/port pair of a socket. */  /* Check permission for setting the local IP address/port pair of a socket. */
659  int ccs_socket_bind_permission(struct socket *sock, struct sockaddr *addr,  static int __ccs_socket_bind_permission(struct socket *sock,
660                                 int addr_len)                                          struct sockaddr *addr, int addr_len)
661  {  {
662          int error = 0;          int error = 0;
663          const unsigned int type = sock->type;          const unsigned int type = sock->type;
# Line 686  int ccs_socket_bind_permission(struct so Line 684  int ccs_socket_bind_permission(struct so
684                          port = addr6->sin6_port;                          port = addr6->sin6_port;
685                  else                  else
686                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
687                  error = ccs_check_network_bind_acl(true, type,                  error = ccs_network_bind_acl(true, type,
688                                                     addr6->sin6_addr.s6_addr,                                               addr6->sin6_addr.s6_addr,
689                                                     port);                                               port);
690                  break;                  break;
691          case AF_INET:          case AF_INET:
692                  if (addr_len < sizeof(struct sockaddr_in))                  if (addr_len < sizeof(struct sockaddr_in))
# Line 698  int ccs_socket_bind_permission(struct so Line 696  int ccs_socket_bind_permission(struct so
696                          port = addr4->sin_port;                          port = addr4->sin_port;
697                  else                  else
698                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
699                  error = ccs_check_network_bind_acl(false, type,                  error = ccs_network_bind_acl(false, type,
700                                                     (u8 *) &addr4->sin_addr,                                               (u8 *) &addr4->sin_addr,
701                                                     port);                                               port);
702                  break;                  break;
703          }          }
704          return error;          return error;
# Line 711  int ccs_socket_bind_permission(struct so Line 709  int ccs_socket_bind_permission(struct so
709   *   *
710   * Currently, the LSM hook for this purpose is not provided.   * Currently, the LSM hook for this purpose is not provided.
711   */   */
712  int ccs_socket_accept_permission(struct socket *sock, struct sockaddr *addr)  static int __ccs_socket_accept_permission(struct socket *sock,
713                                              struct sockaddr *addr)
714  {  {
715          int error = 0;          int error = 0;
716          int addr_len;          int addr_len;
# Line 733  int ccs_socket_accept_permission(struct Line 732  int ccs_socket_accept_permission(struct
732                  struct sockaddr_in *addr4;                  struct sockaddr_in *addr4;
733          case AF_INET6:          case AF_INET6:
734                  addr6 = (struct sockaddr_in6 *) addr;                  addr6 = (struct sockaddr_in6 *) addr;
735                  error = ccs_check_network_accept_acl(true,                  error = ccs_network_accept_acl(true,
736                                                       addr6->sin6_addr.s6_addr,                                                 addr6->sin6_addr.s6_addr,
737                                                       addr6->sin6_port);                                                 addr6->sin6_port);
738                  break;                  break;
739          case AF_INET:          case AF_INET:
740                  addr4 = (struct sockaddr_in *) addr;                  addr4 = (struct sockaddr_in *) addr;
741                  error = ccs_check_network_accept_acl(false,                  error = ccs_network_accept_acl(false,
742                                                       (u8 *) &addr4->sin_addr,                                                 (u8 *) &addr4->sin_addr,
743                                                       addr4->sin_port);                                                 addr4->sin_port);
744                  break;                  break;
745          }          }
746          return error;          return error;
747  }  }
748    
749  /* Check permission for sending a datagram via a UDP or RAW socket. */  /* Check permission for sending a datagram via a UDP or RAW socket. */
750  int ccs_socket_sendmsg_permission(struct socket *sock, struct sockaddr *addr,  static int __ccs_socket_sendmsg_permission(struct socket *sock,
751                                    int addr_len)                                             struct msghdr *msg, int size)
752  {  {
753            struct sockaddr *addr = (struct sockaddr *) msg->msg_name;
754            const int addr_len = msg->msg_namelen;
755          int error = 0;          int error = 0;
756          const int type = sock->type;          const int type = sock->type;
757          /* Nothing to do if I am a kernel service. */          /* Nothing to do if I am a kernel service. */
# Line 770  int ccs_socket_sendmsg_permission(struct Line 771  int ccs_socket_sendmsg_permission(struct
771                          port = addr6->sin6_port;                          port = addr6->sin6_port;
772                  else                  else
773                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
774                  error = ccs_check_network_sendmsg_acl(true, type,                  error = ccs_network_sendmsg_acl(true, type,
775                                                        addr6->sin6_addr.s6_addr,                                                  addr6->sin6_addr.s6_addr,
776                                                        port);                                                  port);
777                  break;                  break;
778          case AF_INET:          case AF_INET:
779                  if (addr_len < sizeof(struct sockaddr_in))                  if (addr_len < sizeof(struct sockaddr_in))
# Line 782  int ccs_socket_sendmsg_permission(struct Line 783  int ccs_socket_sendmsg_permission(struct
783                          port = addr4->sin_port;                          port = addr4->sin_port;
784                  else                  else
785                          port = htons(sock->sk->sk_protocol);                          port = htons(sock->sk->sk_protocol);
786                  error = ccs_check_network_sendmsg_acl(false, type,                  error = ccs_network_sendmsg_acl(false, type,
787                                                        (u8 *) &addr4->sin_addr,                                                  (u8 *) &addr4->sin_addr, port);
                                                       port);  
788                  break;                  break;
789          }          }
790          return error;          return error;
# Line 792  int ccs_socket_sendmsg_permission(struct Line 792  int ccs_socket_sendmsg_permission(struct
792    
793  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
794  #if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5  #if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5
795    #if !defined(AX_MAJOR) || AX_MAJOR != 3 || !defined(AX_MINOR) || AX_MINOR < 2
796    
797  static inline struct iphdr *ip_hdr(const struct sk_buff *skb)  static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
798  {  {
# Line 810  static inline struct ipv6hdr *ipv6_hdr(c Line 811  static inline struct ipv6hdr *ipv6_hdr(c
811    
812  #endif  #endif
813  #endif  #endif
814    #endif
815    
816  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12)
817  static void skb_kill_datagram(struct sock *sk, struct sk_buff *skb,  static void skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
# Line 854  static void skb_kill_datagram(struct soc Line 856  static void skb_kill_datagram(struct soc
856   *   *
857   * Currently, the LSM hook for this purpose is not provided.   * Currently, the LSM hook for this purpose is not provided.
858   */   */
859  int ccs_socket_recvmsg_permission(struct sock *sk, struct sk_buff *skb,  static int __ccs_socket_recvmsg_permission(struct sock *sk,
860                                    const unsigned int flags)                                             struct sk_buff *skb,
861                                               const unsigned int flags)
862  {  {
863          int error = 0;          int error = 0;
864          const unsigned int type = sk->sk_type;          const unsigned int type = sk->sk_type;
# Line 882  int ccs_socket_recvmsg_permission(struct Line 885  int ccs_socket_recvmsg_permission(struct
885                          ipv6_addr_copy(&sin6, &ipv6_hdr(skb)->saddr);                          ipv6_addr_copy(&sin6, &ipv6_hdr(skb)->saddr);
886                          port = htons(sk->sk_protocol);                          port = htons(sk->sk_protocol);
887                  }                  }
888                  error = ccs_check_network_recvmsg_acl(true, type,                  error = ccs_network_recvmsg_acl(true, type,
889                                                        (u8 *) &sin6, port);                                                  (u8 *) &sin6, port);
890                  break;                  break;
891          case PF_INET:          case PF_INET:
892                  if (type == SOCK_DGRAM) { /* UDP IPv4 */                  if (type == SOCK_DGRAM) { /* UDP IPv4 */
# Line 893  int ccs_socket_recvmsg_permission(struct Line 896  int ccs_socket_recvmsg_permission(struct
896                          sin4.s_addr = ip_hdr(skb)->saddr;                          sin4.s_addr = ip_hdr(skb)->saddr;
897                          port = htons(sk->sk_protocol);                          port = htons(sk->sk_protocol);
898                  }                  }
899                  error = ccs_check_network_recvmsg_acl(false, type,                  error = ccs_network_recvmsg_acl(false, type,
900                                                        (u8 *) &sin4, port);                                                  (u8 *) &sin4, port);
901                  break;                  break;
902          }          }
903          if (!error)          if (!error)
# Line 917  int ccs_socket_recvmsg_permission(struct Line 920  int ccs_socket_recvmsg_permission(struct
920          /* Hope less harmful than -EPERM. */          /* Hope less harmful than -EPERM. */
921          return -ENOMEM;          return -ENOMEM;
922  }  }
923  EXPORT_SYMBOL(ccs_socket_recvmsg_permission);  
924    void __init ccs_network_init(void)
925    {
926            ccsecurity_ops.socket_create_permission =
927                    __ccs_socket_create_permission;
928            ccsecurity_ops.socket_listen_permission =
929                    __ccs_socket_listen_permission;
930            ccsecurity_ops.socket_connect_permission =
931                    __ccs_socket_connect_permission;
932            ccsecurity_ops.socket_bind_permission = __ccs_socket_bind_permission;
933            ccsecurity_ops.socket_accept_permission =
934                    __ccs_socket_accept_permission;
935            ccsecurity_ops.socket_sendmsg_permission =
936                    __ccs_socket_sendmsg_permission;
937            ccsecurity_ops.socket_recvmsg_permission =
938                    __ccs_socket_recvmsg_permission;
939    }

Legend:
Removed from v.2918  
changed lines
  Added in v.3512

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