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>

*** 20,29 **** --- 20,32 ---- */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ + /* + * Copyright 2017 Joyent, Inc. + */ #include <sys/param.h> #include <sys/types.h> #include <sys/stream.h> #include <sys/strsubr.h>
*** 890,899 **** --- 893,977 ---- } return (errno); } /* + * Handle STREAMS ioctl copyin for getsockname() for both PF_KEY and + * PF_POLICY. + */ + void + keysock_spdsock_wput_iocdata(queue_t *q, mblk_t *mp, sa_family_t family) + { + mblk_t *mp1; + STRUCT_HANDLE(strbuf, sb); + /* What size of sockaddr do we need? */ + const uint_t addrlen = sizeof (struct sockaddr); + + /* We only handle TI_GET{MY,PEER}NAME (get{sock,peer}name()). */ + switch (((struct iocblk *)mp->b_rptr)->ioc_cmd) { + case TI_GETMYNAME: + case TI_GETPEERNAME: + break; + default: + freemsg(mp); + return; + } + + switch (mi_copy_state(q, mp, &mp1)) { + case -1: + return; + case MI_COPY_CASE(MI_COPY_IN, 1): + break; + case MI_COPY_CASE(MI_COPY_OUT, 1): + /* + * The address has been copied out, so now + * copyout the strbuf. + */ + mi_copyout(q, mp); + return; + case MI_COPY_CASE(MI_COPY_OUT, 2): + /* + * The address and strbuf have been copied out. + * We're done, so just acknowledge the original + * M_IOCTL. + */ + mi_copy_done(q, mp, 0); + return; + default: + /* + * Something strange has happened, so acknowledge + * the original M_IOCTL with an EPROTO error. + */ + mi_copy_done(q, mp, EPROTO); + return; + } + + /* + * Now we have the strbuf structure for TI_GET{MY,PEER}NAME. Next we + * copyout the requested address and then we'll copyout the strbuf. + * Regardless of sockname or peername, we just return a sockaddr with + * sa_family set. + */ + STRUCT_SET_HANDLE(sb, ((struct iocblk *)mp->b_rptr)->ioc_flag, + (void *)mp1->b_rptr); + + if (STRUCT_FGET(sb, maxlen) < addrlen) { + mi_copy_done(q, mp, EINVAL); + return; + } + + mp1 = mi_copyout_alloc(q, mp, STRUCT_FGETP(sb, buf), addrlen, B_TRUE); + if (mp1 == NULL) + return; + + STRUCT_FSET(sb, len, addrlen); + ((struct sockaddr *)mp1->b_wptr)->sa_family = family; + mp1->b_wptr += addrlen; + mi_copyout(q, mp); + } + + /* * Handle STREAMS messages. */ static void keysock_wput_other(queue_t *q, mblk_t *mp) {
*** 952,966 **** --- 1030,1057 ---- /* Not supported by keysock. */ keysock_err_ack(q, mp, TNOTSUPPORT, 0); break; } return; + case M_IOCDATA: + keysock_spdsock_wput_iocdata(q, mp, PF_KEY); + return; case M_IOCTL: iocp = (struct iocblk *)mp->b_rptr; error = EINVAL; switch (iocp->ioc_cmd) { + case TI_GETMYNAME: + case TI_GETPEERNAME: + /* + * For pfiles(1) observability with getsockname(). + * See keysock_spdsock_wput_iocdata() for the rest of + * this. + */ + mi_copyin(q, mp, NULL, + SIZEOF_STRUCT(strbuf, iocp->ioc_flag)); + return; case ND_SET: case ND_GET: if (nd_getset(q, keystack->keystack_g_nd, mp)) { qreply(q, mp); return;