Print this page
3354 kernel crash in rpcsec_gss after using gsscred
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Carlos Neira <cneirabustos@gmail.com>
Approved by: Robert Mustacchi <rm@joyent.com>
NEX-4123 xdrmblk_getpos() is unreliable
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
re #13613 rb4516 Tunables needs volatile keyword
closes  #11843 rb3753 - NFSv3/UDP server sends packets with wrong Source IP in header (picked from ncp3-gate)


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  24  *  Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  25  * Copyright (c) 2012 by Delphix. All rights reserved.


  26  */
  27 
  28 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  29 /*        All Rights Reserved   */
  30 
  31 /*
  32  * Portions of this source code were derived from Berkeley 4.3 BSD
  33  * under license from the Regents of the University of California.
  34  */
  35 
  36 /*
  37  * svc_clts.c
  38  * Server side for RPC in the kernel.
  39  *
  40  */
  41 
  42 #include <sys/param.h>
  43 #include <sys/types.h>
  44 #include <sys/sysmacros.h>
  45 #include <sys/file.h>


  84 static void             svc_clts_kstart(SVCMASTERXPRT *);
  85 static void             svc_clts_kclone_xprt(SVCXPRT *, SVCXPRT *);
  86 static void             svc_clts_ktattrs(SVCXPRT *, int, void **);
  87 
  88 /*
  89  * Server transport operations vector.
  90  */
  91 struct svc_ops svc_clts_op = {
  92         svc_clts_krecv,         /* Get requests */
  93         svc_clts_kgetargs,      /* Deserialize arguments */
  94         svc_clts_ksend,         /* Send reply */
  95         svc_clts_kfreeargs,     /* Free argument data space */
  96         svc_clts_kdestroy,      /* Destroy transport handle */
  97         svc_clts_kdup,          /* Check entry in dup req cache */
  98         svc_clts_kdupdone,      /* Mark entry in dup req cache as done */
  99         svc_clts_kgetres,       /* Get pointer to response buffer */
 100         svc_clts_kfreeres,      /* Destroy pre-serialized response header */
 101         svc_clts_kclone_destroy, /* Destroy a clone xprt */
 102         svc_clts_kstart,        /* Tell `ready-to-receive' to rpcmod */
 103         svc_clts_kclone_xprt,   /* transport specific clone xprt function */
 104         svc_clts_ktattrs        /* Transport specific attributes. */


 105 };
 106 
 107 /*
 108  * Transport private data.
 109  * Kept in xprt->xp_p2buf.
 110  */
 111 struct udp_data {
 112         mblk_t  *ud_resp;                       /* buffer for response */
 113         mblk_t  *ud_inmp;                       /* mblk chain of request */

 114 };
 115 
 116 #define UD_MAXSIZE      8800
 117 #define UD_INITSIZE     2048
 118 
 119 /*
 120  * Connectionless server statistics
 121  */
 122 static const struct rpc_clts_server {
 123         kstat_named_t   rscalls;
 124         kstat_named_t   rsbadcalls;
 125         kstat_named_t   rsnullrecv;
 126         kstat_named_t   rsbadlen;
 127         kstat_named_t   rsxdrcall;
 128         kstat_named_t   rsdupchecks;
 129         kstat_named_t   rsdupreqs;
 130 } clts_rsstat_tmpl = {
 131         { "calls",      KSTAT_DATA_UINT64 },
 132         { "badcalls",   KSTAT_DATA_UINT64 },
 133         { "nullrecv",   KSTAT_DATA_UINT64 },


 307             pptr->unitdata_ind.OPT_length) ||
 308             hdrsz < (pptr->unitdata_ind.SRC_offset +
 309             pptr->unitdata_ind.SRC_length)) {
 310                 goto bad;
 311         }
 312 
 313         /*
 314          * Make sure that the transport provided a usable address.
 315          */
 316         if (pptr->unitdata_ind.SRC_length <= 0) {
 317                 goto bad;
 318         }
 319         /*
 320          * Point the remote transport address in the service_transport
 321          * handle at the address in the request.
 322          */
 323         clone_xprt->xp_rtaddr.buf = (char *)mp->b_rptr +
 324             pptr->unitdata_ind.SRC_offset;
 325         clone_xprt->xp_rtaddr.len = pptr->unitdata_ind.SRC_length;
 326 


 327         /*
 328          * Copy the local transport address in the service_transport
 329          * handle at the address in the request. We will have only
 330          * the local IP address in options.
 331          */
 332         ((sin_t *)(clone_xprt->xp_lcladdr.buf))->sin_family = AF_UNSPEC;
 333         if (pptr->unitdata_ind.OPT_length && pptr->unitdata_ind.OPT_offset) {
 334                 char *dstopt = (char *)mp->b_rptr +
 335                     pptr->unitdata_ind.OPT_offset;
 336                 struct T_opthdr *toh = (struct T_opthdr *)dstopt;
 337 
 338                 if (toh->level == IPPROTO_IPV6 && toh->status == 0 &&
 339                     toh->name == IPV6_PKTINFO) {
 340                         struct in6_pktinfo *pkti;
 341 
 342                         dstopt += sizeof (struct T_opthdr);
 343                         pkti = (struct in6_pktinfo *)dstopt;
 344                         ((sin6_t *)(clone_xprt->xp_lcladdr.buf))->sin6_addr
 345                             = pkti->ipi6_addr;
 346                         ((sin6_t *)(clone_xprt->xp_lcladdr.buf))->sin6_family


 744  */
 745 
 746 /*
 747  * MAXDUPREQS is the number of cached items.  It should be adjusted
 748  * to the service load so that there is likely to be a response entry
 749  * when the first retransmission comes in.
 750  */
 751 #define MAXDUPREQS      8192
 752 
 753 /*
 754  * This should be appropriately scaled to MAXDUPREQS.  To produce as less as
 755  * possible collisions it is suggested to set this to a prime.
 756  */
 757 #define DRHASHSZ        2053
 758 
 759 #define XIDHASH(xid)    ((xid) % DRHASHSZ)
 760 #define DRHASH(dr)      XIDHASH((dr)->dr_xid)
 761 #define REQTOXID(req)   ((req)->rq_xprt->xp_xid)
 762 
 763 static int      ndupreqs = 0;
 764 int     maxdupreqs = MAXDUPREQS;
 765 static kmutex_t dupreq_lock;
 766 static struct dupreq *drhashtbl[DRHASHSZ];
 767 static int      drhashstat[DRHASHSZ];
 768 
 769 static void unhash(struct dupreq *);
 770 
 771 /*
 772  * drmru points to the head of a circular linked list in lru order.
 773  * drmru->dr_next == drlru
 774  */
 775 struct dupreq *drmru;
 776 
 777 /*
 778  * PSARC 2003/523 Contract Private Interface
 779  * svc_clts_kdup
 780  * Changes must be reviewed by Solaris File Sharing
 781  * Changes must be communicated to contract-2003-523@sun.com
 782  *
 783  * svc_clts_kdup searches the request cache and returns 0 if the
 784  * request is not found in the cache.  If it is found, then it




   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  24  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  25  * Copyright (c) 2012 by Delphix. All rights reserved.
  26  * Copyright 2012 Marcel Telka <marcel@telka.sk>
  27  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  28  */
  29 
  30 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  31 /*      All Rights Reserved     */
  32 
  33 /*
  34  * Portions of this source code were derived from Berkeley 4.3 BSD
  35  * under license from the Regents of the University of California.
  36  */
  37 
  38 /*
  39  * svc_clts.c
  40  * Server side for RPC in the kernel.
  41  *
  42  */
  43 
  44 #include <sys/param.h>
  45 #include <sys/types.h>
  46 #include <sys/sysmacros.h>
  47 #include <sys/file.h>


  86 static void             svc_clts_kstart(SVCMASTERXPRT *);
  87 static void             svc_clts_kclone_xprt(SVCXPRT *, SVCXPRT *);
  88 static void             svc_clts_ktattrs(SVCXPRT *, int, void **);
  89 
  90 /*
  91  * Server transport operations vector.
  92  */
  93 struct svc_ops svc_clts_op = {
  94         svc_clts_krecv,         /* Get requests */
  95         svc_clts_kgetargs,      /* Deserialize arguments */
  96         svc_clts_ksend,         /* Send reply */
  97         svc_clts_kfreeargs,     /* Free argument data space */
  98         svc_clts_kdestroy,      /* Destroy transport handle */
  99         svc_clts_kdup,          /* Check entry in dup req cache */
 100         svc_clts_kdupdone,      /* Mark entry in dup req cache as done */
 101         svc_clts_kgetres,       /* Get pointer to response buffer */
 102         svc_clts_kfreeres,      /* Destroy pre-serialized response header */
 103         svc_clts_kclone_destroy, /* Destroy a clone xprt */
 104         svc_clts_kstart,        /* Tell `ready-to-receive' to rpcmod */
 105         svc_clts_kclone_xprt,   /* transport specific clone xprt function */
 106         svc_clts_ktattrs,       /* Transport specific attributes */
 107         rpcmod_hold,            /* Increment transport reference count */
 108         rpcmod_release          /* Decrement transport reference count */
 109 };
 110 
 111 /*
 112  * Transport private data.
 113  * Kept in xprt->xp_p2buf.
 114  */
 115 struct udp_data {
 116         mblk_t  *ud_resp;                       /* buffer for response */
 117         mblk_t  *ud_inmp;                       /* mblk chain of request */
 118         sin6_t  ud_local;                       /* local address */
 119 };
 120 
 121 #define UD_MAXSIZE      8800
 122 #define UD_INITSIZE     2048
 123 
 124 /*
 125  * Connectionless server statistics
 126  */
 127 static const struct rpc_clts_server {
 128         kstat_named_t   rscalls;
 129         kstat_named_t   rsbadcalls;
 130         kstat_named_t   rsnullrecv;
 131         kstat_named_t   rsbadlen;
 132         kstat_named_t   rsxdrcall;
 133         kstat_named_t   rsdupchecks;
 134         kstat_named_t   rsdupreqs;
 135 } clts_rsstat_tmpl = {
 136         { "calls",      KSTAT_DATA_UINT64 },
 137         { "badcalls",   KSTAT_DATA_UINT64 },
 138         { "nullrecv",   KSTAT_DATA_UINT64 },


 312             pptr->unitdata_ind.OPT_length) ||
 313             hdrsz < (pptr->unitdata_ind.SRC_offset +
 314             pptr->unitdata_ind.SRC_length)) {
 315                 goto bad;
 316         }
 317 
 318         /*
 319          * Make sure that the transport provided a usable address.
 320          */
 321         if (pptr->unitdata_ind.SRC_length <= 0) {
 322                 goto bad;
 323         }
 324         /*
 325          * Point the remote transport address in the service_transport
 326          * handle at the address in the request.
 327          */
 328         clone_xprt->xp_rtaddr.buf = (char *)mp->b_rptr +
 329             pptr->unitdata_ind.SRC_offset;
 330         clone_xprt->xp_rtaddr.len = pptr->unitdata_ind.SRC_length;
 331 
 332         clone_xprt->xp_lcladdr.buf = (char *)&ud->ud_local;
 333 
 334         /*
 335          * Copy the local transport address in the service_transport
 336          * handle at the address in the request. We will have only
 337          * the local IP address in options.
 338          */
 339         ((sin_t *)(clone_xprt->xp_lcladdr.buf))->sin_family = AF_UNSPEC;
 340         if (pptr->unitdata_ind.OPT_length && pptr->unitdata_ind.OPT_offset) {
 341                 char *dstopt = (char *)mp->b_rptr +
 342                     pptr->unitdata_ind.OPT_offset;
 343                 struct T_opthdr *toh = (struct T_opthdr *)dstopt;
 344 
 345                 if (toh->level == IPPROTO_IPV6 && toh->status == 0 &&
 346                     toh->name == IPV6_PKTINFO) {
 347                         struct in6_pktinfo *pkti;
 348 
 349                         dstopt += sizeof (struct T_opthdr);
 350                         pkti = (struct in6_pktinfo *)dstopt;
 351                         ((sin6_t *)(clone_xprt->xp_lcladdr.buf))->sin6_addr
 352                             = pkti->ipi6_addr;
 353                         ((sin6_t *)(clone_xprt->xp_lcladdr.buf))->sin6_family


 751  */
 752 
 753 /*
 754  * MAXDUPREQS is the number of cached items.  It should be adjusted
 755  * to the service load so that there is likely to be a response entry
 756  * when the first retransmission comes in.
 757  */
 758 #define MAXDUPREQS      8192
 759 
 760 /*
 761  * This should be appropriately scaled to MAXDUPREQS.  To produce as less as
 762  * possible collisions it is suggested to set this to a prime.
 763  */
 764 #define DRHASHSZ        2053
 765 
 766 #define XIDHASH(xid)    ((xid) % DRHASHSZ)
 767 #define DRHASH(dr)      XIDHASH((dr)->dr_xid)
 768 #define REQTOXID(req)   ((req)->rq_xprt->xp_xid)
 769 
 770 static int      ndupreqs = 0;
 771 volatile int    maxdupreqs = MAXDUPREQS;
 772 static kmutex_t dupreq_lock;
 773 static struct dupreq *drhashtbl[DRHASHSZ];
 774 static int      drhashstat[DRHASHSZ];
 775 
 776 static void unhash(struct dupreq *);
 777 
 778 /*
 779  * drmru points to the head of a circular linked list in lru order.
 780  * drmru->dr_next == drlru
 781  */
 782 struct dupreq *drmru;
 783 
 784 /*
 785  * PSARC 2003/523 Contract Private Interface
 786  * svc_clts_kdup
 787  * Changes must be reviewed by Solaris File Sharing
 788  * Changes must be communicated to contract-2003-523@sun.com
 789  *
 790  * svc_clts_kdup searches the request cache and returns 0 if the
 791  * request is not found in the cache.  If it is found, then it