Print this page
Try to remove assumption that zone's root vnode is marked VROOT


 394                 *exip = exi;
 395 
 396                 VN_RELE(*vpp);
 397                 *vpp = vp;
 398         }
 399 
 400         return (0);
 401 }
 402 
 403 /*
 404  * Given mounted "dvp" and "exi", go upper mountpoint
 405  * with dvp/exi correction
 406  * Return 0 in success
 407  */
 408 int
 409 rfs_climb_crossmnt(vnode_t **dvpp, struct exportinfo **exip, cred_t *cr)
 410 {
 411         struct exportinfo *exi;
 412         vnode_t *dvp = *dvpp;
 413 
 414         ASSERT(dvp->v_flag & VROOT);
 415 
 416         VN_HOLD(dvp);
 417         dvp = untraverse(dvp);
 418         exi = nfs_vptoexi(NULL, dvp, cr, NULL, NULL, FALSE);
 419         if (exi == NULL) {
 420                 VN_RELE(dvp);
 421                 return (-1);
 422         }
 423 
 424         exi_rele(*exip);
 425         *exip = exi;
 426         VN_RELE(*dvpp);
 427         *dvpp = dvp;
 428 
 429         return (0);
 430 }
 431 /*
 432  * Directory lookup.
 433  * Returns an fhandle and file attributes for file name in a directory.
 434  */


 473                 dvp = ZONE_ROOTVP();
 474                 VN_HOLD(dvp);
 475         } else {
 476                 dvp = nfs_fhtovp(fhp, exi);
 477                 if (dvp == NULL) {
 478                         dr->dr_status = NFSERR_STALE;
 479                         return;
 480                 }
 481         }
 482 
 483         exi_hold(exi);
 484 
 485         /*
 486          * Not allow lookup beyond root.
 487          * If the filehandle matches a filehandle of the exi,
 488          * then the ".." refers beyond the root of an exported filesystem.
 489          */
 490         if (strcmp(da->da_name, "..") == 0 &&
 491             EQFID(&exi->exi_fid, (fid_t *)&fhp->fh_len)) {
 492                 if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
 493                     (dvp->v_flag & VROOT)) {
 494                         /*
 495                          * special case for ".." and 'nohide'exported root
 496                          */
 497                         if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
 498                                 error = NFSERR_ACCES;
 499                                 goto out;
 500                         }
 501                 } else  {
 502                         error = NFSERR_NOENT;
 503                         goto out;
 504                 }
 505         }
 506 
 507         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
 508         name = nfscmd_convname(ca, exi, da->da_name, NFSCMD_CONV_INBOUND,
 509             MAXPATHLEN);
 510 
 511         if (name == NULL) {
 512                 error = NFSERR_ACCES;
 513                 goto out;




 394                 *exip = exi;
 395 
 396                 VN_RELE(*vpp);
 397                 *vpp = vp;
 398         }
 399 
 400         return (0);
 401 }
 402 
 403 /*
 404  * Given mounted "dvp" and "exi", go upper mountpoint
 405  * with dvp/exi correction
 406  * Return 0 in success
 407  */
 408 int
 409 rfs_climb_crossmnt(vnode_t **dvpp, struct exportinfo **exip, cred_t *cr)
 410 {
 411         struct exportinfo *exi;
 412         vnode_t *dvp = *dvpp;
 413 
 414         ASSERT((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp));
 415 
 416         VN_HOLD(dvp);
 417         dvp = untraverse(dvp);
 418         exi = nfs_vptoexi(NULL, dvp, cr, NULL, NULL, FALSE);
 419         if (exi == NULL) {
 420                 VN_RELE(dvp);
 421                 return (-1);
 422         }
 423 
 424         exi_rele(*exip);
 425         *exip = exi;
 426         VN_RELE(*dvpp);
 427         *dvpp = dvp;
 428 
 429         return (0);
 430 }
 431 /*
 432  * Directory lookup.
 433  * Returns an fhandle and file attributes for file name in a directory.
 434  */


 473                 dvp = ZONE_ROOTVP();
 474                 VN_HOLD(dvp);
 475         } else {
 476                 dvp = nfs_fhtovp(fhp, exi);
 477                 if (dvp == NULL) {
 478                         dr->dr_status = NFSERR_STALE;
 479                         return;
 480                 }
 481         }
 482 
 483         exi_hold(exi);
 484 
 485         /*
 486          * Not allow lookup beyond root.
 487          * If the filehandle matches a filehandle of the exi,
 488          * then the ".." refers beyond the root of an exported filesystem.
 489          */
 490         if (strcmp(da->da_name, "..") == 0 &&
 491             EQFID(&exi->exi_fid, (fid_t *)&fhp->fh_len)) {
 492                 if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
 493                     ((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp))) {
 494                         /*
 495                          * special case for ".." and 'nohide'exported root
 496                          */
 497                         if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
 498                                 error = NFSERR_ACCES;
 499                                 goto out;
 500                         }
 501                 } else  {
 502                         error = NFSERR_NOENT;
 503                         goto out;
 504                 }
 505         }
 506 
 507         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
 508         name = nfscmd_convname(ca, exi, da->da_name, NFSCMD_CONV_INBOUND,
 509             MAXPATHLEN);
 510 
 511         if (name == NULL) {
 512                 error = NFSERR_ACCES;
 513                 goto out;