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.


2063         zone0.zone_shares = 1;
2064         zone0.zone_nlwps = 0;
2065         zone0.zone_nlwps_ctl = INT_MAX;
2066         zone0.zone_nprocs = 0;
2067         zone0.zone_nprocs_ctl = INT_MAX;
2068         zone0.zone_locked_mem = 0;
2069         zone0.zone_locked_mem_ctl = UINT64_MAX;
2070         ASSERT(zone0.zone_max_swap == 0);
2071         zone0.zone_max_swap_ctl = UINT64_MAX;
2072         zone0.zone_max_lofi = 0;
2073         zone0.zone_max_lofi_ctl = UINT64_MAX;
2074         zone0.zone_shmmax = 0;
2075         zone0.zone_ipc.ipcq_shmmni = 0;
2076         zone0.zone_ipc.ipcq_semmni = 0;
2077         zone0.zone_ipc.ipcq_msgmni = 0;
2078         zone0.zone_name = GLOBAL_ZONENAME;
2079         zone0.zone_nodename = utsname.nodename;
2080         zone0.zone_domain = srpc_domain;
2081         zone0.zone_hostid = HW_INVALID_HOSTID;
2082         zone0.zone_fs_allowed = NULL;

2083         zone0.zone_ref = 1;
2084         zone0.zone_id = GLOBAL_ZONEID;
2085         zone0.zone_status = ZONE_IS_RUNNING;
2086         zone0.zone_rootpath = "/";
2087         zone0.zone_rootpathlen = 2;
2088         zone0.zone_psetid = ZONE_PS_INVAL;
2089         zone0.zone_ncpus = 0;
2090         zone0.zone_ncpus_online = 0;
2091         zone0.zone_proc_initpid = 1;
2092         zone0.zone_initname = initname;
2093         zone0.zone_lockedmem_kstat = NULL;
2094         zone0.zone_swapresv_kstat = NULL;
2095         zone0.zone_nprocs_kstat = NULL;
2096 
2097         zone0.zone_stime = 0;
2098         zone0.zone_utime = 0;
2099         zone0.zone_wtime = 0;
2100 
2101         list_create(&zone0.zone_ref_list, sizeof (zone_ref_t),
2102             offsetof(zone_ref_t, zref_linkage));


2510          */
2511         mutex_enter(&zone_status_lock);
2512 
2513         /* Re-Branding is not allowed and the zone can't be booted yet */
2514         if ((ZONE_IS_BRANDED(zone)) ||
2515             (zone_status_get(zone) >= ZONE_IS_BOOTING)) {
2516                 mutex_exit(&zone_status_lock);
2517                 brand_unregister_zone(bp);
2518                 return (EINVAL);
2519         }
2520 
2521         /* set up the brand specific data */
2522         zone->zone_brand = bp;
2523         ZBROP(zone)->b_init_brand_data(zone);
2524 
2525         mutex_exit(&zone_status_lock);
2526         return (0);
2527 }
2528 
2529 static int


























2530 zone_set_fs_allowed(zone_t *zone, const char *zone_fs_allowed)
2531 {
2532         char *buf = kmem_zalloc(ZONE_FS_ALLOWED_MAX, KM_SLEEP);
2533         int err = 0;
2534 
2535         ASSERT(zone != global_zone);
2536         if ((err = copyinstr(zone_fs_allowed, buf,
2537             ZONE_FS_ALLOWED_MAX, NULL)) != 0)
2538                 goto done;
2539 
2540         if (zone->zone_fs_allowed != NULL)
2541                 strfree(zone->zone_fs_allowed);
2542 
2543         zone->zone_fs_allowed = strdup(buf);
2544 
2545 done:
2546         kmem_free(buf, ZONE_FS_ALLOWED_MAX);
2547         return (err);
2548 }
2549 


3971                         ASSERT(error == 0);
3972                 }
3973                 error = nvpair_value_nvlist_array(nvp, &nvlarray, &nelem);
3974                 ASSERT(error == 0);
3975                 for (i = 0; i < nelem; i++) {
3976                         rctl_val_t *nvalp;
3977 
3978                         nvalp = kmem_cache_alloc(rctl_val_cache, KM_SLEEP);
3979                         error = nvlist2rctlval(nvlarray[i], nvalp);
3980                         ASSERT(error == 0);
3981                         /*
3982                          * rctl_local_insert can fail if the value being
3983                          * inserted is a duplicate; this is OK.
3984                          */
3985                         mutex_enter(&pp->p_lock);
3986                         if (rctl_local_insert(hndl, nvalp, pp) != 0)
3987                                 kmem_cache_free(rctl_val_cache, nvalp);
3988                         mutex_exit(&pp->p_lock);
3989                 }
3990         }

3991         /*
3992          * Tell the world that we're done setting up.
3993          *
3994          * At this point we want to set the zone status to ZONE_IS_INITIALIZED
3995          * and atomically set the zone's processor set visibility.  Once
3996          * we drop pool_lock() this zone will automatically get updated
3997          * to reflect any future changes to the pools configuration.
3998          *
3999          * Note that after we drop the locks below (zonehash_lock in
4000          * particular) other operations such as a zone_getattr call can
4001          * now proceed and observe the zone. That is the reason for doing a
4002          * state transition to the INITIALIZED state.
4003          */
4004         pool_lock();
4005         mutex_enter(&cpu_lock);
4006         mutex_enter(&zonehash_lock);
4007         zone_uniqid(zone);
4008         zone_zsd_configure(zone);
4009         if (pool_state == POOL_ENABLED)
4010                 zone_pset_set(zone, pool_default->pool_pset->pset_id);


4254                 ASSERT(error == 0);
4255                 for (i = 0; i < nelem; i++) {
4256                         if (error = nvlist2rctlval(nvlarray[i], &rv))
4257                                 goto out;
4258                 }
4259                 if (rctl_invalid_value(rde, &rv)) {
4260                         error = EINVAL;
4261                         goto out;
4262                 }
4263         }
4264         error = 0;
4265         *nvlp = nvl;
4266 out:
4267         kmem_free(kbuf, buflen);
4268         if (error && nvl != NULL)
4269                 nvlist_free(nvl);
4270         return (error);
4271 }
4272 
4273 int
4274 zone_create_error(int er_error, int er_ext, int *er_out) {

4275         if (er_out != NULL) {
4276                 if (copyout(&er_ext, er_out, sizeof (int))) {
4277                         return (set_errno(EFAULT));
4278                 }
4279         }
4280         return (set_errno(er_error));
4281 }
4282 
4283 static int
4284 zone_set_label(zone_t *zone, const bslabel_t *lab, uint32_t doi)
4285 {
4286         ts_label_t *tsl;
4287         bslabel_t blab;
4288 
4289         /* Get label from user */
4290         if (copyin(lab, &blab, sizeof (blab)) != 0)
4291                 return (EFAULT);
4292         tsl = labelalloc(&blab, doi, KM_NOSLEEP);
4293         if (tsl == NULL)
4294                 return (ENOMEM);


4424         if ((error = zone_set_privset(zone, zone_privs, zone_privssz)) != 0) {
4425                 zone_free(zone);
4426                 return (zone_create_error(error, 0, extended_error));
4427         }
4428 
4429         /* initialize node name to be the same as zone name */
4430         zone->zone_nodename = kmem_alloc(_SYS_NMLN, KM_SLEEP);
4431         (void) strncpy(zone->zone_nodename, zone->zone_name, _SYS_NMLN);
4432         zone->zone_nodename[_SYS_NMLN - 1] = '\0';
4433 
4434         zone->zone_domain = kmem_alloc(_SYS_NMLN, KM_SLEEP);
4435         zone->zone_domain[0] = '\0';
4436         zone->zone_hostid = HW_INVALID_HOSTID;
4437         zone->zone_shares = 1;
4438         zone->zone_shmmax = 0;
4439         zone->zone_ipc.ipcq_shmmni = 0;
4440         zone->zone_ipc.ipcq_semmni = 0;
4441         zone->zone_ipc.ipcq_msgmni = 0;
4442         zone->zone_bootargs = NULL;
4443         zone->zone_fs_allowed = NULL;






4444         zone->zone_initname =
4445             kmem_alloc(strlen(zone_default_initname) + 1, KM_SLEEP);
4446         (void) strcpy(zone->zone_initname, zone_default_initname);
4447         zone->zone_nlwps = 0;
4448         zone->zone_nlwps_ctl = INT_MAX;
4449         zone->zone_nprocs = 0;
4450         zone->zone_nprocs_ctl = INT_MAX;
4451         zone->zone_locked_mem = 0;
4452         zone->zone_locked_mem_ctl = UINT64_MAX;
4453         zone->zone_max_swap = 0;
4454         zone->zone_max_swap_ctl = UINT64_MAX;
4455         zone->zone_max_lofi = 0;
4456         zone->zone_max_lofi_ctl = UINT64_MAX;
4457         zone0.zone_lockedmem_kstat = NULL;
4458         zone0.zone_swapresv_kstat = NULL;
4459 
4460         /*
4461          * Zsched initializes the rctls.
4462          */
4463         zone->zone_rctls = NULL;


5545                             bufsize) != 0)
5546                                 error = EFAULT;
5547                 } else {
5548                         error = EINVAL;
5549                 }
5550                 break;
5551         case ZONE_ATTR_FS_ALLOWED:
5552                 if (zone->zone_fs_allowed == NULL)
5553                         outstr = "";
5554                 else
5555                         outstr = zone->zone_fs_allowed;
5556                 size = strlen(outstr) + 1;
5557                 if (bufsize > size)
5558                         bufsize = size;
5559                 if (buf != NULL) {
5560                         err = copyoutstr(outstr, buf, bufsize, NULL);
5561                         if (err != 0 && err != ENAMETOOLONG)
5562                                 error = EFAULT;
5563                 }
5564                 break;







5565         case ZONE_ATTR_NETWORK:
5566                 zbuf = kmem_alloc(bufsize, KM_SLEEP);
5567                 if (copyin(buf, zbuf, bufsize) != 0) {
5568                         error = EFAULT;
5569                 } else {
5570                         error = zone_get_network(zoneid, zbuf);
5571                         if (error == 0 && copyout(zbuf, buf, bufsize) != 0)
5572                                 error = EFAULT;
5573                 }
5574                 kmem_free(zbuf, bufsize);
5575                 break;
5576         default:
5577                 if ((attr >= ZONE_ATTR_BRAND_ATTRS) && ZONE_IS_BRANDED(zone)) {
5578                         size = bufsize;
5579                         error = ZBROP(zone)->b_getattr(zone, attr, buf, &size);
5580                 } else {
5581                         error = EINVAL;
5582                 }
5583         }
5584         zone_rele(zone);


5629                 goto done;
5630         }
5631 
5632         switch (attr) {
5633         case ZONE_ATTR_INITNAME:
5634                 err = zone_set_initname(zone, (const char *)buf);
5635                 break;
5636         case ZONE_ATTR_INITNORESTART:
5637                 zone->zone_restart_init = B_FALSE;
5638                 err = 0;
5639                 break;
5640         case ZONE_ATTR_BOOTARGS:
5641                 err = zone_set_bootargs(zone, (const char *)buf);
5642                 break;
5643         case ZONE_ATTR_BRAND:
5644                 err = zone_set_brand(zone, (const char *)buf);
5645                 break;
5646         case ZONE_ATTR_FS_ALLOWED:
5647                 err = zone_set_fs_allowed(zone, (const char *)buf);
5648                 break;



5649         case ZONE_ATTR_PHYS_MCAP:
5650                 err = zone_set_phys_mcap(zone, (const uint64_t *)buf);
5651                 break;
5652         case ZONE_ATTR_SCHED_CLASS:
5653                 err = zone_set_sched_class(zone, (const char *)buf);
5654                 break;
5655         case ZONE_ATTR_HOSTID:
5656                 if (bufsize == sizeof (zone->zone_hostid)) {
5657                         if (copyin(buf, &zone->zone_hostid, bufsize) == 0)
5658                                 err = 0;
5659                         else
5660                                 err = EFAULT;
5661                 } else {
5662                         err = EINVAL;
5663                 }
5664                 break;
5665         case ZONE_ATTR_NETWORK:
5666                 if (bufsize > (PIPE_BUF + sizeof (zone_net_data_t))) {
5667                         err = EINVAL;
5668                         break;




2063         zone0.zone_shares = 1;
2064         zone0.zone_nlwps = 0;
2065         zone0.zone_nlwps_ctl = INT_MAX;
2066         zone0.zone_nprocs = 0;
2067         zone0.zone_nprocs_ctl = INT_MAX;
2068         zone0.zone_locked_mem = 0;
2069         zone0.zone_locked_mem_ctl = UINT64_MAX;
2070         ASSERT(zone0.zone_max_swap == 0);
2071         zone0.zone_max_swap_ctl = UINT64_MAX;
2072         zone0.zone_max_lofi = 0;
2073         zone0.zone_max_lofi_ctl = UINT64_MAX;
2074         zone0.zone_shmmax = 0;
2075         zone0.zone_ipc.ipcq_shmmni = 0;
2076         zone0.zone_ipc.ipcq_semmni = 0;
2077         zone0.zone_ipc.ipcq_msgmni = 0;
2078         zone0.zone_name = GLOBAL_ZONENAME;
2079         zone0.zone_nodename = utsname.nodename;
2080         zone0.zone_domain = srpc_domain;
2081         zone0.zone_hostid = HW_INVALID_HOSTID;
2082         zone0.zone_fs_allowed = NULL;
2083         psecflags_default(&zone0.zone_secflags);
2084         zone0.zone_ref = 1;
2085         zone0.zone_id = GLOBAL_ZONEID;
2086         zone0.zone_status = ZONE_IS_RUNNING;
2087         zone0.zone_rootpath = "/";
2088         zone0.zone_rootpathlen = 2;
2089         zone0.zone_psetid = ZONE_PS_INVAL;
2090         zone0.zone_ncpus = 0;
2091         zone0.zone_ncpus_online = 0;
2092         zone0.zone_proc_initpid = 1;
2093         zone0.zone_initname = initname;
2094         zone0.zone_lockedmem_kstat = NULL;
2095         zone0.zone_swapresv_kstat = NULL;
2096         zone0.zone_nprocs_kstat = NULL;
2097 
2098         zone0.zone_stime = 0;
2099         zone0.zone_utime = 0;
2100         zone0.zone_wtime = 0;
2101 
2102         list_create(&zone0.zone_ref_list, sizeof (zone_ref_t),
2103             offsetof(zone_ref_t, zref_linkage));


2511          */
2512         mutex_enter(&zone_status_lock);
2513 
2514         /* Re-Branding is not allowed and the zone can't be booted yet */
2515         if ((ZONE_IS_BRANDED(zone)) ||
2516             (zone_status_get(zone) >= ZONE_IS_BOOTING)) {
2517                 mutex_exit(&zone_status_lock);
2518                 brand_unregister_zone(bp);
2519                 return (EINVAL);
2520         }
2521 
2522         /* set up the brand specific data */
2523         zone->zone_brand = bp;
2524         ZBROP(zone)->b_init_brand_data(zone);
2525 
2526         mutex_exit(&zone_status_lock);
2527         return (0);
2528 }
2529 
2530 static int
2531 zone_set_secflags(zone_t *zone, const psecflags_t *zone_secflags)
2532 {
2533         int err = 0;
2534         psecflags_t psf;
2535 
2536         ASSERT(zone != global_zone);
2537 
2538         if ((err = copyin(zone_secflags, &psf, sizeof (psf))) != 0)
2539                 return (err);
2540 
2541         if (zone_status_get(zone) > ZONE_IS_READY)
2542                 return (EINVAL);
2543 
2544         if (!psecflags_validate(&psf))
2545                 return (EINVAL);
2546 
2547         (void) memcpy(&zone->zone_secflags, &psf, sizeof (psf));
2548 
2549         /* Set security flags on the zone's zsched */
2550         (void) memcpy(&zone->zone_zsched->p_secflags, &zone->zone_secflags,
2551             sizeof (zone->zone_zsched->p_secflags));
2552 
2553         return (0);
2554 }
2555 
2556 static int
2557 zone_set_fs_allowed(zone_t *zone, const char *zone_fs_allowed)
2558 {
2559         char *buf = kmem_zalloc(ZONE_FS_ALLOWED_MAX, KM_SLEEP);
2560         int err = 0;
2561 
2562         ASSERT(zone != global_zone);
2563         if ((err = copyinstr(zone_fs_allowed, buf,
2564             ZONE_FS_ALLOWED_MAX, NULL)) != 0)
2565                 goto done;
2566 
2567         if (zone->zone_fs_allowed != NULL)
2568                 strfree(zone->zone_fs_allowed);
2569 
2570         zone->zone_fs_allowed = strdup(buf);
2571 
2572 done:
2573         kmem_free(buf, ZONE_FS_ALLOWED_MAX);
2574         return (err);
2575 }
2576 


3998                         ASSERT(error == 0);
3999                 }
4000                 error = nvpair_value_nvlist_array(nvp, &nvlarray, &nelem);
4001                 ASSERT(error == 0);
4002                 for (i = 0; i < nelem; i++) {
4003                         rctl_val_t *nvalp;
4004 
4005                         nvalp = kmem_cache_alloc(rctl_val_cache, KM_SLEEP);
4006                         error = nvlist2rctlval(nvlarray[i], nvalp);
4007                         ASSERT(error == 0);
4008                         /*
4009                          * rctl_local_insert can fail if the value being
4010                          * inserted is a duplicate; this is OK.
4011                          */
4012                         mutex_enter(&pp->p_lock);
4013                         if (rctl_local_insert(hndl, nvalp, pp) != 0)
4014                                 kmem_cache_free(rctl_val_cache, nvalp);
4015                         mutex_exit(&pp->p_lock);
4016                 }
4017         }
4018 
4019         /*
4020          * Tell the world that we're done setting up.
4021          *
4022          * At this point we want to set the zone status to ZONE_IS_INITIALIZED
4023          * and atomically set the zone's processor set visibility.  Once
4024          * we drop pool_lock() this zone will automatically get updated
4025          * to reflect any future changes to the pools configuration.
4026          *
4027          * Note that after we drop the locks below (zonehash_lock in
4028          * particular) other operations such as a zone_getattr call can
4029          * now proceed and observe the zone. That is the reason for doing a
4030          * state transition to the INITIALIZED state.
4031          */
4032         pool_lock();
4033         mutex_enter(&cpu_lock);
4034         mutex_enter(&zonehash_lock);
4035         zone_uniqid(zone);
4036         zone_zsd_configure(zone);
4037         if (pool_state == POOL_ENABLED)
4038                 zone_pset_set(zone, pool_default->pool_pset->pset_id);


4282                 ASSERT(error == 0);
4283                 for (i = 0; i < nelem; i++) {
4284                         if (error = nvlist2rctlval(nvlarray[i], &rv))
4285                                 goto out;
4286                 }
4287                 if (rctl_invalid_value(rde, &rv)) {
4288                         error = EINVAL;
4289                         goto out;
4290                 }
4291         }
4292         error = 0;
4293         *nvlp = nvl;
4294 out:
4295         kmem_free(kbuf, buflen);
4296         if (error && nvl != NULL)
4297                 nvlist_free(nvl);
4298         return (error);
4299 }
4300 
4301 int
4302 zone_create_error(int er_error, int er_ext, int *er_out)
4303 {
4304         if (er_out != NULL) {
4305                 if (copyout(&er_ext, er_out, sizeof (int))) {
4306                         return (set_errno(EFAULT));
4307                 }
4308         }
4309         return (set_errno(er_error));
4310 }
4311 
4312 static int
4313 zone_set_label(zone_t *zone, const bslabel_t *lab, uint32_t doi)
4314 {
4315         ts_label_t *tsl;
4316         bslabel_t blab;
4317 
4318         /* Get label from user */
4319         if (copyin(lab, &blab, sizeof (blab)) != 0)
4320                 return (EFAULT);
4321         tsl = labelalloc(&blab, doi, KM_NOSLEEP);
4322         if (tsl == NULL)
4323                 return (ENOMEM);


4453         if ((error = zone_set_privset(zone, zone_privs, zone_privssz)) != 0) {
4454                 zone_free(zone);
4455                 return (zone_create_error(error, 0, extended_error));
4456         }
4457 
4458         /* initialize node name to be the same as zone name */
4459         zone->zone_nodename = kmem_alloc(_SYS_NMLN, KM_SLEEP);
4460         (void) strncpy(zone->zone_nodename, zone->zone_name, _SYS_NMLN);
4461         zone->zone_nodename[_SYS_NMLN - 1] = '\0';
4462 
4463         zone->zone_domain = kmem_alloc(_SYS_NMLN, KM_SLEEP);
4464         zone->zone_domain[0] = '\0';
4465         zone->zone_hostid = HW_INVALID_HOSTID;
4466         zone->zone_shares = 1;
4467         zone->zone_shmmax = 0;
4468         zone->zone_ipc.ipcq_shmmni = 0;
4469         zone->zone_ipc.ipcq_semmni = 0;
4470         zone->zone_ipc.ipcq_msgmni = 0;
4471         zone->zone_bootargs = NULL;
4472         zone->zone_fs_allowed = NULL;
4473 
4474         secflags_zero(&zone0.zone_secflags.psf_lower);
4475         secflags_zero(&zone0.zone_secflags.psf_effective);
4476         secflags_zero(&zone0.zone_secflags.psf_inherit);
4477         secflags_fullset(&zone0.zone_secflags.psf_upper);
4478 
4479         zone->zone_initname =
4480             kmem_alloc(strlen(zone_default_initname) + 1, KM_SLEEP);
4481         (void) strcpy(zone->zone_initname, zone_default_initname);
4482         zone->zone_nlwps = 0;
4483         zone->zone_nlwps_ctl = INT_MAX;
4484         zone->zone_nprocs = 0;
4485         zone->zone_nprocs_ctl = INT_MAX;
4486         zone->zone_locked_mem = 0;
4487         zone->zone_locked_mem_ctl = UINT64_MAX;
4488         zone->zone_max_swap = 0;
4489         zone->zone_max_swap_ctl = UINT64_MAX;
4490         zone->zone_max_lofi = 0;
4491         zone->zone_max_lofi_ctl = UINT64_MAX;
4492         zone0.zone_lockedmem_kstat = NULL;
4493         zone0.zone_swapresv_kstat = NULL;
4494 
4495         /*
4496          * Zsched initializes the rctls.
4497          */
4498         zone->zone_rctls = NULL;


5580                             bufsize) != 0)
5581                                 error = EFAULT;
5582                 } else {
5583                         error = EINVAL;
5584                 }
5585                 break;
5586         case ZONE_ATTR_FS_ALLOWED:
5587                 if (zone->zone_fs_allowed == NULL)
5588                         outstr = "";
5589                 else
5590                         outstr = zone->zone_fs_allowed;
5591                 size = strlen(outstr) + 1;
5592                 if (bufsize > size)
5593                         bufsize = size;
5594                 if (buf != NULL) {
5595                         err = copyoutstr(outstr, buf, bufsize, NULL);
5596                         if (err != 0 && err != ENAMETOOLONG)
5597                                 error = EFAULT;
5598                 }
5599                 break;
5600         case ZONE_ATTR_SECFLAGS:
5601                 size = sizeof (zone->zone_secflags);
5602                 if (bufsize > size)
5603                         bufsize = size;
5604                 if ((err = copyout(&zone->zone_secflags, buf, bufsize)) != 0)
5605                         error = EFAULT;
5606                 break;
5607         case ZONE_ATTR_NETWORK:
5608                 zbuf = kmem_alloc(bufsize, KM_SLEEP);
5609                 if (copyin(buf, zbuf, bufsize) != 0) {
5610                         error = EFAULT;
5611                 } else {
5612                         error = zone_get_network(zoneid, zbuf);
5613                         if (error == 0 && copyout(zbuf, buf, bufsize) != 0)
5614                                 error = EFAULT;
5615                 }
5616                 kmem_free(zbuf, bufsize);
5617                 break;
5618         default:
5619                 if ((attr >= ZONE_ATTR_BRAND_ATTRS) && ZONE_IS_BRANDED(zone)) {
5620                         size = bufsize;
5621                         error = ZBROP(zone)->b_getattr(zone, attr, buf, &size);
5622                 } else {
5623                         error = EINVAL;
5624                 }
5625         }
5626         zone_rele(zone);


5671                 goto done;
5672         }
5673 
5674         switch (attr) {
5675         case ZONE_ATTR_INITNAME:
5676                 err = zone_set_initname(zone, (const char *)buf);
5677                 break;
5678         case ZONE_ATTR_INITNORESTART:
5679                 zone->zone_restart_init = B_FALSE;
5680                 err = 0;
5681                 break;
5682         case ZONE_ATTR_BOOTARGS:
5683                 err = zone_set_bootargs(zone, (const char *)buf);
5684                 break;
5685         case ZONE_ATTR_BRAND:
5686                 err = zone_set_brand(zone, (const char *)buf);
5687                 break;
5688         case ZONE_ATTR_FS_ALLOWED:
5689                 err = zone_set_fs_allowed(zone, (const char *)buf);
5690                 break;
5691         case ZONE_ATTR_SECFLAGS:
5692                 err = zone_set_secflags(zone, (psecflags_t *)buf);
5693                 break;
5694         case ZONE_ATTR_PHYS_MCAP:
5695                 err = zone_set_phys_mcap(zone, (const uint64_t *)buf);
5696                 break;
5697         case ZONE_ATTR_SCHED_CLASS:
5698                 err = zone_set_sched_class(zone, (const char *)buf);
5699                 break;
5700         case ZONE_ATTR_HOSTID:
5701                 if (bufsize == sizeof (zone->zone_hostid)) {
5702                         if (copyin(buf, &zone->zone_hostid, bufsize) == 0)
5703                                 err = 0;
5704                         else
5705                                 err = EFAULT;
5706                 } else {
5707                         err = EINVAL;
5708                 }
5709                 break;
5710         case ZONE_ATTR_NETWORK:
5711                 if (bufsize > (PIPE_BUF + sizeof (zone_net_data_t))) {
5712                         err = EINVAL;
5713                         break;