Print this page
Revert exi_zone to exi_zoneid, and install exi_ne backpointer
Caution with use after exi_rele()
Be far more judicious in the use of curzone-using macros.
(Merge and extra asserts by danmcd.)
curzone reality check and teardown changes to use the RIGHT zone
Try to remove assumption that zone's root vnode is marked VROOT

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs3_srv.c
          +++ new/usr/src/uts/common/fs/nfs/nfs3_srv.c
↓ open down ↓ 403 lines elided ↑ open up ↑
 404  404          dvap = NULL;
 405  405  
 406  406          if (exi != NULL)
 407  407                  exi_hold(exi);
 408  408  
 409  409          /*
 410  410           * Allow lookups from the root - the default
 411  411           * location of the public filehandle.
 412  412           */
 413  413          if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
      414 +                ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
 414  415                  dvp = ZONE_ROOTVP();
 415  416                  VN_HOLD(dvp);
 416  417  
 417  418                  DTRACE_NFSV3_5(op__lookup__start, struct svc_req *, req,
 418  419                      cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
 419  420                      LOOKUP3args *, args);
 420  421          } else {
 421  422                  dvp = nfs3_fhtovp(&args->what.dir, exi);
 422  423  
 423  424                  DTRACE_NFSV3_5(op__lookup__start, struct svc_req *, req,
↓ open down ↓ 13 lines elided ↑ open up ↑
 437  438                  resp->status = NFS3ERR_NAMETOOLONG;
 438  439                  goto out1;
 439  440          }
 440  441  
 441  442          if (args->what.name == NULL || *(args->what.name) == '\0') {
 442  443                  resp->status = NFS3ERR_ACCES;
 443  444                  goto out1;
 444  445          }
 445  446  
 446  447          fhp = &args->what.dir;
      448 +        ASSERT3U(curzone->zone_id, ==, exi->exi_zoneid); /* exi is non-NULL */
 447  449          if (strcmp(args->what.name, "..") == 0 &&
 448  450              EQFID(&exi->exi_fid, FH3TOFIDP(fhp))) {
 449  451                  if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
 450      -                    (dvp->v_flag & VROOT)) {
      452 +                    ((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp))) {
 451  453                          /*
 452  454                           * special case for ".." and 'nohide'exported root
 453  455                           */
 454  456                          if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
 455  457                                  resp->status = NFS3ERR_ACCES;
 456  458                                  goto out1;
 457  459                          }
 458  460                  } else {
 459  461                          resp->status = NFS3ERR_NOENT;
 460  462                          goto out1;
↓ open down ↓ 10 lines elided ↑ open up ↑
 471  473          }
 472  474  
 473  475          /*
 474  476           * If the public filehandle is used then allow
 475  477           * a multi-component lookup
 476  478           */
 477  479          if (PUBLIC_FH3(&args->what.dir)) {
 478  480                  publicfh_flag = TRUE;
 479  481  
 480  482                  exi_rele(exi);
      483 +                exi = NULL;
 481  484  
 482  485                  error = rfs_publicfh_mclookup(name, dvp, cr, &vp,
 483  486                      &exi, &sec);
 484  487  
 485  488                  /*
 486  489                   * Since WebNFS may bypass MOUNT, we need to ensure this
 487  490                   * request didn't come from an unlabeled admin_low client.
 488  491                   */
 489  492                  if (is_system_labeled() && error == 0) {
 490  493                          int             addr_type;
↓ open down ↓ 63 lines elided ↑ open up ↑
 554  557          }
 555  558  
 556  559          if (error) {
 557  560                  VN_RELE(vp);
 558  561                  goto out;
 559  562          }
 560  563  
 561  564          va.va_mask = AT_ALL;
 562  565          vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
 563  566  
 564      -        exi_rele(exi);
 565  567          VN_RELE(vp);
 566  568  
 567  569          resp->status = NFS3_OK;
 568  570          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 569  571          vattr_to_post_op_attr(dvap, &resp->resok.dir_attributes);
 570  572  
 571  573          /*
 572  574           * If it's public fh, no 0x81, and client's flavor is
 573  575           * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now.
 574  576           * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
 575  577           */
 576  578          if (auth_weak)
 577  579                  resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
 578  580  
 579  581          DTRACE_NFSV3_5(op__lookup__done, struct svc_req *, req,
 580  582              cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
 581  583              LOOKUP3res *, resp);
 582  584          VN_RELE(dvp);
      585 +        exi_rele(exi);
 583  586  
 584  587          return;
 585  588  
 586  589  out:
 587  590          if (curthread->t_flag & T_WOULDBLOCK) {
 588  591                  curthread->t_flag &= ~T_WOULDBLOCK;
 589  592                  resp->status = NFS3ERR_JUKEBOX;
 590  593          } else
 591  594                  resp->status = puterrno3(error);
 592  595  out1:
↓ open down ↓ 733 lines elided ↑ open up ↑
1326 1329  
1327 1330          DTRACE_NFSV3_5(op__write__start, struct svc_req *, req,
1328 1331              cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
1329 1332              WRITE3args *, args);
1330 1333  
1331 1334          if (vp == NULL) {
1332 1335                  error = ESTALE;
1333 1336                  goto err;
1334 1337          }
1335 1338  
     1339 +        ASSERT3U(curzone->zone_id, ==, exi->exi_zoneid); /* exi is non-NULL. */
1336 1340          ns = nfs3_get_srv();
     1341 +
1337 1342          if (is_system_labeled()) {
1338 1343                  bslabel_t *clabel = req->rq_label;
1339 1344  
1340 1345                  ASSERT(clabel != NULL);
1341 1346                  DTRACE_PROBE2(tx__rfs3__log__info__opwrite__clabel, char *,
1342 1347                      "got client label from request(1)", struct svc_req *, req);
1343 1348  
1344 1349                  if (!blequal(&l_admin_low->tsl_label, clabel)) {
1345 1350                          if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK,
1346 1351                              exi)) {
↓ open down ↓ 1317 lines elided ↑ open up ↑
2664 2669  
2665 2670          ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2666 2671          name = nfscmd_convname(ca, exi, args->object.name,
2667 2672              NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2668 2673  
2669 2674          if (name == NULL) {
2670 2675                  resp->status = NFS3ERR_INVAL;
2671 2676                  goto err1;
2672 2677          }
2673 2678  
     2679 +        ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
2674 2680          error = VOP_RMDIR(vp, name, ZONE_ROOTVP(), cr, NULL, 0);
2675 2681  
2676 2682          if (name != args->object.name)
2677 2683                  kmem_free(name, MAXPATHLEN + 1);
2678 2684  
2679 2685          ava.va_mask = AT_ALL;
2680 2686          avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;
2681 2687  
2682 2688          /*
2683 2689           * Force modified data and metadata out to stable storage.
↓ open down ↓ 1442 lines elided ↑ open up ↑
4126 4132  
4127 4133          DTRACE_NFSV3_5(op__commit__start, struct svc_req *, req,
4128 4134              cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
4129 4135              COMMIT3args *, args);
4130 4136  
4131 4137          if (vp == NULL) {
4132 4138                  error = ESTALE;
4133 4139                  goto out;
4134 4140          }
4135 4141  
     4142 +        ASSERT3U(curzone->zone_id, ==, exi->exi_zoneid); /* exi is non-NULL. */
4136 4143          ns = nfs3_get_srv();
4137 4144          bva.va_mask = AT_ALL;
4138 4145          error = VOP_GETATTR(vp, &bva, 0, cr, NULL);
4139 4146  
4140 4147          /*
4141 4148           * If we can't get the attributes, then we can't do the
4142 4149           * right access checking.  So, we'll fail the request.
4143 4150           */
4144 4151          if (error)
4145 4152                  goto out;
↓ open down ↓ 313 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX