Print this page
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.


2031         zone0.zone_shares = 1;
2032         zone0.zone_nlwps = 0;
2033         zone0.zone_nlwps_ctl = INT_MAX;
2034         zone0.zone_nprocs = 0;
2035         zone0.zone_nprocs_ctl = INT_MAX;
2036         zone0.zone_locked_mem = 0;
2037         zone0.zone_locked_mem_ctl = UINT64_MAX;
2038         ASSERT(zone0.zone_max_swap == 0);
2039         zone0.zone_max_swap_ctl = UINT64_MAX;
2040         zone0.zone_max_lofi = 0;
2041         zone0.zone_max_lofi_ctl = UINT64_MAX;
2042         zone0.zone_shmmax = 0;
2043         zone0.zone_ipc.ipcq_shmmni = 0;
2044         zone0.zone_ipc.ipcq_semmni = 0;
2045         zone0.zone_ipc.ipcq_msgmni = 0;
2046         zone0.zone_name = GLOBAL_ZONENAME;
2047         zone0.zone_nodename = utsname.nodename;
2048         zone0.zone_domain = srpc_domain;
2049         zone0.zone_hostid = HW_INVALID_HOSTID;
2050         zone0.zone_fs_allowed = NULL;

2051         zone0.zone_ref = 1;
2052         zone0.zone_id = GLOBAL_ZONEID;
2053         zone0.zone_status = ZONE_IS_RUNNING;
2054         zone0.zone_rootpath = "/";
2055         zone0.zone_rootpathlen = 2;
2056         zone0.zone_psetid = ZONE_PS_INVAL;
2057         zone0.zone_ncpus = 0;
2058         zone0.zone_ncpus_online = 0;
2059         zone0.zone_proc_initpid = 1;
2060         zone0.zone_initname = initname;
2061         zone0.zone_lockedmem_kstat = NULL;
2062         zone0.zone_swapresv_kstat = NULL;
2063         zone0.zone_nprocs_kstat = NULL;
2064 
2065         zone0.zone_stime = 0;
2066         zone0.zone_utime = 0;
2067         zone0.zone_wtime = 0;
2068 
2069         list_create(&zone0.zone_ref_list, sizeof (zone_ref_t),
2070             offsetof(zone_ref_t, zref_linkage));


2478          */
2479         mutex_enter(&zone_status_lock);
2480 
2481         /* Re-Branding is not allowed and the zone can't be booted yet */
2482         if ((ZONE_IS_BRANDED(zone)) ||
2483             (zone_status_get(zone) >= ZONE_IS_BOOTING)) {
2484                 mutex_exit(&zone_status_lock);
2485                 brand_unregister_zone(bp);
2486                 return (EINVAL);
2487         }
2488 
2489         /* set up the brand specific data */
2490         zone->zone_brand = bp;
2491         ZBROP(zone)->b_init_brand_data(zone);
2492 
2493         mutex_exit(&zone_status_lock);
2494         return (0);
2495 }
2496 
2497 static int


























2498 zone_set_fs_allowed(zone_t *zone, const char *zone_fs_allowed)
2499 {
2500         char *buf = kmem_zalloc(ZONE_FS_ALLOWED_MAX, KM_SLEEP);
2501         int err = 0;
2502 
2503         ASSERT(zone != global_zone);
2504         if ((err = copyinstr(zone_fs_allowed, buf,
2505             ZONE_FS_ALLOWED_MAX, NULL)) != 0)
2506                 goto done;
2507 
2508         if (zone->zone_fs_allowed != NULL)
2509                 strfree(zone->zone_fs_allowed);
2510 
2511         zone->zone_fs_allowed = strdup(buf);
2512 
2513 done:
2514         kmem_free(buf, ZONE_FS_ALLOWED_MAX);
2515         return (err);
2516 }
2517 


3939                         ASSERT(error == 0);
3940                 }
3941                 error = nvpair_value_nvlist_array(nvp, &nvlarray, &nelem);
3942                 ASSERT(error == 0);
3943                 for (i = 0; i < nelem; i++) {
3944                         rctl_val_t *nvalp;
3945 
3946                         nvalp = kmem_cache_alloc(rctl_val_cache, KM_SLEEP);
3947                         error = nvlist2rctlval(nvlarray[i], nvalp);
3948                         ASSERT(error == 0);
3949                         /*
3950                          * rctl_local_insert can fail if the value being
3951                          * inserted is a duplicate; this is OK.
3952                          */
3953                         mutex_enter(&pp->p_lock);
3954                         if (rctl_local_insert(hndl, nvalp, pp) != 0)
3955                                 kmem_cache_free(rctl_val_cache, nvalp);
3956                         mutex_exit(&pp->p_lock);
3957                 }
3958         }

3959         /*
3960          * Tell the world that we're done setting up.
3961          *
3962          * At this point we want to set the zone status to ZONE_IS_INITIALIZED
3963          * and atomically set the zone's processor set visibility.  Once
3964          * we drop pool_lock() this zone will automatically get updated
3965          * to reflect any future changes to the pools configuration.
3966          *
3967          * Note that after we drop the locks below (zonehash_lock in
3968          * particular) other operations such as a zone_getattr call can
3969          * now proceed and observe the zone. That is the reason for doing a
3970          * state transition to the INITIALIZED state.
3971          */
3972         pool_lock();
3973         mutex_enter(&cpu_lock);
3974         mutex_enter(&zonehash_lock);
3975         zone_uniqid(zone);
3976         zone_zsd_configure(zone);
3977         if (pool_state == POOL_ENABLED)
3978                 zone_pset_set(zone, pool_default->pool_pset->pset_id);


4222                 ASSERT(error == 0);
4223                 for (i = 0; i < nelem; i++) {
4224                         if (error = nvlist2rctlval(nvlarray[i], &rv))
4225                                 goto out;
4226                 }
4227                 if (rctl_invalid_value(rde, &rv)) {
4228                         error = EINVAL;
4229                         goto out;
4230                 }
4231         }
4232         error = 0;
4233         *nvlp = nvl;
4234 out:
4235         kmem_free(kbuf, buflen);
4236         if (error && nvl != NULL)
4237                 nvlist_free(nvl);
4238         return (error);
4239 }
4240 
4241 int
4242 zone_create_error(int er_error, int er_ext, int *er_out) {

4243         if (er_out != NULL) {
4244                 if (copyout(&er_ext, er_out, sizeof (int))) {
4245                         return (set_errno(EFAULT));
4246                 }
4247         }
4248         return (set_errno(er_error));
4249 }
4250 
4251 static int
4252 zone_set_label(zone_t *zone, const bslabel_t *lab, uint32_t doi)
4253 {
4254         ts_label_t *tsl;
4255         bslabel_t blab;
4256 
4257         /* Get label from user */
4258         if (copyin(lab, &blab, sizeof (blab)) != 0)
4259                 return (EFAULT);
4260         tsl = labelalloc(&blab, doi, KM_NOSLEEP);
4261         if (tsl == NULL)
4262                 return (ENOMEM);


4392         if ((error = zone_set_privset(zone, zone_privs, zone_privssz)) != 0) {
4393                 zone_free(zone);
4394                 return (zone_create_error(error, 0, extended_error));
4395         }
4396 
4397         /* initialize node name to be the same as zone name */
4398         zone->zone_nodename = kmem_alloc(_SYS_NMLN, KM_SLEEP);
4399         (void) strncpy(zone->zone_nodename, zone->zone_name, _SYS_NMLN);
4400         zone->zone_nodename[_SYS_NMLN - 1] = '\0';
4401 
4402         zone->zone_domain = kmem_alloc(_SYS_NMLN, KM_SLEEP);
4403         zone->zone_domain[0] = '\0';
4404         zone->zone_hostid = HW_INVALID_HOSTID;
4405         zone->zone_shares = 1;
4406         zone->zone_shmmax = 0;
4407         zone->zone_ipc.ipcq_shmmni = 0;
4408         zone->zone_ipc.ipcq_semmni = 0;
4409         zone->zone_ipc.ipcq_msgmni = 0;
4410         zone->zone_bootargs = NULL;
4411         zone->zone_fs_allowed = NULL;






4412         zone->zone_initname =
4413             kmem_alloc(strlen(zone_default_initname) + 1, KM_SLEEP);
4414         (void) strcpy(zone->zone_initname, zone_default_initname);
4415         zone->zone_nlwps = 0;
4416         zone->zone_nlwps_ctl = INT_MAX;
4417         zone->zone_nprocs = 0;
4418         zone->zone_nprocs_ctl = INT_MAX;
4419         zone->zone_locked_mem = 0;
4420         zone->zone_locked_mem_ctl = UINT64_MAX;
4421         zone->zone_max_swap = 0;
4422         zone->zone_max_swap_ctl = UINT64_MAX;
4423         zone->zone_max_lofi = 0;
4424         zone->zone_max_lofi_ctl = UINT64_MAX;
4425         zone0.zone_lockedmem_kstat = NULL;
4426         zone0.zone_swapresv_kstat = NULL;
4427 
4428         /*
4429          * Zsched initializes the rctls.
4430          */
4431         zone->zone_rctls = NULL;


5513                             bufsize) != 0)
5514                                 error = EFAULT;
5515                 } else {
5516                         error = EINVAL;
5517                 }
5518                 break;
5519         case ZONE_ATTR_FS_ALLOWED:
5520                 if (zone->zone_fs_allowed == NULL)
5521                         outstr = "";
5522                 else
5523                         outstr = zone->zone_fs_allowed;
5524                 size = strlen(outstr) + 1;
5525                 if (bufsize > size)
5526                         bufsize = size;
5527                 if (buf != NULL) {
5528                         err = copyoutstr(outstr, buf, bufsize, NULL);
5529                         if (err != 0 && err != ENAMETOOLONG)
5530                                 error = EFAULT;
5531                 }
5532                 break;







5533         case ZONE_ATTR_NETWORK:
5534                 zbuf = kmem_alloc(bufsize, KM_SLEEP);
5535                 if (copyin(buf, zbuf, bufsize) != 0) {
5536                         error = EFAULT;
5537                 } else {
5538                         error = zone_get_network(zoneid, zbuf);
5539                         if (error == 0 && copyout(zbuf, buf, bufsize) != 0)
5540                                 error = EFAULT;
5541                 }
5542                 kmem_free(zbuf, bufsize);
5543                 break;
5544         default:
5545                 if ((attr >= ZONE_ATTR_BRAND_ATTRS) && ZONE_IS_BRANDED(zone)) {
5546                         size = bufsize;
5547                         error = ZBROP(zone)->b_getattr(zone, attr, buf, &size);
5548                 } else {
5549                         error = EINVAL;
5550                 }
5551         }
5552         zone_rele(zone);


5597                 goto done;
5598         }
5599 
5600         switch (attr) {
5601         case ZONE_ATTR_INITNAME:
5602                 err = zone_set_initname(zone, (const char *)buf);
5603                 break;
5604         case ZONE_ATTR_INITNORESTART:
5605                 zone->zone_restart_init = B_FALSE;
5606                 err = 0;
5607                 break;
5608         case ZONE_ATTR_BOOTARGS:
5609                 err = zone_set_bootargs(zone, (const char *)buf);
5610                 break;
5611         case ZONE_ATTR_BRAND:
5612                 err = zone_set_brand(zone, (const char *)buf);
5613                 break;
5614         case ZONE_ATTR_FS_ALLOWED:
5615                 err = zone_set_fs_allowed(zone, (const char *)buf);
5616                 break;



5617         case ZONE_ATTR_PHYS_MCAP:
5618                 err = zone_set_phys_mcap(zone, (const uint64_t *)buf);
5619                 break;
5620         case ZONE_ATTR_SCHED_CLASS:
5621                 err = zone_set_sched_class(zone, (const char *)buf);
5622                 break;
5623         case ZONE_ATTR_HOSTID:
5624                 if (bufsize == sizeof (zone->zone_hostid)) {
5625                         if (copyin(buf, &zone->zone_hostid, bufsize) == 0)
5626                                 err = 0;
5627                         else
5628                                 err = EFAULT;
5629                 } else {
5630                         err = EINVAL;
5631                 }
5632                 break;
5633         case ZONE_ATTR_NETWORK:
5634                 if (bufsize > (PIPE_BUF + sizeof (zone_net_data_t))) {
5635                         err = EINVAL;
5636                         break;




2031         zone0.zone_shares = 1;
2032         zone0.zone_nlwps = 0;
2033         zone0.zone_nlwps_ctl = INT_MAX;
2034         zone0.zone_nprocs = 0;
2035         zone0.zone_nprocs_ctl = INT_MAX;
2036         zone0.zone_locked_mem = 0;
2037         zone0.zone_locked_mem_ctl = UINT64_MAX;
2038         ASSERT(zone0.zone_max_swap == 0);
2039         zone0.zone_max_swap_ctl = UINT64_MAX;
2040         zone0.zone_max_lofi = 0;
2041         zone0.zone_max_lofi_ctl = UINT64_MAX;
2042         zone0.zone_shmmax = 0;
2043         zone0.zone_ipc.ipcq_shmmni = 0;
2044         zone0.zone_ipc.ipcq_semmni = 0;
2045         zone0.zone_ipc.ipcq_msgmni = 0;
2046         zone0.zone_name = GLOBAL_ZONENAME;
2047         zone0.zone_nodename = utsname.nodename;
2048         zone0.zone_domain = srpc_domain;
2049         zone0.zone_hostid = HW_INVALID_HOSTID;
2050         zone0.zone_fs_allowed = NULL;
2051         psecflags_default(&zone0.zone_secflags);
2052         zone0.zone_ref = 1;
2053         zone0.zone_id = GLOBAL_ZONEID;
2054         zone0.zone_status = ZONE_IS_RUNNING;
2055         zone0.zone_rootpath = "/";
2056         zone0.zone_rootpathlen = 2;
2057         zone0.zone_psetid = ZONE_PS_INVAL;
2058         zone0.zone_ncpus = 0;
2059         zone0.zone_ncpus_online = 0;
2060         zone0.zone_proc_initpid = 1;
2061         zone0.zone_initname = initname;
2062         zone0.zone_lockedmem_kstat = NULL;
2063         zone0.zone_swapresv_kstat = NULL;
2064         zone0.zone_nprocs_kstat = NULL;
2065 
2066         zone0.zone_stime = 0;
2067         zone0.zone_utime = 0;
2068         zone0.zone_wtime = 0;
2069 
2070         list_create(&zone0.zone_ref_list, sizeof (zone_ref_t),
2071             offsetof(zone_ref_t, zref_linkage));


2479          */
2480         mutex_enter(&zone_status_lock);
2481 
2482         /* Re-Branding is not allowed and the zone can't be booted yet */
2483         if ((ZONE_IS_BRANDED(zone)) ||
2484             (zone_status_get(zone) >= ZONE_IS_BOOTING)) {
2485                 mutex_exit(&zone_status_lock);
2486                 brand_unregister_zone(bp);
2487                 return (EINVAL);
2488         }
2489 
2490         /* set up the brand specific data */
2491         zone->zone_brand = bp;
2492         ZBROP(zone)->b_init_brand_data(zone);
2493 
2494         mutex_exit(&zone_status_lock);
2495         return (0);
2496 }
2497 
2498 static int
2499 zone_set_secflags(zone_t *zone, const psecflags_t *zone_secflags)
2500 {
2501         int err = 0;
2502         psecflags_t psf;
2503 
2504         ASSERT(zone != global_zone);
2505 
2506         if ((err = copyin(zone_secflags, &psf, sizeof (psf))) != 0)
2507                 return (err);
2508 
2509         if (zone_status_get(zone) > ZONE_IS_READY)
2510                 return (EINVAL);
2511 
2512         if (!psecflags_validate(&psf))
2513                 return (EINVAL);
2514 
2515         (void) memcpy(&zone->zone_secflags, &psf, sizeof (psf));
2516 
2517         /* Set security flags on the zone's zsched */
2518         (void) memcpy(&zone->zone_zsched->p_secflags, &zone->zone_secflags,
2519             sizeof (zone->zone_zsched->p_secflags));
2520 
2521         return (0);
2522 }
2523 
2524 static int
2525 zone_set_fs_allowed(zone_t *zone, const char *zone_fs_allowed)
2526 {
2527         char *buf = kmem_zalloc(ZONE_FS_ALLOWED_MAX, KM_SLEEP);
2528         int err = 0;
2529 
2530         ASSERT(zone != global_zone);
2531         if ((err = copyinstr(zone_fs_allowed, buf,
2532             ZONE_FS_ALLOWED_MAX, NULL)) != 0)
2533                 goto done;
2534 
2535         if (zone->zone_fs_allowed != NULL)
2536                 strfree(zone->zone_fs_allowed);
2537 
2538         zone->zone_fs_allowed = strdup(buf);
2539 
2540 done:
2541         kmem_free(buf, ZONE_FS_ALLOWED_MAX);
2542         return (err);
2543 }
2544 


3966                         ASSERT(error == 0);
3967                 }
3968                 error = nvpair_value_nvlist_array(nvp, &nvlarray, &nelem);
3969                 ASSERT(error == 0);
3970                 for (i = 0; i < nelem; i++) {
3971                         rctl_val_t *nvalp;
3972 
3973                         nvalp = kmem_cache_alloc(rctl_val_cache, KM_SLEEP);
3974                         error = nvlist2rctlval(nvlarray[i], nvalp);
3975                         ASSERT(error == 0);
3976                         /*
3977                          * rctl_local_insert can fail if the value being
3978                          * inserted is a duplicate; this is OK.
3979                          */
3980                         mutex_enter(&pp->p_lock);
3981                         if (rctl_local_insert(hndl, nvalp, pp) != 0)
3982                                 kmem_cache_free(rctl_val_cache, nvalp);
3983                         mutex_exit(&pp->p_lock);
3984                 }
3985         }
3986 
3987         /*
3988          * Tell the world that we're done setting up.
3989          *
3990          * At this point we want to set the zone status to ZONE_IS_INITIALIZED
3991          * and atomically set the zone's processor set visibility.  Once
3992          * we drop pool_lock() this zone will automatically get updated
3993          * to reflect any future changes to the pools configuration.
3994          *
3995          * Note that after we drop the locks below (zonehash_lock in
3996          * particular) other operations such as a zone_getattr call can
3997          * now proceed and observe the zone. That is the reason for doing a
3998          * state transition to the INITIALIZED state.
3999          */
4000         pool_lock();
4001         mutex_enter(&cpu_lock);
4002         mutex_enter(&zonehash_lock);
4003         zone_uniqid(zone);
4004         zone_zsd_configure(zone);
4005         if (pool_state == POOL_ENABLED)
4006                 zone_pset_set(zone, pool_default->pool_pset->pset_id);


4250                 ASSERT(error == 0);
4251                 for (i = 0; i < nelem; i++) {
4252                         if (error = nvlist2rctlval(nvlarray[i], &rv))
4253                                 goto out;
4254                 }
4255                 if (rctl_invalid_value(rde, &rv)) {
4256                         error = EINVAL;
4257                         goto out;
4258                 }
4259         }
4260         error = 0;
4261         *nvlp = nvl;
4262 out:
4263         kmem_free(kbuf, buflen);
4264         if (error && nvl != NULL)
4265                 nvlist_free(nvl);
4266         return (error);
4267 }
4268 
4269 int
4270 zone_create_error(int er_error, int er_ext, int *er_out)
4271 {
4272         if (er_out != NULL) {
4273                 if (copyout(&er_ext, er_out, sizeof (int))) {
4274                         return (set_errno(EFAULT));
4275                 }
4276         }
4277         return (set_errno(er_error));
4278 }
4279 
4280 static int
4281 zone_set_label(zone_t *zone, const bslabel_t *lab, uint32_t doi)
4282 {
4283         ts_label_t *tsl;
4284         bslabel_t blab;
4285 
4286         /* Get label from user */
4287         if (copyin(lab, &blab, sizeof (blab)) != 0)
4288                 return (EFAULT);
4289         tsl = labelalloc(&blab, doi, KM_NOSLEEP);
4290         if (tsl == NULL)
4291                 return (ENOMEM);


4421         if ((error = zone_set_privset(zone, zone_privs, zone_privssz)) != 0) {
4422                 zone_free(zone);
4423                 return (zone_create_error(error, 0, extended_error));
4424         }
4425 
4426         /* initialize node name to be the same as zone name */
4427         zone->zone_nodename = kmem_alloc(_SYS_NMLN, KM_SLEEP);
4428         (void) strncpy(zone->zone_nodename, zone->zone_name, _SYS_NMLN);
4429         zone->zone_nodename[_SYS_NMLN - 1] = '\0';
4430 
4431         zone->zone_domain = kmem_alloc(_SYS_NMLN, KM_SLEEP);
4432         zone->zone_domain[0] = '\0';
4433         zone->zone_hostid = HW_INVALID_HOSTID;
4434         zone->zone_shares = 1;
4435         zone->zone_shmmax = 0;
4436         zone->zone_ipc.ipcq_shmmni = 0;
4437         zone->zone_ipc.ipcq_semmni = 0;
4438         zone->zone_ipc.ipcq_msgmni = 0;
4439         zone->zone_bootargs = NULL;
4440         zone->zone_fs_allowed = NULL;
4441 
4442         secflags_zero(&zone0.zone_secflags.psf_lower);
4443         secflags_zero(&zone0.zone_secflags.psf_effective);
4444         secflags_zero(&zone0.zone_secflags.psf_inherit);
4445         secflags_fullset(&zone0.zone_secflags.psf_upper);
4446 
4447         zone->zone_initname =
4448             kmem_alloc(strlen(zone_default_initname) + 1, KM_SLEEP);
4449         (void) strcpy(zone->zone_initname, zone_default_initname);
4450         zone->zone_nlwps = 0;
4451         zone->zone_nlwps_ctl = INT_MAX;
4452         zone->zone_nprocs = 0;
4453         zone->zone_nprocs_ctl = INT_MAX;
4454         zone->zone_locked_mem = 0;
4455         zone->zone_locked_mem_ctl = UINT64_MAX;
4456         zone->zone_max_swap = 0;
4457         zone->zone_max_swap_ctl = UINT64_MAX;
4458         zone->zone_max_lofi = 0;
4459         zone->zone_max_lofi_ctl = UINT64_MAX;
4460         zone0.zone_lockedmem_kstat = NULL;
4461         zone0.zone_swapresv_kstat = NULL;
4462 
4463         /*
4464          * Zsched initializes the rctls.
4465          */
4466         zone->zone_rctls = NULL;


5548                             bufsize) != 0)
5549                                 error = EFAULT;
5550                 } else {
5551                         error = EINVAL;
5552                 }
5553                 break;
5554         case ZONE_ATTR_FS_ALLOWED:
5555                 if (zone->zone_fs_allowed == NULL)
5556                         outstr = "";
5557                 else
5558                         outstr = zone->zone_fs_allowed;
5559                 size = strlen(outstr) + 1;
5560                 if (bufsize > size)
5561                         bufsize = size;
5562                 if (buf != NULL) {
5563                         err = copyoutstr(outstr, buf, bufsize, NULL);
5564                         if (err != 0 && err != ENAMETOOLONG)
5565                                 error = EFAULT;
5566                 }
5567                 break;
5568         case ZONE_ATTR_SECFLAGS:
5569                 size = sizeof (zone->zone_secflags);
5570                 if (bufsize > size)
5571                         bufsize = size;
5572                 if ((err = copyout(&zone->zone_secflags, buf, bufsize)) != 0)
5573                         error = EFAULT;
5574                 break;
5575         case ZONE_ATTR_NETWORK:
5576                 zbuf = kmem_alloc(bufsize, KM_SLEEP);
5577                 if (copyin(buf, zbuf, bufsize) != 0) {
5578                         error = EFAULT;
5579                 } else {
5580                         error = zone_get_network(zoneid, zbuf);
5581                         if (error == 0 && copyout(zbuf, buf, bufsize) != 0)
5582                                 error = EFAULT;
5583                 }
5584                 kmem_free(zbuf, bufsize);
5585                 break;
5586         default:
5587                 if ((attr >= ZONE_ATTR_BRAND_ATTRS) && ZONE_IS_BRANDED(zone)) {
5588                         size = bufsize;
5589                         error = ZBROP(zone)->b_getattr(zone, attr, buf, &size);
5590                 } else {
5591                         error = EINVAL;
5592                 }
5593         }
5594         zone_rele(zone);


5639                 goto done;
5640         }
5641 
5642         switch (attr) {
5643         case ZONE_ATTR_INITNAME:
5644                 err = zone_set_initname(zone, (const char *)buf);
5645                 break;
5646         case ZONE_ATTR_INITNORESTART:
5647                 zone->zone_restart_init = B_FALSE;
5648                 err = 0;
5649                 break;
5650         case ZONE_ATTR_BOOTARGS:
5651                 err = zone_set_bootargs(zone, (const char *)buf);
5652                 break;
5653         case ZONE_ATTR_BRAND:
5654                 err = zone_set_brand(zone, (const char *)buf);
5655                 break;
5656         case ZONE_ATTR_FS_ALLOWED:
5657                 err = zone_set_fs_allowed(zone, (const char *)buf);
5658                 break;
5659         case ZONE_ATTR_SECFLAGS:
5660                 err = zone_set_secflags(zone, (psecflags_t *)buf);
5661                 break;
5662         case ZONE_ATTR_PHYS_MCAP:
5663                 err = zone_set_phys_mcap(zone, (const uint64_t *)buf);
5664                 break;
5665         case ZONE_ATTR_SCHED_CLASS:
5666                 err = zone_set_sched_class(zone, (const char *)buf);
5667                 break;
5668         case ZONE_ATTR_HOSTID:
5669                 if (bufsize == sizeof (zone->zone_hostid)) {
5670                         if (copyin(buf, &zone->zone_hostid, bufsize) == 0)
5671                                 err = 0;
5672                         else
5673                                 err = EFAULT;
5674                 } else {
5675                         err = EINVAL;
5676                 }
5677                 break;
5678         case ZONE_ATTR_NETWORK:
5679                 if (bufsize > (PIPE_BUF + sizeof (zone_net_data_t))) {
5680                         err = EINVAL;
5681                         break;