Print this page
NEX-3524 CLONE - Port NEX-3505 "wrong authentication" messages with root=@0.0.0.0/0 set, result in loss of client access
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
NEX-3533 CLONE - Port NEX-3019 NFSv3 writes underneath mounted filesystem to directory
Reviewed by: Dan Fields <dan.fields@nexenta.com>
re #13613 rb4516 Tunables needs volatile keyword

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs_subr.c
          +++ new/usr/src/uts/common/fs/nfs/nfs_subr.c
↓ open down ↓ 10 lines elided ↑ open up ↑
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  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   23   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23   24   * Use is subject to license terms.
  24   25   */
  25   26  
  26   27  /*
  27      - * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
       28 + * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  28   29   * Copyright (c) 2016, 2017 by Delphix. All rights reserved.
  29   30   */
  30   31  
  31   32  #include <sys/param.h>
  32   33  #include <sys/types.h>
  33   34  #include <sys/systm.h>
  34   35  #include <sys/cred.h>
  35   36  #include <sys/proc.h>
  36   37  #include <sys/user.h>
  37   38  #include <sys/time.h>
↓ open down ↓ 86 lines elided ↑ open up ↑
 124  125   * The lock ordering is:
 125  126   *
 126  127   *      hash bucket lock -> vnode lock
 127  128   *      hash bucket lock -> freelist lock
 128  129   */
 129  130  static rhashq_t *rtable;
 130  131  
 131  132  static kmutex_t rpfreelist_lock;
 132  133  static rnode_t *rpfreelist = NULL;
 133  134  static long rnew = 0;
 134      -long nrnode = 0;
      135 +volatile long nrnode = 0;
 135  136  
 136  137  static int rtablesize;
 137  138  static int rtablemask;
 138  139  
 139  140  static int hashlen = 4;
 140  141  
 141  142  static struct kmem_cache *rnode_cache;
 142  143  
 143  144  /*
 144  145   * Mutex to protect the following variables:
 145  146   *      nfs_major
 146  147   *      nfs_minor
 147  148   */
 148  149  kmutex_t nfs_minor_lock;
 149  150  int nfs_major;
 150  151  int nfs_minor;
 151  152  
 152      -/* Do we allow preepoch (negative) time values otw? */
 153      -bool_t nfs_allow_preepoch_time = FALSE; /* default: do not allow preepoch */
      153 +/*
      154 + * Do we allow preepoch (negative) time values otw?
      155 + * default: do not allow preepoch
      156 + */
      157 +volatile bool_t nfs_allow_preepoch_time = FALSE;
 154  158  
 155  159  /*
 156  160   * Access cache
 157  161   */
 158  162  static acache_hash_t *acache;
 159      -static long nacache;    /* used strictly to size the number of hash queues */
      163 +volatile long nacache;  /* used strictly to size the number of hash queues */
 160  164  
 161  165  static int acachesize;
 162  166  static int acachemask;
 163  167  static struct kmem_cache *acache_cache;
 164  168  
 165  169  /*
 166  170   * Client side utilities
 167  171   */
 168  172  
 169  173  /*
↓ open down ↓ 51 lines elided ↑ open up ↑
 221  225  static zone_key_t nfsclnt_zone_key;
 222  226  
 223  227  static struct kmem_cache *chtab_cache;
 224  228  
 225  229  /*
 226  230   * Some servers do not properly update the attributes of the
 227  231   * directory when changes are made.  To allow interoperability
 228  232   * with these broken servers, the nfs_disable_rddir_cache
 229  233   * parameter must be set in /etc/system
 230  234   */
 231      -int nfs_disable_rddir_cache = 0;
      235 +volatile int nfs_disable_rddir_cache = 0;
 232  236  
 233  237  int             clget(clinfo_t *, servinfo_t *, cred_t *, CLIENT **,
 234  238                      struct chtab **);
 235  239  void            clfree(CLIENT *, struct chtab *);
 236  240  static int      acl_clget(mntinfo_t *, servinfo_t *, cred_t *, CLIENT **,
 237  241                      struct chtab **, struct nfs_clnt *);
 238  242  static int      nfs_clget(mntinfo_t *, servinfo_t *, cred_t *, CLIENT **,
 239  243                      struct chtab **, struct nfs_clnt *);
 240  244  static void     clreclaim(void *);
 241  245  static int      nfs_feedback(int, int, mntinfo_t *);
↓ open down ↓ 615 lines elided ↑ open up ↑
 857  861          } else if (rpc_status == RPC_PROCUNAVAIL) {
 858  862                  *statusp = NFSERR_OPNOTSUPP;
 859  863                  rpcerror = 0;
 860  864          }
 861  865  
 862  866          return (rpcerror);
 863  867  }
 864  868  
 865  869  #define NFS3_JUKEBOX_DELAY      10 * hz
 866  870  
 867      -static clock_t nfs3_jukebox_delay = 0;
      871 +volatile clock_t nfs3_jukebox_delay = 0;
 868  872  
 869  873  #ifdef DEBUG
 870  874  static int rfs3call_hits = 0;
 871  875  static int rfs3call_misses = 0;
 872  876  #endif
 873  877  
 874  878  int
 875  879  rfs3call(mntinfo_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
 876  880      xdrproc_t xdrres, caddr_t resp, cred_t *cr, int *douprintf,
 877  881      nfsstat3 *statusp, int flags, failinfo_t *fi)
↓ open down ↓ 4334 lines elided ↑ open up ↑
5212 5216                      VIEW_READONLY) == 0) {
5213 5217                          dp = (dirent64_t *)((intptr_t)dp + dp->d_reclen);
5214 5218                          continue;
5215 5219                  }
5216 5220  
5217 5221                  *valp = 1;
5218 5222                  break;
5219 5223          }
5220 5224          kmem_free(dbuf, dlen);
5221 5225          return (0);
     5226 +}
     5227 +
     5228 +/*
     5229 + * Return non-zero in a case the vp is an empty directory used as a ZFS mount
     5230 + * point.  The NFSv2 and NFSv3 servers should not allow to write to such
     5231 + * directories.
     5232 + */
     5233 +int
     5234 +protect_zfs_mntpt(vnode_t *vp)
     5235 +{
     5236 +        int error;
     5237 +        vfs_t *vfsp;
     5238 +        struct uio uio;
     5239 +        struct iovec iov;
     5240 +        int eof;
     5241 +        size_t len = 8 * 1024;
     5242 +        char *buf;
     5243 +
     5244 +        if (vp->v_type != VDIR || vn_ismntpt(vp) == 0)
     5245 +                return (0);
     5246 +
     5247 +        error = vn_vfsrlock_wait(vp);
     5248 +        if (error != 0)
     5249 +                return (error);
     5250 +
     5251 +        /*
     5252 +         * We protect ZFS mount points only
     5253 +         */
     5254 +        if ((vfsp = vn_mountedvfs(vp)) == NULL ||
     5255 +            strncmp(vfssw[vfsp->vfs_fstype].vsw_name, "zfs", 3) != 0) {
     5256 +                vn_vfsunlock(vp);
     5257 +                return (0);
     5258 +        }
     5259 +
     5260 +        vn_vfsunlock(vp);
     5261 +
     5262 +        buf = kmem_alloc(len, KM_SLEEP);
     5263 +
     5264 +        uio.uio_iov = &iov;
     5265 +        uio.uio_iovcnt = 1;
     5266 +        uio.uio_segflg = UIO_SYSSPACE;
     5267 +        uio.uio_fmode = 0;
     5268 +        uio.uio_extflg = UIO_COPY_CACHED;
     5269 +        uio.uio_loffset = 0;
     5270 +        uio.uio_llimit = MAXOFFSET_T;
     5271 +
     5272 +        eof = 0;
     5273 +
     5274 +        do {
     5275 +                size_t rlen;
     5276 +                dirent64_t *dp;
     5277 +
     5278 +                uio.uio_resid = len;
     5279 +                iov.iov_base = buf;
     5280 +                iov.iov_len = len;
     5281 +
     5282 +                (void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
     5283 +                error = VOP_READDIR(vp, &uio, kcred, &eof, NULL, 0);
     5284 +                VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
     5285 +
     5286 +                if (error != 0)
     5287 +                        break;
     5288 +
     5289 +                error = EBUSY;
     5290 +
     5291 +                rlen = len - uio.uio_resid;
     5292 +                if (rlen == 0)
     5293 +                        break;
     5294 +
     5295 +                for (dp = (dirent64_t *)buf;
     5296 +                    (intptr_t)dp < (intptr_t)buf + rlen;
     5297 +                    dp = (dirent64_t *)((intptr_t)dp + dp->d_reclen)) {
     5298 +                        if (strcmp(dp->d_name, ".") != 0 &&
     5299 +                            strcmp(dp->d_name, "..") != 0) {
     5300 +                                error = 0;
     5301 +                                break;
     5302 +                        }
     5303 +                }
     5304 +        } while (eof == 0 && error != 0);
     5305 +
     5306 +        kmem_free(buf, len);
     5307 +
     5308 +        return (error);
5222 5309  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX