Print this page
8541 pfiles does not properly identify PF_KEY or PF_POLICY
Reviewed by: Mike Zeller <mike.zeller@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/ip/keysock.c
          +++ new/usr/src/uts/common/inet/ip/keysock.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
       25 +/*
       26 + * Copyright 2017 Joyent, Inc.
       27 + */
  25   28  
  26   29  #include <sys/param.h>
  27   30  #include <sys/types.h>
  28   31  #include <sys/stream.h>
  29   32  #include <sys/strsubr.h>
  30   33  #include <sys/strsun.h>
  31   34  #include <sys/stropts.h>
  32   35  #include <sys/vnode.h>
  33   36  #include <sys/zone.h>
  34   37  #include <sys/strlog.h>
↓ open down ↓ 850 lines elided ↑ open up ↑
 885  888                  }
 886  889                  mutex_exit(&ks->keysock_lock);
 887  890                  break;
 888  891          default:
 889  892                  errno = EINVAL;
 890  893          }
 891  894          return (errno);
 892  895  }
 893  896  
 894  897  /*
      898 + * Handle STREAMS ioctl copyin for getsockname() for both PF_KEY and
      899 + * PF_POLICY.
      900 + */
      901 +void
      902 +keysock_spdsock_wput_iocdata(queue_t *q, mblk_t *mp, sa_family_t family)
      903 +{
      904 +        mblk_t *mp1;
      905 +        STRUCT_HANDLE(strbuf, sb);
      906 +        /* What size of sockaddr do we need? */
      907 +        const uint_t addrlen = sizeof (struct sockaddr);
      908 +
      909 +        /* We only handle TI_GET{MY,PEER}NAME (get{sock,peer}name()). */
      910 +        switch (((struct iocblk *)mp->b_rptr)->ioc_cmd) {
      911 +        case TI_GETMYNAME:
      912 +        case TI_GETPEERNAME:
      913 +                break;
      914 +        default:
      915 +                freemsg(mp);
      916 +                return;
      917 +        }
      918 +
      919 +        switch (mi_copy_state(q, mp, &mp1)) {
      920 +        case -1:
      921 +                return;
      922 +        case MI_COPY_CASE(MI_COPY_IN, 1):
      923 +                break;
      924 +        case MI_COPY_CASE(MI_COPY_OUT, 1):
      925 +                /*
      926 +                 * The address has been copied out, so now
      927 +                 * copyout the strbuf.
      928 +                 */
      929 +                mi_copyout(q, mp);
      930 +                return;
      931 +        case MI_COPY_CASE(MI_COPY_OUT, 2):
      932 +                /*
      933 +                 * The address and strbuf have been copied out.
      934 +                 * We're done, so just acknowledge the original
      935 +                 * M_IOCTL.
      936 +                 */
      937 +                mi_copy_done(q, mp, 0);
      938 +                return;
      939 +        default:
      940 +                /*
      941 +                 * Something strange has happened, so acknowledge
      942 +                 * the original M_IOCTL with an EPROTO error.
      943 +                 */
      944 +                mi_copy_done(q, mp, EPROTO);
      945 +                return;
      946 +        }
      947 +
      948 +        /*
      949 +         * Now we have the strbuf structure for TI_GET{MY,PEER}NAME. Next we
      950 +         * copyout the requested address and then we'll copyout the strbuf.
      951 +         * Regardless of sockname or peername, we just return a sockaddr with
      952 +         * sa_family set.
      953 +         */
      954 +        STRUCT_SET_HANDLE(sb, ((struct iocblk *)mp->b_rptr)->ioc_flag,
      955 +            (void *)mp1->b_rptr);
      956 +
      957 +        if (STRUCT_FGET(sb, maxlen) < addrlen) {
      958 +                mi_copy_done(q, mp, EINVAL);
      959 +                return;
      960 +        }
      961 +
      962 +        mp1 = mi_copyout_alloc(q, mp, STRUCT_FGETP(sb, buf), addrlen, B_TRUE);
      963 +        if (mp1 == NULL)
      964 +                return;
      965 +
      966 +        STRUCT_FSET(sb, len, addrlen);
      967 +        ((struct sockaddr *)mp1->b_wptr)->sa_family = family;
      968 +        mp1->b_wptr += addrlen;
      969 +        mi_copyout(q, mp);
      970 +}
      971 +
      972 +/*
 895  973   * Handle STREAMS messages.
 896  974   */
 897  975  static void
 898  976  keysock_wput_other(queue_t *q, mblk_t *mp)
 899  977  {
 900  978          struct iocblk *iocp;
 901  979          int error;
 902  980          keysock_t *ks = (keysock_t *)q->q_ptr;
 903  981          keysock_stack_t *keystack = ks->keysock_keystack;
 904  982          cred_t          *cr;
↓ open down ↓ 42 lines elided ↑ open up ↑
 947 1025                          /* Illegal for keysock. */
 948 1026                          freemsg(mp);
 949 1027                          (void) putnextctl1(RD(q), M_ERROR, EPROTO);
 950 1028                          break;
 951 1029                  default:
 952 1030                          /* Not supported by keysock. */
 953 1031                          keysock_err_ack(q, mp, TNOTSUPPORT, 0);
 954 1032                          break;
 955 1033                  }
 956 1034                  return;
     1035 +        case M_IOCDATA:
     1036 +                keysock_spdsock_wput_iocdata(q, mp, PF_KEY);
     1037 +                return;
 957 1038          case M_IOCTL:
 958 1039                  iocp = (struct iocblk *)mp->b_rptr;
 959 1040                  error = EINVAL;
 960 1041  
 961 1042                  switch (iocp->ioc_cmd) {
     1043 +                case TI_GETMYNAME:
     1044 +                case TI_GETPEERNAME:
     1045 +                        /*
     1046 +                         * For pfiles(1) observability with getsockname().
     1047 +                         * See keysock_spdsock_wput_iocdata() for the rest of
     1048 +                         * this.
     1049 +                         */
     1050 +                        mi_copyin(q, mp, NULL,
     1051 +                            SIZEOF_STRUCT(strbuf, iocp->ioc_flag));
     1052 +                        return;
 962 1053                  case ND_SET:
 963 1054                  case ND_GET:
 964 1055                          if (nd_getset(q, keystack->keystack_g_nd, mp)) {
 965 1056                                  qreply(q, mp);
 966 1057                                  return;
 967 1058                          } else
 968 1059                                  error = ENOENT;
 969 1060                          /* FALLTHRU */
 970 1061                  default:
 971 1062                          miocnak(q, mp, 0, error);
↓ open down ↓ 1415 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX