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

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 3915 by kumaneko, Mon Aug 23 02:55:04 2010 UTC revision 3916 by kumaneko, Mon Aug 23 08:15:53 2010 UTC
# Line 15  Line 15 
15  #include <linux/in.h>  #include <linux/in.h>
16  #include <linux/in6.h>  #include <linux/in6.h>
17  #include <linux/un.h>  #include <linux/un.h>
18    #include <net/sock.h>
19    #include <net/af_unix.h>
20  #include <net/ip.h>  #include <net/ip.h>
21  #include <net/ipv6.h>  #include <net/ipv6.h>
22  #include <net/udp.h>  #include <net/udp.h>
# Line 301  static int ccs_inet_entry(const struct c Line 303  static int ccs_inet_entry(const struct c
303          int error = 0;          int error = 0;
304          const u8 type = ccs_inet2mac[address->protocol][address->operation];          const u8 type = ccs_inet2mac[address->protocol][address->operation];
305          if (type && ccs_init_request_info(&r, type) != CCS_CONFIG_DISABLED) {          if (type && ccs_init_request_info(&r, type) != CCS_CONFIG_DISABLED) {
306                    struct task_struct * const task = current;
307                    const bool no_sleep = address->operation == CCS_NETWORK_ACCEPT
308                            || address->operation == CCS_NETWORK_RECV;
309                  r.param_type = CCS_TYPE_INET_ACL;                  r.param_type = CCS_TYPE_INET_ACL;
310                  r.param.inet_network.protocol = address->protocol;                  r.param.inet_network.protocol = address->protocol;
311                  r.param.inet_network.operation = address->operation;                  r.param.inet_network.operation = address->operation;
# Line 309  static int ccs_inet_entry(const struct c Line 314  static int ccs_inet_entry(const struct c
314                  r.param.inet_network.port = ntohs(address->inet.port);                  r.param.inet_network.port = ntohs(address->inet.port);
315                  /* use host byte order to allow u32 comparison than memcmp().*/                  /* use host byte order to allow u32 comparison than memcmp().*/
316                  r.param.inet_network.ip = ntohl(*address->inet.address);                  r.param.inet_network.ip = ntohl(*address->inet.address);
317                    if (no_sleep)
318                            task->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
319                  do {                  do {
320                          ccs_check_acl(&r, ccs_check_inet_acl);                          ccs_check_acl(&r, ccs_check_inet_acl);
321                          error = ccs_audit_inet_log(&r);                          error = ccs_audit_inet_log(&r);
322                  } while (error == CCS_RETRY_REQUEST);                  } while (error == CCS_RETRY_REQUEST);
323                    if (no_sleep)
324                            task->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
325          }          }
326          ccs_read_unlock(idx);          ccs_read_unlock(idx);
327          return error;          return error;
# Line 341  static int ccs_unix_entry(const struct c Line 350  static int ccs_unix_entry(const struct c
350                                            address->unix0.addr_len                                            address->unix0.addr_len
351                                            - sizeof(sa_family_t));                                            - sizeof(sa_family_t));
352                  if (buf) {                  if (buf) {
353                            struct task_struct * const task = current;
354                            const bool no_sleep =
355                                    address->operation == CCS_NETWORK_ACCEPT ||
356                                    address->operation == CCS_NETWORK_RECV;
357                          struct ccs_path_info addr;                          struct ccs_path_info addr;
358                          addr.name = buf;                          addr.name = buf;
359                          ccs_fill_path_info(&addr);                          ccs_fill_path_info(&addr);
# Line 348  static int ccs_unix_entry(const struct c Line 361  static int ccs_unix_entry(const struct c
361                          r.param.unix_network.protocol = address->protocol;                          r.param.unix_network.protocol = address->protocol;
362                          r.param.unix_network.operation = address->operation;                          r.param.unix_network.operation = address->operation;
363                          r.param.unix_network.address = &addr;                          r.param.unix_network.address = &addr;
364                            if (no_sleep)
365                                    task->ccs_flags |=
366                                            CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
367                    
368                          do {                          do {
369                                  ccs_check_acl(&r, ccs_check_unix_acl);                                  ccs_check_acl(&r, ccs_check_unix_acl);
370                                  error = ccs_audit_unix_log(&r);                                  error = ccs_audit_unix_log(&r);
371                          } while (error == CCS_RETRY_REQUEST);                          } while (error == CCS_RETRY_REQUEST);
372                            if (no_sleep)
373                                    task->ccs_flags &=
374                                            ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
375                          kfree(buf);                          kfree(buf);
376                  } else                  } else
377                          error = -ENOMEM;                          error = -ENOMEM;
# Line 363  static int ccs_unix_entry(const struct c Line 383  static int ccs_unix_entry(const struct c
383  static bool ccs_same_inet_acl(const struct ccs_acl_info *a,  static bool ccs_same_inet_acl(const struct ccs_acl_info *a,
384                                        const struct ccs_acl_info *b)                                        const struct ccs_acl_info *b)
385  {  {
386          const struct ccs_inet_acl *p1 = container_of(a, typeof(*p1),          const struct ccs_inet_acl *p1 = container_of(a, typeof(*p1), head);
387                                                               head);          const struct ccs_inet_acl *p2 = container_of(b, typeof(*p2), head);
         const struct ccs_inet_acl *p2 = container_of(b, typeof(*p2),  
                                                              head);  
388          return ccs_same_acl_head(&p1->head, &p2->head)          return ccs_same_acl_head(&p1->head, &p2->head)
389                  && p1->protocol == p2->protocol                  && p1->protocol == p2->protocol
390                  && p1->address_type == p2->address_type &&                  && p1->address_type == p2->address_type &&
# Line 381  static bool ccs_same_inet_acl(const stru Line 399  static bool ccs_same_inet_acl(const stru
399  static bool ccs_same_unix_acl(const struct ccs_acl_info *a,  static bool ccs_same_unix_acl(const struct ccs_acl_info *a,
400                                        const struct ccs_acl_info *b)                                        const struct ccs_acl_info *b)
401  {  {
402          const struct ccs_unix_acl *p1 = container_of(a, typeof(*p1),          const struct ccs_unix_acl *p1 = container_of(a, typeof(*p1), head);
403                                                               head);          const struct ccs_unix_acl *p2 = container_of(b, typeof(*p2), head);
         const struct ccs_unix_acl *p2 = container_of(b, typeof(*p2),  
                                                              head);  
404          return ccs_same_acl_head(&p1->head, &p2->head) &&          return ccs_same_acl_head(&p1->head, &p2->head) &&
405                  p1->protocol == p2->protocol &&                  p1->protocol == p2->protocol &&
406                  ccs_same_name_union(&p1->name, &p2->name);                  ccs_same_name_union(&p1->name, &p2->name);
407  }  }
408    
409  static bool ccs_merge_inet_acl(struct ccs_acl_info *a,  static bool ccs_merge_inet_acl(struct ccs_acl_info *a, struct ccs_acl_info *b,
410                                         struct ccs_acl_info *b,                                 const bool is_delete)
                                        const bool is_delete)  
411  {  {
412          u8 * const a_perm = &container_of(a, struct ccs_inet_acl, head)          u8 * const a_perm = &container_of(a, struct ccs_inet_acl, head)->perm;
                 ->perm;  
413          u8 perm = *a_perm;          u8 perm = *a_perm;
414          const u8 b_perm = container_of(b, struct ccs_inet_acl, head)          const u8 b_perm = container_of(b, struct ccs_inet_acl, head)->perm;
                 ->perm;  
415          if (is_delete)          if (is_delete)
416                  perm &= ~b_perm;                  perm &= ~b_perm;
417          else          else
# Line 407  static bool ccs_merge_inet_acl(struct cc Line 420  static bool ccs_merge_inet_acl(struct cc
420          return !perm;          return !perm;
421  }  }
422    
423  static bool ccs_merge_unix_acl(struct ccs_acl_info *a,  static bool ccs_merge_unix_acl(struct ccs_acl_info *a, struct ccs_acl_info *b,
424                                         struct ccs_acl_info *b,                                 const bool is_delete)
                                        const bool is_delete)  
425  {  {
426          u8 * const a_perm = &container_of(a, struct ccs_unix_acl, head)          u8 * const a_perm = &container_of(a, struct ccs_unix_acl, head)->perm;
                 ->perm;  
427          u8 perm = *a_perm;          u8 perm = *a_perm;
428          const u8 b_perm = container_of(b, struct ccs_unix_acl, head)          const u8 b_perm = container_of(b, struct ccs_unix_acl, head)->perm;
                 ->perm;  
429          if (is_delete)          if (is_delete)
430                  perm &= ~b_perm;                  perm &= ~b_perm;
431          else          else
# Line 449  int ccs_write_inet_network(char *data, s Line 459  int ccs_write_inet_network(char *data, s
459          char *w[4];          char *w[4];
460          if (!ccs_tokenize(data, w, sizeof(w)) || !w[3][0])          if (!ccs_tokenize(data, w, sizeof(w)) || !w[3][0])
461                  return -EINVAL;                  return -EINVAL;
462          for (e.protocol = 0; e.protocol < CCS_MAX_INET_PROTOCOL;          for (e.protocol = 0; e.protocol < CCS_MAX_INET_PROTOCOL; e.protocol++)
              e.protocol++)  
463                  if (!strcmp(w[0], ccs_inet_keyword[e.protocol]))                  if (!strcmp(w[0], ccs_inet_keyword[e.protocol]))
464                          break;                          break;
465          for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)          for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
# Line 521  int ccs_write_unix_network(char *data, s Line 530  int ccs_write_unix_network(char *data, s
530          char *w[3];          char *w[3];
531          if (!ccs_tokenize(data, w, sizeof(w)) || !w[2][0])          if (!ccs_tokenize(data, w, sizeof(w)) || !w[2][0])
532                  return -EINVAL;                  return -EINVAL;
533          for (e.protocol = 0; e.protocol < CCS_MAX_UNIX_PROTOCOL;          for (e.protocol = 0; e.protocol < CCS_MAX_UNIX_PROTOCOL; e.protocol++)
              e.protocol++)  
534                  if (!strcmp(w[0], ccs_unix_keyword[e.protocol]))                  if (!strcmp(w[0], ccs_unix_keyword[e.protocol]))
535                          break;                          break;
536          for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)          for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
# Line 546  void __init ccs_network_init(void) Line 554  void __init ccs_network_init(void)
554    
555  #else  #else
556    
557  static bool ccs_check_inet_address(const struct sockaddr *addr,  static int ccs_check_inet_address(const struct sockaddr *addr,
558                                     const unsigned int addr_len,                                    const unsigned int addr_len, const u16 port,
559                                     struct ccs_inet_addr_info *address)                                    struct ccs_addr_info *address)
560  {  {
561            struct ccs_inet_addr_info *i = &address->inet;
562          switch (addr->sa_family) {          switch (addr->sa_family) {
563          case AF_INET6:          case AF_INET6:
564                  if (addr_len < SIN6_LEN_RFC2133)                  if (addr_len < SIN6_LEN_RFC2133)
565                          goto skip;                          goto skip;
566                  address->is_ipv6 = true;                  i->is_ipv6 = true;
567                  address->address = (u32 *)                  i->address = (u32 *)
568                          ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr;                          ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr;
569                  address->port = ((struct sockaddr_in6 *) addr)->sin6_port;                  i->port = ((struct sockaddr_in6 *) addr)->sin6_port;
570                  break;                  break;
571          case AF_INET:          case AF_INET:
572                  if (addr_len < sizeof(struct sockaddr_in))                  if (addr_len < sizeof(struct sockaddr_in))
573                          goto skip;                          goto skip;
574                  address->is_ipv6 = false;                  i->is_ipv6 = false;
575                  address->address = (u32 *)                  i->address = (u32 *) &((struct sockaddr_in *) addr)->sin_addr;
576                          &((struct sockaddr_in *) addr)->sin_addr;                  i->port = ((struct sockaddr_in *) addr)->sin_port;
                 address->port = ((struct sockaddr_in *) addr)->sin_port;  
577                  break;                  break;
578          default:          default:
579                  goto skip;                  goto skip;
580          }          }
581          return true;          if (address->protocol == CCS_NETWORK_INET_RAW_PROTOCOL)
582                    i->port = htons(port);
583            return ccs_inet_entry(address);
584   skip:   skip:
585          return false;          return 0;
586  }  }
587    
588  static bool ccs_check_unix_address(struct sockaddr *addr,  static int ccs_unix_entry(const struct ccs_addr_info *address);
589                                     const unsigned int addr_len,  
590                                     struct ccs_unix_addr_info *address)  static int ccs_check_unix_address(struct sockaddr *addr,
591                                      const unsigned int addr_len,
592                                      struct ccs_addr_info *address)
593  {  {
594            struct ccs_unix_addr_info *u = &address->unix0;
595          if (addr->sa_family != AF_UNIX)          if (addr->sa_family != AF_UNIX)
596                  return false;                  return 0;
597          address->addr = ((struct sockaddr_un *) addr)->sun_path;          u->addr = ((struct sockaddr_un *) addr)->sun_path;
598          address->addr_len = addr_len;          u->addr_len = addr_len;
599          /*          /*
600           * Terminate pathname with '\0' like unix_mkname() does.           * Terminate pathname with '\0' like unix_mkname() does.
601           * This is needed because pathname was copied by move_addr_to_kernel()           * This is needed because pathname was copied by move_addr_to_kernel()
602           * but not yet terminated by unix_mkname().           * but not yet terminated by unix_mkname().
603           */           */
604          if (address->addr[0] && addr_len > sizeof(short) &&          if (u->addr[0] && addr_len > sizeof(short) &&
605              addr_len <= sizeof(struct sockaddr_un))              addr_len <= sizeof(struct sockaddr_un))
606                  ((char *) addr)[addr_len] = '\0';                  ((char *) u->addr)[addr_len] = '\0';
607          return true;          return ccs_unix_entry(address);
608  }  }
609    
610  static bool ccs_kernel_service(void)  static bool ccs_kernel_service(void)
# Line 600  static bool ccs_kernel_service(void) Line 613  static bool ccs_kernel_service(void)
613          return segment_eq(get_fs(), KERNEL_DS);          return segment_eq(get_fs(), KERNEL_DS);
614  }  }
615    
616  static u8 ccs_sock_family(struct socket *sock)  static u8 ccs_sock_family(struct sock *sk)
617  {  {
618          if (ccs_kernel_service())          if (ccs_kernel_service())
619                  return 0;                  return 0;
620          switch (sock->sk->sk_family) {          switch (sk->sk_family) {
621          case PF_INET:          case PF_INET:
622          case PF_INET6:          case PF_INET6:
623                  return 1;                  return 1;
# Line 630  static int __ccs_socket_create_permissio Line 643  static int __ccs_socket_create_permissio
643  /* Check permission for listening a socket. */  /* Check permission for listening a socket. */
644  static int __ccs_socket_listen_permission(struct socket *sock)  static int __ccs_socket_listen_permission(struct socket *sock)
645  {  {
         struct sockaddr_storage addr;  
         int error;  
         int addr_len;  
646          struct ccs_addr_info address;          struct ccs_addr_info address;
647          const u8 family = ccs_sock_family(sock);          const u8 family = ccs_sock_family(sock->sk);
648          const unsigned int type = sock->type;          const unsigned int type = sock->type;
649            struct sockaddr_storage addr;
650            int addr_len;
651          if (!family || (type != SOCK_STREAM && type != SOCK_SEQPACKET))          if (!family || (type != SOCK_STREAM && type != SOCK_SEQPACKET))
652                  return 0;                  return 0;
653          error = sock->ops->getname(sock, (struct sockaddr *) &addr, &addr_len,          {
654                                     0);                  const int error = sock->ops->getname(sock, (struct sockaddr *)
655          if (error)                                                       &addr, &addr_len, 0);
656                  return error;                  if (error)
657                            return error;
658            }
659          address.operation = CCS_NETWORK_LISTEN;          address.operation = CCS_NETWORK_LISTEN;
660          if (family == 2) {          if (family == 2) {
661                  if (type == SOCK_STREAM)                  if (type == SOCK_STREAM)
662                          address.protocol = CCS_NETWORK_UNIX_STREAM_PROTOCOL;                          address.protocol = CCS_NETWORK_UNIX_STREAM_PROTOCOL;
663                  else                  else
664                          address.protocol = CCS_NETWORK_UNIX_SEQPACKET_PROTOCOL;                          address.protocol = CCS_NETWORK_UNIX_SEQPACKET_PROTOCOL;
665                  if (ccs_check_unix_address((struct sockaddr *) &addr, addr_len,                  return ccs_check_unix_address((struct sockaddr *) &addr,
666                                             &address.unix0))                                                addr_len, &address);
                         error = ccs_unix_entry(&address);  
         } else {  
                 address.protocol = CCS_NETWORK_INET_TCP_PROTOCOL;  
                 if (ccs_check_inet_address((struct sockaddr *) &addr, addr_len,  
                                            &address.inet))  
                         error = ccs_inet_entry(&address);  
667          }          }
668          return error;          address.protocol = CCS_NETWORK_INET_TCP_PROTOCOL;
669            return ccs_check_inet_address((struct sockaddr *) &addr, addr_len, 0,
670                                          &address);
671  }  }
672    
673  /* Check permission for setting the remote address of a socket. */  /* Check permission for setting the remote address of a socket. */
674  static int __ccs_socket_connect_permission(struct socket *sock,  static int __ccs_socket_connect_permission(struct socket *sock,
675                                             struct sockaddr *addr, int addr_len)                                             struct sockaddr *addr, int addr_len)
676  {  {
         int error = 0;  
         const unsigned int type = sock->type;  
677          struct ccs_addr_info address;          struct ccs_addr_info address;
678          const u8 family = ccs_sock_family(sock);          const u8 family = ccs_sock_family(sock->sk);
679            const unsigned int type = sock->type;
680          if (!family)          if (!family)
681                  return 0;                  return 0;
682          address.operation = CCS_NETWORK_CONNECT;          address.operation = CCS_NETWORK_CONNECT;
# Line 686  static int __ccs_socket_connect_permissi Line 695  static int __ccs_socket_connect_permissi
695                  default:                  default:
696                          return 0;                          return 0;
697                  }                  }
698                  if (ccs_check_unix_address(addr, addr_len, &address.unix0))                  return ccs_check_unix_address(addr, addr_len, &address);
                         error = ccs_unix_entry(&address);  
         } else {  
                 switch (type) {  
                 case SOCK_STREAM:  
                         address.protocol = CCS_NETWORK_INET_TCP_PROTOCOL;  
                         break;  
                 case SOCK_DGRAM:  
                         address.protocol = CCS_NETWORK_INET_UDP_PROTOCOL;  
                         address.operation = CCS_NETWORK_SEND;  
                         break;  
                 case SOCK_RAW:  
                         address.protocol = CCS_NETWORK_INET_RAW_PROTOCOL;  
                         address.operation = CCS_NETWORK_SEND;  
                         break;  
                 default:  
                         return 0;  
                 }  
                 if (ccs_check_inet_address(addr, addr_len, &address.inet)) {  
                         if (type == SOCK_RAW)  
                                 address.inet.port = htons(sock->sk->sk_protocol);  
                         error = ccs_inet_entry(&address);  
                 }  
699          }          }
700          return error;          switch (type) {
701            case SOCK_STREAM:
702                    address.protocol = CCS_NETWORK_INET_TCP_PROTOCOL;
703                    break;
704            case SOCK_DGRAM:
705                    address.protocol = CCS_NETWORK_INET_UDP_PROTOCOL;
706                    address.operation = CCS_NETWORK_SEND;
707                    break;
708            case SOCK_RAW:
709                    address.protocol = CCS_NETWORK_INET_RAW_PROTOCOL;
710                    address.operation = CCS_NETWORK_SEND;
711                    break;
712            default:
713                    return 0;
714            }
715            return ccs_check_inet_address(addr, addr_len, sock->sk->sk_protocol,
716                                          &address);
717  }  }
718    
719  /* Check permission for setting the local address of a socket. */  /* Check permission for setting the local address of a socket. */
720  static int __ccs_socket_bind_permission(struct socket *sock,  static int __ccs_socket_bind_permission(struct socket *sock,
721                                          struct sockaddr *addr, int addr_len)                                          struct sockaddr *addr, int addr_len)
722  {  {
         int error = 0;  
         const unsigned int type = sock->type;  
723          struct ccs_addr_info address;          struct ccs_addr_info address;
724          const u8 family = ccs_sock_family(sock);          const u8 family = ccs_sock_family(sock->sk);
725            const unsigned int type = sock->type;
726          if (!family)          if (!family)
727                  return 0;                  return 0;
728          address.operation = CCS_NETWORK_BIND;          address.operation = CCS_NETWORK_BIND;
# Line 738  static int __ccs_socket_bind_permission( Line 740  static int __ccs_socket_bind_permission(
740                  default:                  default:
741                          return 0;                          return 0;
742                  }                  }
743                  if (ccs_check_unix_address(addr, addr_len, &address.unix0))                  return ccs_check_unix_address(addr, addr_len, &address);
                         error = ccs_unix_entry(&address);  
         } else {  
                 switch (type) {  
                 case SOCK_STREAM:  
                         address.protocol = CCS_NETWORK_INET_TCP_PROTOCOL;  
                         break;  
                 case SOCK_DGRAM:  
                         address.protocol = CCS_NETWORK_INET_UDP_PROTOCOL;  
                         break;  
                 case SOCK_RAW:  
                         address.protocol = CCS_NETWORK_INET_RAW_PROTOCOL;  
                         break;  
                 default:  
                         return 0;  
                 }  
                 if (ccs_check_inet_address(addr, addr_len, &address.inet)) {  
                         if (type == SOCK_RAW)  
                                 address.inet.port = htons(sock->sk->sk_protocol);  
                         error = ccs_inet_entry(&address);  
                 }  
744          }          }
745          return error;          switch (type) {
746            case SOCK_STREAM:
747                    address.protocol = CCS_NETWORK_INET_TCP_PROTOCOL;
748                    break;
749            case SOCK_DGRAM:
750                    address.protocol = CCS_NETWORK_INET_UDP_PROTOCOL;
751                    break;
752            case SOCK_RAW:
753                    address.protocol = CCS_NETWORK_INET_RAW_PROTOCOL;
754                    break;
755            default:
756                    return 0;
757            }
758            return ccs_check_inet_address(addr, addr_len, sock->sk->sk_protocol,
759                                          &address);
760  }  }
761    
762  /* Check permission for sending a datagram via a UDP or RAW socket. */  /* Check permission for sending a datagram via a UDP or RAW socket. */
763  static int __ccs_socket_sendmsg_permission(struct socket *sock,  static int __ccs_socket_sendmsg_permission(struct socket *sock,
764                                             struct msghdr *msg, int size)                                             struct msghdr *msg, int size)
765  {  {
         int error = 0;  
         const int type = sock->type;  
766          struct ccs_addr_info address;          struct ccs_addr_info address;
767          const u8 family = ccs_sock_family(sock);          const u8 family = ccs_sock_family(sock->sk);
768            const unsigned int type = sock->type;
769          if (!msg->msg_name || !family)          if (!msg->msg_name || !family)
770                  return 0;                  return 0;
771          address.operation = CCS_NETWORK_SEND;          address.operation = CCS_NETWORK_SEND;
# Line 778  static int __ccs_socket_sendmsg_permissi Line 773  static int __ccs_socket_sendmsg_permissi
773                  if (type != SOCK_DGRAM)                  if (type != SOCK_DGRAM)
774                          return 0;                          return 0;
775                  address.protocol = CCS_NETWORK_UNIX_DGRAM_PROTOCOL;                  address.protocol = CCS_NETWORK_UNIX_DGRAM_PROTOCOL;
776                  if (ccs_check_unix_address((struct sockaddr *) msg->msg_name,                  return ccs_check_unix_address((struct sockaddr *)
777                                             msg->msg_namelen, &address.unix0))                                                msg->msg_name, msg->msg_namelen,
778                          error = ccs_unix_entry(&address);                                                &address);
         } else {  
                 switch (type) {  
                 case SOCK_DGRAM:  
                         address.protocol = CCS_NETWORK_INET_UDP_PROTOCOL;  
                         break;  
                 case SOCK_RAW:  
                         address.protocol = CCS_NETWORK_INET_RAW_PROTOCOL;  
                         break;  
                 default:  
                         return 0;  
                 }  
                 if (ccs_check_inet_address((struct sockaddr *) msg->msg_name,  
                                            msg->msg_namelen, &address.inet)) {  
                         if (type == SOCK_RAW)  
                                 address.inet.port = htons(sock->sk->sk_protocol);  
                         error = ccs_inet_entry(&address);  
                 }  
779          }          }
780          return error;          switch (type) {
781            case SOCK_DGRAM:
782                    address.protocol = CCS_NETWORK_INET_UDP_PROTOCOL;
783                    break;
784            case SOCK_RAW:
785                    address.protocol = CCS_NETWORK_INET_RAW_PROTOCOL;
786                    break;
787            default:
788                    return 0;
789            }
790            return ccs_check_inet_address((struct sockaddr *) msg->msg_name,
791                                          msg->msg_namelen, sock->sk->sk_protocol,
792                                          &address);
793  }  }
794    
795  /* Check permission for accepting a socket. */  /* Check permission for accepting a socket. */
796  static int __ccs_socket_post_accept_permission(struct socket *sock,  static int __ccs_socket_post_accept_permission(struct socket *sock,
797                                                 struct socket *newsock)                                                 struct socket *newsock)
798  {  {
         struct sockaddr_storage addr;  
         struct task_struct * const task = current;  
         int error;  
         int addr_len;  
         const u8 family = ccs_sock_family(sock);  
799          struct ccs_addr_info address;          struct ccs_addr_info address;
800            const u8 family = ccs_sock_family(sock->sk);
801          const unsigned int type = sock->type;          const unsigned int type = sock->type;
802            struct sockaddr_storage addr;
803            int addr_len;
804          if (!family || (type != SOCK_STREAM && type != SOCK_SEQPACKET))          if (!family || (type != SOCK_STREAM && type != SOCK_SEQPACKET))
805                  return 0;                  return 0;
806          error = newsock->ops->getname(newsock, (struct sockaddr *) &addr,          {
807                                        &addr_len, 2);                  const int error = newsock->ops->getname(newsock,
808          if (error)                                                          (struct sockaddr *)
809                  return error;                                                          &addr, &addr_len, 2);
810                    if (error)
811                            return error;
812            }
813          address.operation = CCS_NETWORK_ACCEPT;          address.operation = CCS_NETWORK_ACCEPT;
         task->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;  
814          if (family == 2) {          if (family == 2) {
815                  if (type == SOCK_STREAM)                  if (type == SOCK_STREAM)
816                          address.protocol = CCS_NETWORK_UNIX_STREAM_PROTOCOL;                          address.protocol = CCS_NETWORK_UNIX_STREAM_PROTOCOL;
817                  else                  else
818                          address.protocol = CCS_NETWORK_UNIX_SEQPACKET_PROTOCOL;                          address.protocol = CCS_NETWORK_UNIX_SEQPACKET_PROTOCOL;
819                  if (ccs_check_unix_address((struct sockaddr *) &addr, addr_len,                  return ccs_check_unix_address((struct sockaddr *) &addr,
820                                             &address.unix0))                                                addr_len, &address);
                         error = ccs_unix_entry(&address);  
         } else {  
                 address.protocol = CCS_NETWORK_INET_TCP_PROTOCOL;  
                 if (ccs_check_inet_address((struct sockaddr *) &addr, addr_len,  
                                            &address.inet))  
                         error = ccs_inet_entry(&address);  
821          }          }
822          task->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          address.protocol = CCS_NETWORK_INET_TCP_PROTOCOL;
823          return error;          return ccs_check_inet_address((struct sockaddr *) &addr, addr_len, 0,
824                                          &address);
825  }  }
826    
827  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
# Line 866  static inline struct ipv6hdr *ipv6_hdr(c Line 851  static inline struct ipv6hdr *ipv6_hdr(c
851  static int __ccs_socket_post_recvmsg_permission(struct sock *sk,  static int __ccs_socket_post_recvmsg_permission(struct sock *sk,
852                                                  struct sk_buff *skb)                                                  struct sk_buff *skb)
853  {  {
         struct task_struct * const task = current;  
         int error = 0;  
         const unsigned int type = sk->sk_type;  
854          struct ccs_addr_info address;          struct ccs_addr_info address;
855          union {          const u8 family = ccs_sock_family(sk);
856                  struct in6_addr sin6;          const unsigned int type = sk->sk_type;
857                  struct in_addr sin4;          struct sockaddr_storage addr;
858          } ip_address;          if (!family)
859                    return 0;
860          switch (type) {          switch (type) {
861          case SOCK_DGRAM:          case SOCK_DGRAM:
862                  address.protocol = CCS_NETWORK_INET_UDP_PROTOCOL;                  if (family == 2)
863                            address.protocol = CCS_NETWORK_UNIX_DGRAM_PROTOCOL;
864                    else
865                            address.protocol = CCS_NETWORK_INET_UDP_PROTOCOL;
866                  break;                  break;
867          case SOCK_RAW:          case SOCK_RAW:
868                  address.protocol = CCS_NETWORK_INET_RAW_PROTOCOL;                  address.protocol = CCS_NETWORK_INET_RAW_PROTOCOL;
# Line 884  static int __ccs_socket_post_recvmsg_per Line 870  static int __ccs_socket_post_recvmsg_per
870          default:          default:
871                  return 0;                  return 0;
872          }          }
873          if (ccs_kernel_service())          address.operation = CCS_NETWORK_RECV;
874                  return 0;          if (family == 2) {
875          switch (sk->sk_family) {  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
876          case PF_INET6:                  struct unix_address *u = unix_sk(skb->sk)->addr;
877                  address.inet.is_ipv6 = true;  #else
878                  if (type == SOCK_DGRAM && skb->protocol == htons(ETH_P_IP))                  struct unix_address *u = skb->sk->protinfo.af_unix.addr;
879                          ipv6_addr_set(&ip_address.sin6, 0, 0, htonl(0xffff),  #endif
880                                        ip_hdr(skb)->saddr);                  unsigned int addr_len;
881                    if (!u)
882                            return 0;
883                    addr_len = u->len;
884                    if (addr_len >= sizeof(addr))
885                            return 0;
886                    memcpy(&addr, u->name, addr_len);
887                    return ccs_check_unix_address((struct sockaddr *) &addr,
888                                                  addr_len, &address);
889            } else {
890                    struct in6_addr *sin6 = (struct in6_addr *) &addr;
891                    struct in_addr *sin4 = (struct in_addr *) &addr;
892                    switch (sk->sk_family) {
893                    case PF_INET6:
894                            address.inet.is_ipv6 = true;
895                            if (type == SOCK_DGRAM &&
896                                skb->protocol == htons(ETH_P_IP))
897                                    ipv6_addr_set(sin6, 0, 0, htonl(0xffff),
898                                                  ip_hdr(skb)->saddr);
899                            else
900                                    ipv6_addr_copy(sin6, &ipv6_hdr(skb)->saddr);
901                            break;
902                    case PF_INET:
903                            address.inet.is_ipv6 = false;
904                            sin4->s_addr = ip_hdr(skb)->saddr;
905                            break;
906                    default:
907                            return 0;
908                    }
909                    address.inet.address = (u32 *) &addr;
910                    if (type == SOCK_DGRAM)
911                            address.inet.port = udp_hdr(skb)->source;
912                  else                  else
913                          ipv6_addr_copy(&ip_address.sin6,                          address.inet.port = htons(sk->sk_protocol);
914                                         &ipv6_hdr(skb)->saddr);                  return ccs_inet_entry(&address);
                 break;  
         case PF_INET:  
                 address.inet.is_ipv6 = false;  
                 ip_address.sin4.s_addr = ip_hdr(skb)->saddr;  
                 break;  
         default:  
                 goto skip;  
915          }          }
         address.inet.address = (u32 *) &ip_address;  
         if (type == SOCK_DGRAM)  
                 address.inet.port = udp_hdr(skb)->source;  
         else  
                 address.inet.port = htons(sk->sk_protocol);  
         address.operation = CCS_NETWORK_RECV;  
         task->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;  
         error = ccs_inet_entry(&address);  
         task->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;  
  skip:  
         return error;  
916  }  }
917    
918  void __init ccs_network_init(void)  void __init ccs_network_init(void)

Legend:
Removed from v.3915  
changed lines
  Added in v.3916

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